检测何时按下主页按钮 iOS

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10324596/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 18:04:50  来源:igfitidea点击:

Detect when home button is pressed iOS

iphoneiosipadios5

提问by nick

I have several iOS apps that all use the same port to listen for a network beacon. On the main view I use viewWillDisappear to close the port when another view is opened, which was working great. Then I noticed if I pressed the home button from the main view controller without opening another view to close the port, then the port stays open and non of my other apps can listen on that port any more. I then tried using viewWillUnload, but that doesn't seem to get called when I press the home button.

我有几个 iOS 应用程序都使用相同的端口来侦听网络信标。在主视图上,当打开另一个视图时,我使用 viewWillDisappear 关闭端口,这很好用。然后我注意到如果我从主视图控制器按下主页按钮而不打开另一个视图来关闭端口,那么端口保持打开状态并且我的其他应用程序不能再侦听该端口。然后我尝试使用 viewWillUnload,但当我按下主页按钮时,它似乎没有被调用。

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

View will unload is never displayed in the console, which leads me to believe that the method is never getting called.

View will unload 永远不会显示在控制台中,这让我相信该方法永远不会被调用。

Is there a way to detect when the home button is pressed so I can close my port?

有没有办法检测何时按下主页按钮,以便我可以关闭我的端口?

回答by Mick MacCallum

These are your options

这些是您的选择

In your app delegate:

在您的应用委托中:

- (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:.
}

回答by PeterPurple

The easiest way to handle this is to register to receive the UIApplicationWillResignActiveNotification notification in your view controller.

处理此问题的最简单方法是注册以在您的视图控制器中接收 UIApplicationWillResignActiveNotification 通知。

The event is issued upon a home button press, lock and upon a phone call

该事件在按下主页按钮、锁定和电话时发出

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

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

回答by Sruit A.Suk

In case of Swift User

如果是 Swift 用户

you can write it like this

你可以这样写

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!")
}

also, Don't forget to close it when your app is terminate

另外,不要忘记在您的应用程序终止时关闭它

deinit {

    // code here...

    NSNotificationCenter.defaultCenter().removeObserver(self)
}

回答by Vyacheslav

Better to use UIApplicationWillResignActiveand UIApplicationDidBecomeActivedue to they catch 'top rectangle catch and release event'. I would suggest to use this root class:

更好地使用UIApplicationWillResignActive并且UIApplicationDidBecomeActive由于它们捕获“顶部矩形捕获和释放事件”。我建议使用这个根类:

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()
    }

}

Override onStop()and onStart()inside childs to catch all view appearance/disappearance

覆盖onStop()onStart()内部孩子以捕捉所有视图外观/消失

That is,

那是,

class SomeViewController: VBase {

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

回答by warrenm

viewWillUnloadis often not called except in the case of low memory. You're better off implementing the application delegate methodsapplicationDidEnterBackground:or applicationWillTerminate:and doing the work there or sending a notification to the part of your application that knows how to handle the cleanup process.

viewWillUnload除了内存不足的情况外,通常不会被调用。您最好实现应用程序委托方法,applicationDidEnterBackground:或者applicationWillTerminate:在那里完成工作,或者向知道如何处理清理过程的应用程序部分发送通知。

回答by dgund

viewWillUnload is usually not called except in the case of low memory.Use these instead:

除非内存不足,否则通常不会调用 viewWillUnload。改用这些:

In your App Delegate:

在您的应用程序委托中:

- (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:.
}

Or if you want to use code in your View Controller:

或者,如果您想在视图控制器中使用代码:

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

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