【问题标题】:Detect when home button is pressed iOS检测何时按下主页按钮iOS
【发布时间】:2012-05-06 15:57:27
【问题描述】:

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

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

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

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

【问题讨论】:

  • 尝试使用“applicationWillTerminate”方法。 :-)
  • “applicationWillTerminate”方法不存在。但是,子类可以注册 UIApplicationWillTerminateNotification,然后自己进行清理或关闭。

标签: iphone ios ipad ios5


【解决方案1】:

这些是你的选择

在您的应用委托中:

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

【讨论】:

  • 我有代码可以在 viewWillDisappear 中关闭端口,但它似乎没有被调用。该端口将保持打开状态,并且使用该端口的所有其他应用程序都将失败。我设置了一个类方法来关闭端口并从 applicationDidEnterBackground 调用它,效果很好
  • viewWillDisappearviewDidDisappear 在按下 Home 按钮或应用程序终止时不会被调用。最好的解决方案是使用UIApplicationWillResignActiveNotification 通知
【解决方案2】:

viewWillUnload 通常不会被调用,除非内存不足。您最好实现 application delegate methods applicationDidEnterBackground:applicationWillTerminate: 并在那里完成工作或向知道如何处理清理过程的应用程序部分发送通知。

【讨论】:

    【解决方案3】:

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

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

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

    【讨论】:

    • viewWill/DidDisappear 将在应用程序关闭时调用。当按下主页按钮以最小化控制中心的应用程序时不会。
    【解决方案4】:

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

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

    - (void) applicationWillResign{
        NSLog(@"About to lose focus");
    }
    
    - (void) myVcInitMethod { 
        [[NSNotificationCenter defaultCenter]
            addObserver:self
            selector:@selector(applicationWillResign)
            name:UIApplicationWillResignActiveNotification 
            object:nil];
    }
    

    【讨论】:

    • 为什么要传递 NULL 而不是 nil?
    • 实际上applicationWillResignActive 通知不是始终是最好的方法,因为主动辞职还包括(意外)向下滑动顶部菜单,或新的向上滑动底部菜单在 ios 7 中。applicationDidEnterBackground 表示您的应用已“最小化”,并且可从 iOS 4 使用。
    【解决方案5】:

    如果是 Swift 用户

    你可以这样写

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

    【讨论】:

    • 如果您使用的是 iOS 9 或更高版本,您可以忘记在 deinit 方法中删除观察者。但是,前提是您不打算支持 iOS 8 或更早版本。而且,正如@bobobobo 所说,您应该使用 applicationDidEnterBackground
    【解决方案6】:

    最好使用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()
        }
    }
    

    【讨论】:

    • 谢谢。太棒了。
    猜你喜欢
    • 1970-01-01
    • 2016-05-31
    • 1970-01-01
    • 2012-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-20
    相关资源
    最近更新 更多