UITextView cursor below frame when changing frame

前端 未结 9 421
名媛妹妹
名媛妹妹 2020-12-01 06:50

I have a UIViewCOntrollerthat contains a UITextView. When the keyboard appears I resize it like this:

#pragma mark - Responding to          


        
相关标签:
9条回答
  • 2020-12-01 07:36

    A lot of answers already, I found that in my case it's actually much simpler. On keyboardWillShow I adjust the text view's contentInset and keep the frame full screen. And while scrollRangeToVisible: is not working for me like for so many others, the scroll view methods (from which UITextView inherits) work just fine. This works for me:

    - (void)textViewDidChange:(UITextView *)textView
    {
        CGRect caret = [_textView caretRectForPosition:_textView.selectedTextRange.end];
        [_textView scrollRectToVisible:caret animated:YES];
    }
    
    0 讨论(0)
  • 2020-12-01 07:36

    This is what I ended up doing, and something that seems to work:

    - (void)textViewKeyboardWillShow:(NSNotification *)notification
    {
    
        NSDictionary* info = [notification userInfo];
        CGSize kbSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
    
         // self.textViewBottomSpace.constant = NSLayoutConstraint in IB (bottom position)
        self.textViewBottomSpace.constant = kbSize.height + 70;
        [self.textView setNeedsDisplay];
    }
    
    
    - (void)textViewKeyboardWillHide:(NSNotification *)notification
    {
        self.textViewBottomSpace.constant = 0;
        [self.textView setNeedsDisplay];
    }
    
    - (void)scrollCaretToVisible
    {
        //This is where the cursor is at.
        CGRect caretRect = [self.textView caretRectForPosition:self.textView.selectedTextRange.end];
    
        if(CGRectEqualToRect(caretRect, _oldRect))
            return;
    
        _oldRect = caretRect;
    
        //This is the visible rect of the textview.
        CGRect visibleRect = self.textView.bounds;
        visibleRect.size.height -= (self.textView.contentInset.top + self.textView.contentInset.bottom);
        visibleRect.origin.y = self.textView.contentOffset.y;
    
        //We will scroll only if the caret falls outside of the visible rect.
        if(!CGRectContainsRect(visibleRect, caretRect)) {
            CGPoint newOffset = self.textView.contentOffset;
    
            newOffset.y = MAX((caretRect.origin.y + caretRect.size.height) - visibleRect.size.height + 10, 0);
    
            [self.textView setContentOffset:newOffset animated:YES];
        }
    }
    
    - (void)textViewDidEndEditing:(UITextView *)textView
    {    
        [_caretVisibilityTimer invalidate];
        _caretVisibilityTimer = nil;
    }
    
    - (void)textViewDidBeginEditing:(UITextView *)textView
    { 
        self.oldRect = [self.textView caretRectForPosition:self.textView.selectedTextRange.end];
        self.caretVisibilityTimer = [NSTimer scheduledTimerWithTimeInterval:0.3 target:self selector:@selector(scrollCaretToVisible) userInfo:nil repeats:YES];
    }
    
    0 讨论(0)
  • 2020-12-01 07:38

    A simpler solution to this problem is to update the text view frame in response to the textViewDidBegingEditing delegate method. For further details, see the following:

    How to re-size UITextView when keyboard shown with iOS 7

    0 讨论(0)
提交回复
热议问题