2015-10-06 45 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

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

相關問題