2016-11-28 66 views
4

我的應用程序顯示一個表單,並且在某些單元格上有可輸入信息的文本框。如果單元格朝向屏幕的底部,單元格將被完全阻塞,這意味着您無法看到您正在回答的問題。我的UITableView嵌入在UIViewController中。讓鍵盤阻止單元格

我已經瀏覽了許多建議這個問題的答案並實現了一些代碼的線程。如果我能得到這個方法的工作,我相信我的代碼將工作:

func textFieldDidBeginEditing(_ textField: UITextField) { 
    if (self.tableView.contentOffset.y == 0) 
    { 
     self.tableView.scrollToRow(at: self.tableView.indexPath(for:), at: UITableViewScrollPosition, animated: true) 
    } 
} 

現在我正在努力解決越來越活躍的細胞,以便它可以被輸入到self.tableView.indexPath(for:)的問題。

我該怎麼做呢?這是移動鍵盤上方視圖的正確方法嗎?

+0

可以請你告訴我表單是動態的還是靜態的,如果是靜態的,那麼就有很簡單的方法來實現它,而不需要任何代碼。 –

+0

我已經使用[IQKeyboardManager](https://github.com/hackiftekhar/IQKeyboardManager)來移動文本框,以防止它們被阻止。到目前爲止,它對我來說非常有用。 – NerdsGeeksGurus

+0

使用鍵盤通知來處理此類問題 –

回答

0

退房這個問題的答案後由我
iOS Support External Keyboard Without Displaying One

此外,對於的tableView,我使用這樣的與鍵盤顯示適當的單元格。

func textFieldDidBeginEditing(_ textField: UITextField) { 
    tableView.isScrollEnabled = false 
    var path: IndexPath? 

    path = theIndexPathOfTheCellWithTheTextField 

    if path != nil { 
     let rect = CGRect(x: 0, y: 0, width: tableView.frame.width, height: tableView.frame.height) 
     tableView.tableFooterView = UIView(frame: rect) 

     UIView.animate(withDuration: 0.6, animations: { 
      [weak self] in 
      self?.tableView.scrollToRow(at: path!, at: .top, animated: false) 
     }, completion: nil) 
    } 
} 

func textFieldDidEndEditing(_ textField: UITextField) { 
    tableView.tableFooterView = UIView() 
    tableView.isScrollEnabled = true 
} 

如果您具有的tableView的tableFooterView一個UI,比這部分代碼可能需要改變或基於頁腳視圖可用大小中刪除。

編輯 - 更多信息: 爲了做一個indexPath,你有幾個選項。您只需硬編碼,如果你知道了細胞的位置,像這樣:

//This works where neither theRowInt or theSectionInt are negative. 
IndexPath(row: theRowInt, section: theSectionInt) 

//So this would be the first section/first row 
IndexPath(row: 0, section: 0) 

下一個辦法是將它基於您通過文本框找到電池:

let textFieldCell = textField.superview.superview.superview as! UITableViewCell 
let indexPath = self.tableView.indexPathForCell(textFieldCell) 

這工作假設你這是正確的監視次數。如果將textField直接放入contentView中,則無論如何,這應該是自iOS 7以來的正確數字。如果它崩潰,不僅僅是改變.superviews的數量直到它工作。

還有其他的方法,但如果你對它們感興趣,那麼自己研究一下。關於這個問題,Here是一個很好的堆棧溢出帖子。

+0

如何獲取theIndexPathOfTheCellWithTheTextField?似乎如果我能弄清楚,我可以運行我的上述代碼。 –

+0

檢查我即將編輯的編輯。 – Sethmr

+0

所以我試過這個解決方案後沒有與我的運氣和另一個......這一個也沒有工作。當我點擊一個文本框時,tableview根本不會滾動。多一點信息。我正在使用我創建的自定義tableviewcells。 uitableview放置在我的uiviewcontroller中的2個uiviews之間。我不知道這是否對正確滾動有影響。任何想法如何我可以調試這個? –

0

到目前爲止,最簡單的解決方案是使用UITableViewController而不是帶有tableView屬性的UIViewController

它自動神奇地爲您處理它。我很清楚有些情況下你不能使用UITableViewController,但是如果可能的話,你應該。使用在常規控制器中嵌入UITableViewController的容器視圖控制器,即使在更復雜的情況下也可以實現這一點。

0

在viewWillAppear中你UIKeyboardWillShow和UIKeyboardWillHide註冊通知:

NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name:NSNotification.Name.UIKeyboardWillShow, object: nil) 
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name:NSNotification.Name.UIKeyboardWillHide, object: nil) 

然後keyboardWillShow你鍵盤的框架,改變的tableView

func keyboardWillShow(notification: Notification) { 
    guard let keyboardFrame = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue else { return } 
     let convertedFrame = view.convert(keyboardFrame, from: nil) 
     tableView.contentInset.bottom = convertedFrame.height 
} 

然後keyboardWillHide你改變的插圖底部插入回到0,並且如果需要的話,將tableView滾動回特定行。這將它滾動回位於tableView頂部的第一行。

func keyboardWillHide(notification: Notification) { 
    tableView.contentInset.bottom = 0 
    tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: true) 
} 

這也是一個很好的方法來做到這一點,因爲它讓你的textField代理與影響佈局的代碼保持一致。

我相信我讀的地方,你不需要刪除自己觀察員某些通知,其中包括鍵盤通知,但爲了穩妥起見,你應該把這些在viewWillDisappear或DEINIT視情況

deinit { 
    NotificationCenter.default.removeObserver(self, name: Notification.Name.UIKeyboardWillShow, object: nil) 
    NotificationCenter.default.removeObserver(self, name: Notification.Name.UIKeyboardWillHide, object: nil) 

    // If you don't have any other notifications you wan't to keep observing you can remove yourself from all observers by using this one line 
    // NotificationCenter.default.removeObserver(self) 
    } 
1

使用通知中心。

NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillAppear), name: NSNotification.Name.UIKeyboardWillShow, object: nil) 

NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillDisappear), name: NSNotification.Name.UIKeyboardWillHide, object: nil)