Saturday, October 28, 2017

Following cursor in dynamic UITextView with UITableView no longer working in iOS 11

Leave a Comment

I created a UITextView which is sized dynamically within a UITableViewCell as a person types.

On iOS 10 the UITextView's cursor is followed automatically with very little code needed.

In the UITextViewDelegate method textViewDidChange: I've used this code which updated the size of the text view without any jumping around.

func textViewDidChange(_ textView: UITextView) {     UIView.setAnimationsEnabled(false)     self.tableView.beginUpdates()     self.tableView.endUpdates()     UIView.setAnimationsEnabled(true)     self.tableView.contentOffset = currentOffset } 

In iOS 11 this no longer works and when I type the cursor disappears under the keyboard. Note that I didn't need any changes when the keyboard appeared.

I know that there were changes in iOS 11 related to how content insets work but have been unable to figure out what changes I'd need to make to make this work.

Where should I be looking to make these changes to fix it?

-- Update --

It would turn out that removing all of that code solves my problem in iOS 11 and iOS 11 handles scrolling down to follow the cursor as I type automatically without any problems.

The one issue I have remaining is that I can only type up to 28 lines of text into the UITextView before it stops updating the UITextViews size.

3 Answers

Answers 1

class TextViewTableCell: UITableViewCell {      @IBOutlet private weak var textView: UITextView! {         didSet {             textView.delegate = self             textView.isScrollEnabled = false         }     }      var textDidChangeHandler: (((text: String?, shouldScroll: Bool)) -> Void)?      func textViewDidChange(_ textView: UITextView) {         let size = textView.bounds.size         let newSize = textView.sizeThatFits(CGSize(width: size.width, height: .greatestFiniteMagnitude))          let shouldScroll = size.height != newSize.height ? textView.text.count == textView.selectedRange.location : false         textDidChangeHandler?((text: textView.text, shouldScroll: shouldScroll))     } } 

Inside you data source cellForRow method:

// dequeue TextViewTableCell cell cell.textDidChangeHandler = { [weak self] (text, shouldScroll) in     guard let this = self else { return }     // do whatever actions with text if needed     guard shouldScroll else { return }     UIView.performWithoutAnimation {         tableView.beginUpdates()         tableView.endUpdates()      }     tableView.scrollToRow(at: indexPath, at: .bottom, animated: false) } 

Also good to have minimum height constraint for text view (for e.g. >=44)

Answers 2

I am using the sabe method to update a textView, and it's working fine for more than 28 lines of text, make sure you have all this properties set:

textView.showsVerticalScrollIndicator = false textView.isScrollEnabled = false 

also when i define the textView text i call textView.sizeToFit()

Answers 3

From XCode 9, the calculation of row is automatic once you set properties in size inspector of tableview.Here, You can check this in image and I mad one change in func textViewDidChange(_ textView: UITextView) Below is my code

 func textViewDidChange(_ textView: UITextView) {         UIView.setAnimationsEnabled(false)         self.tableView.beginUpdates()         self.tableView.endUpdates()         UIView.setAnimationsEnabled(true)         textView.sizeToFit()     } 

and It's working fine for me in iOS 11

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment