自动滚动到放置在 UITableViewCell 内的 textView 光标在 iOS11 中不起作用

Posted

技术标签:

【中文标题】自动滚动到放置在 UITableViewCell 内的 textView 光标在 iOS11 中不起作用【英文标题】:Autoscroll to the textView cursor which is placed inside the UITableViewCell is not working in iOS11 【发布时间】:2017-12-08 05:51:56 【问题描述】:

在编辑时,我有一个基于 UITextView 光标位置在 cell 内的 tableView 的自动滚动功能。

它在以前的 ios 版本中有效。从iOS11开始就坏了。

我已经根据键盘高度设置了tableViewcontentInset。对于自动滚动,我在textViewDidChange中使用以下代码

if let confirmedTextViewCursorPosition = textView.selectedTextRange?.end 

            let caretPosition = textView.caretRect(for: confirmedTextViewCursorPosition)
            var textViewActualPosition = tableView.convert(caretPosition, from: textView.superview?.superview)
            textViewActualPosition.origin.y += 22.0 
            tableView.scrollRectToVisible(textViewActualPosition, animated: false)

        

【问题讨论】:

您能在此添加更多代码吗?例如UITableViewUITableViewCell 的代码 【参考方案1】:

Askh1t 是正确的,这是我的实现:

    var info = notification.userInfo!
    var keyboardSize:CGRect = (info[UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
    if keyboardSize.size.height <= 0  // to fix bug on iOS 11
        keyboardSize = (info[UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
    

以及应该为您工作的完整模块化实现:

//MARK: - Properties
var activeTextView: UITextView?

//MARK: - Scroll View Notifications
// add in viewDidLoad
func registerForKeyboardNotifications()
    //Adding notifies on keyboard appearing
    NotificationCenter.default.addObserver(forName: Notification.Name.UIKeyboardWillShow, object: nil, queue: nil, using: keyboardWasShown)
    NotificationCenter.default.addObserver(forName: Notification.Name.UIKeyboardWillHide, object: nil, queue: nil, using: keyboardWillBeHidden)


//add in viewWillDisappear
func deregisterFromKeyboardNotifications()
    //Removing notifies on keyboard appearing
    NotificationCenter.default.removeObserver(self, name: Notification.Name.UIKeyboardDidShow, object: nil)
    NotificationCenter.default.removeObserver(self, name: Notification.Name.UIKeyboardWillHide, object: nil)


func keyboardWasShown(notification: Notification) -> Void 
    //Need to calculate keyboard exact size due to Apple suggestions
    self.tableView.isScrollEnabled = true
    var info = notification.userInfo!
    var keyboardSize:CGRect = (info[UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
    if keyboardSize.size.height <= 0  // to fix bug on iOS 11
        keyboardSize = (info[UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
    
    self.tableView.contentInset.bottom = keyboardSize.height //add this much
    self.tableView.scrollIndicatorInsets.bottom = keyboardSize.height //scroll too it.

    var aRect : CGRect = self.view.frame
    aRect.size.height -= keyboardSize.height
    if let activeField = self.activeTextView 
        if (!aRect.contains(activeField.frame.origin))
            self.tableView.scrollRectToVisible(activeField.frame, animated: true)
        
    


func keyboardWillBeHidden(notification: Notification)
    self.tableView.contentInset.bottom = 0
    self.tableView.isScrollEnabled = true
    self.tableView.alwaysBounceVertical = true


func textViewDidBeginEditing(_ textView: UITextView)
    activeTextView = textView




func textViewDidEndEditing(_ textView: UITextView)
    tableView.isScrollEnabled = true
    activeTextView = nil

【讨论】:

这里的问题是计算是正确的,但 tableview scrolltorect 不起作用。当我添加计时器块来执行 tableview.scrolltoRect 它工作得很好 确保在设置 .isScrollEnabled 后调用您的代码。更新 ui 的同步块需要在主线程上调用。 我只是在主线程内调用 scrolltorect 但它不适用于 iOS 11

以上是关于自动滚动到放置在 UITableViewCell 内的 textView 光标在 iOS11 中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

出队的 UITableViewCell 在滚动之前布局不正确(使用自动布局)

向下滚动并返回时 UITextField 进入 UITableViewCell 自动重置?

滚动时 UITableViewCell 自动布局抖动的动态单元格高度问题

滚动 UITableViewCell 时自动布局中断,尤其是对于 UIImageView

UITableViewCell 扩展自动布局

滚动所有 uitableviewcell 内的所有 UICollectionView