Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 486
Mark Reid Avatar asked Oct 19 '17 00:10

Mark Reid


2 Answers

I have the same problem, a UITableViewController with a UITableViewCell containing a non-scrolling editable UITextView in a cell, and the cursor would go behind the keyboard in iOS11. Worked fine in prior iOS versions.

I finally figured out a fix based on this and other articles:

- (void)textViewDidChange:(UITextView *)textView {
    // handle to UITableView
    UITableView *tableView = ....

    // tell table to resize itself
    [UIView performWithoutAnimation:^{
        [tableView beginUpdates];
        [tableView endUpdates];
    }];

    // get the caret rectangle so we can make sure we scroll it into view.
    CGRect unconvertedRect = [textView caretRectForPosition:textView.selectedTextRange.start];
    CGRect caretRect = [textView convertRect:unconvertedRect toView:tableView];
    // make the rect a little bigger so it's not at the extreme bottom of the view area
    caretRect.size.height += caretRect.size.height / 2;

    // this doesn't seem to work with a simple dispatch_async, but dispatch_after 0.1s seems to work.
    // why, i have no idea.
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [tableView scrollRectToVisible:caretRect animated:NO];
    });
}

Hope this helps someone...

like image 62
rodfleischer Avatar answered Oct 22 '22 20:10

rodfleischer


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

Here is Image of my tableview from storyboard, you can see constraints as well, which are simple and I am using it without margins.

And your textview cursor issue, I would suggest you IQKeyboardManager, it will manage all things like this.

like image 38
Dipak Kacha Avatar answered Oct 22 '22 21:10

Dipak Kacha