2017-03-08 95 views
0

下面是处理使用UITextFields和高UITableViewCells滚动的最佳方法吗?UITextField和UITableViewCell自动滚动

我有一个UITableView与高细胞和UITextFields里面,分布从上到下。高,我的意思是当弹出键盘时,整个单元格不能显示。

当依赖默认行为时,当位于单元格顶部的UITextField被选中时,自动滚动不起作用。这似乎是非常基本的,总是滚动到底部位置,这导致隐藏最顶层的UITextFields(包括所选的一个)。

因此,我使用UIKeyboardWillShow/UIKeyboardDidShow通知。

我试着首先使用这种行为仅用于顶部的UITextFields,否则依靠默认行为,但由于某种原因,自动滚动不再可靠,所以我用手动滚动查看所有内容。

下面是我使用的(有点“经典”)代码。 基本上,我只是告诉tableview中,其中滚动到,改变根据的UITextField的UITableViewScrollPosition被选中

var scrollTo: (indexPath: IndexPath, position: UITableViewScrollPosition)? 

override func viewWillAppear(_ animated: Bool) { 
    super.viewWillAppear(animated) 
    registerForKeyboardNotifications() 
} 

override func viewWillDisappear(_ animated: Bool) { 
    unregisterForKeyboardNotifications() 
    super.viewWillDisappear(animated) 
} 

func registerForKeyboardNotifications() { 
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil) 
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardDidShow), name: NSNotification.Name.UIKeyboardDidShow, object: nil) 
} 

func unregisterForKeyboardNotifications() { 
    NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: nil) 
    NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardDidShow, object: nil) 
} 

func keyboardWillShow() { 
    tableView.isScrollEnabled = scrollTo == nil 
} 

func keyboardDidShow() { 
    guard let scrollTo = scrollTo else { return } 
    self.scrollTo = nil 
    tableView.scrollToRow(at: scrollTo.indexPath, at: scrollTo.position, animated: true) 
    tableView.isScrollEnabled = true 
} 

/// Textfields are tagged to allow UITextFieldDelegate method identification 
/// I renamed each text field according to its location in the cell for sake of clarity 
enum CellTextField: Int { 
    case topFieldA = 1, topFieldB, middleFieldA, bottomFieldA, bottomFieldB 

    static let multiplier = 10 

    static func identifiersFrom(cellTag: Int) -> (cellTextField: CellTextField, indexPath: IndexPath)? { 
     guard let cellTextField = CellTextField(rawValue: cellTag % CellTextField.multiplier) else { 
      return nil 
     } 
     let indexPath = IndexPath(row: cellTag/CellTextField.multiplier, section: 0) 
     return (cellTextField, indexPath) 
    } 

    func tagFor(row: Int) -> Int { 
     return row * CellTextField.multiplier + self.rawValue 
    } 
} 

/// When the textfield is selected, I retrieve the indexPath from the textfield tag 
/// (set by tableView(tableView:cellForRowAt indexPath:)) and set the most relevant 
//// scrollTo position according to the textfield position in the cell 
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool { 
    guard let identifiers = CellTextField.identifiersFrom(cellTag: textField.tag) else { return true } 
    switch identifiers.cellTextField { 
    case .topFieldA, . topFieldB: 
     scrollTo = (identifiers.indexPath, .top) 
    case . middleFieldA: 
     scrollTo = (identifiers.indexPath, .middle) 
    case .bottomFieldA, . bottomFieldB: 
     scrollTo = (identifiers.indexPath, .bottom) 
    } 
    return true 
} 

上面的代码工作正常,它只是似乎是一个开销很大的罪有高细胞。或者它是处理这个问题的正确方法?

回答

0

我带你去得不到答案为一体:是的,这是处理它的正确方法。

相关问题