web-dev-qa-db-ja.com

iOSでホームボタンが押されたことを検出する

ネットワークビーコンをリッスンするために同じポートを使用するiOSアプリがいくつかあります。メインビューでは、別のビューが開かれたときにviewWillDisappearを使用してポートを閉じます。次に、別のビューを開かずにメインビューコントローラーからホームボタンを押してポートを閉じると、ポートが開いたままになり、他のアプリがそのポートでリッスンできないことに気付きました。次に、viewWillUnloadを使用してみましたが、ホームボタンを押しても呼び出されないようです。

-(void)viewWillUnload
{
    //[super viewWillUnload];
    NSLog(@"View will unload");
    [udpSocket close];
    udpSocket = nil;
}

ビューがアンロードされることはコンソールに表示されないため、メソッドが呼び出されることはありません。

ポートを閉じるためにホームボタンが押されたことを検出する方法はありますか?

26
nick

これらはあなたのオプションです

アプリのデリゲートで:

- (void)applicationWillResignActive:(UIApplication *)application
{
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}

- (void)applicationWillTerminate:(UIApplication *)application
{
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
44
Mick MacCallum

これを処理する最も簡単な方法は、View ControllerでUIApplicationWillResignActiveNotification通知を受信するように登録することです。

イベントは、ホームボタンを押してロックし、電話をかけると発行されます。

- (void) applicationWillResign{
    NSLog(@"About to lose focus");
}

- (void) myVcInitMethod { 
    [[NSNotificationCenter defaultCenter]
        addObserver:self
        selector:@selector(applicationWillResign)
        name:UIApplicationWillResignActiveNotification 
        object:nil];
}
31
PeterPurple

Swift Userの場合

このように書くことができます

override func viewDidLoad() {
    super.viewDidLoad()

    // code here...

    NSNotificationCenter.defaultCenter().addObserver(
        self,
        selector: "applicationWillResignActive:",
        name: UIApplicationWillResignActiveNotification,
        object: nil)
}

func applicationWillResignActive(notification: NSNotification) {
    print("I'm out of focus!")
}

また、アプリの終了時に閉じることを忘れないでください

deinit {

    // code here...

    NSNotificationCenter.defaultCenter().removeObserver(self)
}
10
Sruit A.Suk

viewWillUnloadは通常、メモリ不足の場合を除いて呼び出されません。代わりにこれらを使用します。

アプリのデリゲートで:

- (void)applicationWillResignActive:(UIApplication *)application
{
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}

- (void)applicationWillTerminate:(UIApplication *)application
{
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

または、View Controllerでコードを使用する場合:

- (void)viewDidDisappear:(BOOL)animated
{
//Put code here
}

- (void)viewWillDisappear:(BOOL)animated
{
//Put code here
}
5
DGund

viewWillUnloadは、メモリ不足の場合を除いてしばしば呼び出されません。 アプリケーションデリゲートメソッドapplicationDidEnterBackground:またはapplicationWillTerminate:そしてそこで作業を行うか、クリーンアッププロセスの処理方法を知っているアプリケーションの一部に通知を送信します。

5
warrenm

UIApplicationWillResignActiveUIApplicationDidBecomeActiveを使用する方が良いのは、それらが「上部の長方形のキャッチとリリースイベント」をキャッチするためです。このルートクラスを使用することをお勧めします。

_class VBase: UIViewController {
    fileprivate var listenersActivated = false
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        onStart()
    }
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        onStop()
        removeListeners()
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
        onStop()
        removeListeners()
    }

    internal func iniListeners() {
        if (!listenersActivated) {
            NotificationCenter.default.addObserver(self, selector: #selector(onStop), name: NSNotification.Name.UIApplicationWillResignActive, object: nil)
            NotificationCenter.default.addObserver(self, selector: #selector(onStart), name: NSNotification.Name.UIApplicationDidBecomeActive, object: nil)
            listenersActivated = true
        } else {

        }
    }
    internal func removeListeners() {
        NotificationCenter.default.removeObserver(self)
        listenersActivated = false
    }
    internal func onStop() {

    }
    internal func onStart() {
        iniListeners()
    }

}
_

子内部でonStop()およびonStart()をオーバーライドして、すべてのビューの出現/消滅をキャッチします

あれは、

_class SomeViewController: VBase {

...
    override func onStart() {
        super.onStart()
        someFunctionToInitialize()
    }
    override func onStop() {
        super.onStop()
        stopTimer()
        someFunctionToDesctruction()
    }
}
_
4
Vyacheslav