2015-10-06 44 views
0

在我的项目的第一个UITableViewController场景中,我在单元格中使用UITextFields以使其某些内容可以在运行中进行重命名。当出现键盘并隐藏正在修改的单元格时,我不得不实现通知中心观察者来管理tableView insets。如何仅使用可见视图控制器的方法响应通知?

override func viewDidLoad() { 
    (...) 
    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWasShown:"), name:UIKeyboardDidShowNotification, object: nil) 
    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillBeHidden:"), name:UIKeyboardWillHideNotification, object: nil) 
    (...) 
} 

我ASLO投入DEINIT代码删除这些观察员:

deinit { 
    NSNotificationCenter.defaultCenter().removeObserver(self, name:UIKeyboardDidShowNotification, object: nil) 
    NSNotificationCenter.defaultCenter().removeObserver(self, name:UIKeyboardWillHideNotification, object: nil) 
} 

然而,当我执行SEGUE到另一个场景,以及键盘出现我收到运行时异常“致命错误:意外发现零,而用一条线以前的UITableViewController代码的展开的可选值” ,这不应该是活跃在这个场景

func keyboardWasShown(notification: NSNotification) { 
(...) 
    if let cell = tableView.cellForRowAtIndexPath(editingIndexPath!) as? ListsTableViewCell { // ERROR HERE 
     (...) 
    } 
} 

我想这是因为通知全局运行。但我没想到,目前无形视图的控制器会以自己的功能回应通知。 问题是:如何强制控制器仅在其视图可见时才对通知作出反应。在我的情况下,deinit {}不起作用。

回答

2

视图控制器的生命周期如下:

init - >loadView - >viewDidLoad - >viewWillAppear: - >viewDidAppear: - >viewWillDisappear: - >viewDidDisappear: - >deinit

当按下或呈现另一视图控制器(控制器B),当前视图控制器(控制器A)分别调用其viewWillDisappear:viewDidDisappear:函数,但deinit不会被调用,因为(A)仍由导航堆栈引用。当(B)最终弹回或被解雇时,方法viewWillAppear:viewDidAppear:被调用(A)。只有在(A)弹出后deinit被调用。

因此,即使当前不可见,键盘的通知也会在您的视图控制器上被触发。

您应该将您的通知注册和删除分别移至viewWillAppear:viewDidDisappear:

希望这会有所帮助!

+0

是的!非常感谢您的回答! –

相关问题