【问题标题】:How to manage keyboard when there are UITextFields in UITableView using swift?当 UITableView 中有 UITextFields 时如何使用 swift 管理键盘?
【发布时间】:2018-04-22 11:12:11
【问题描述】:

我正在尝试寻找一种方法来避免键盘在动态 UITableViews 中不阻塞选定的 UITextField。

我知道这是一个常见问题,对此有很多答案。但是,我找到的答案要么在 Obj-C 中,要么不涉及动态 UITableView。

我的表格视图有自己的 UITableViewCell,所以 UITextFields 连接到它。

另外,我想在输入 UITextField 时刷新单元格。我可以将该信息(我猜是单元格的 IndexPath.row?)传递给 UIViewController 并让它监听更改并应用重新加载单元格方法吗?

这是我的相关代码:

class favCell: UITableViewCell, UITextFieldDelegate {

    @IBOutlet weak var deciPadField: UITextField!

    @objc func doneClicked(){
        updateTotalWorth()
        deciPadField.resignFirstResponder()
        deciPadField.endEditing(true)
    }

    func textFieldDidBeginEditing(_ textField: UITextField) {
        deciPadField.becomeFirstResponder()
    }

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        let currentString: NSString = (textField.text ?? "") as NSString
        let newString = currentString.replacingCharacters(in: range, with: string)
        return  newString.count <= 10
    }

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        updateTotalWorth()
        deciPadField.resignFirstResponder()
        return true
    }

    private func textViewDidEndEditing(_ textView: UITextView) {
        updateTotalWorth()
        deciPadField.endEditing(true)
    }
}

更新:

如果我可以从 UITableViewCell 访问我的 ViewControllers 视图,下面的代码就可以解决问题:

func animateTextField(textField: UITextField, up: Bool) {
    let movementDistance:CGFloat = -130
    let movementDuration: Double = 0.3
    var movement:CGFloat = 0

    if up {
        movement = movementDistance
    } else {
        movement = -movementDistance
    }
    UIView.beginAnimations("animateTextField", context: nil)
    UIView.setAnimationBeginsFromCurrentState(true)
    UIView.setAnimationDuration(movementDuration)

    // Below line giving error, could not find the view. My ListVC.view should be referred to.
    self.view.frame = self.view.frame.offsetBy(dx: 0, dy: movement)

    UIView.commitAnimations()
}


func textFieldDidBeginEditing(textField: UITextField) {
    self.animateTextField(textField: textField, up:true)
}

func textFieldDidEndEditing(textField: UITextField) {
    self.animateTextField(textField: textField, up:false)
}

谢谢!

【问题讨论】:

  • 试试 self.view.endediting()
  • 如果你 (A) 继承UITableViewController,它应该会自动为你处理。如果您(B) 添加UITableView 作为UIViewController 的子视图,则您必须在显示/隐藏键盘时自己进行调整。你是在做(A)还是(B)
  • 我在做 B。我知道 UITableViewController 的差异。
  • 好的 - 那么你必须自己处理它。已经有很多例子了……通读这篇文章,看看你是否可以让它工作。如果没有,请返回并发布您尝试使用的代码:stackoverflow.com/questions/1126726/…

标签: ios arrays uitableview keyboard uitextfield


【解决方案1】:

好吧,我终于想出了如何解决这个问题。我实现了这个答案:https://stackoverflow.com/a/41040630/4441676

解决的代码如下:

在 ViewController 的 ViewDidLoad 里面添加了两个观察者,如下:

// Notification Observers
    NotificationCenter.default.addObserver(self, selector: #selector(ListVC.keyboardWillShow(notification:)), name: Notification.Name.UIKeyboardDidShow, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(ListVC.keyboardWillHide(notification:)), name: Notification.Name.UIKeyboardDidHide, object: nil)

并添加了相关的两个功能:

@objc func keyboardWillShow(notification: Notification) {
    if let keyboardHeight = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue.height {
        tableView.contentInset = UIEdgeInsetsMake(0, 0, keyboardHeight, 0)
    }
}

@objc func keyboardWillHide(notification: Notification) {
    UIView.animate(withDuration: 0.2, animations: {
        // For some reason adding inset in keyboardWillShow is animated by itself but removing is not, that's why we have to use animateWithDuration here
        self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0)
    })
}

在连接UITextFields的UITableViewCell中,简单实现UITextField Delegate,并在键盘显示/隐藏时添加相关的Notification.posts:

deciPadField.delegate = self

func textFieldDidBeginEditing(_ textField: UITextField) {
    NotificationCenter.default.post(name: Notification.Name.UIKeyboardDidShow, object: self)
}

func textFieldDidEndEditing(_ textField: UITextField) {
    NotificationCenter.default.post(name: Notification.Name.UIKeyboardDidHide, object: self)
}

我有 inputAccessoryView,所以通过以下方式处理关闭键盘:

// Decipad config for adding Done button above itself
let toolBar = UIToolbar()
toolBar.sizeToFit()
let flexiableSpace = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)
let doneButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.done, target: self, action: #selector(self.doneClicked))
toolBar.setItems([flexiableSpace, doneButton], animated: false)

@objc func doneClicked(){
    updateTotalWorth()
    deciPadField.resignFirstResponder()
    deciPadField.endEditing(true)
}

希望这对其他人有帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-18
    • 2013-07-28
    • 2016-03-22
    • 1970-01-01
    • 2016-01-29
    • 2012-04-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多