UITextView cursor below frame when changing frame

前端 未结 9 442
名媛妹妹
名媛妹妹 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:31

    All of the others answers I tried behaved somewhat strangely for me. Using an NSTimer to perform the scroll also meant that the user couldn't scroll up, since the caret would then end up off-screen and it would immediately scroll back down again. In the end I stuck with the original approach of changing the UITextView frame on the keyboard notification events, then added the following methods:

    - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
        // Whenever the user enters text, see if we need to scroll to keep the caret on screen
        [self scrollCaretToVisible];
        return YES;
    }
    
    - (void)scrollCaretToVisible
    {
        //This is where the cursor is at.
        CGRect caretRect = [self.textView caretRectForPosition:self.textView.selectedTextRange.end];
    
        // Convert into the correct coordinate system
        caretRect = [self.view convertRect:caretRect fromView:self.textView];
    
        if(CGRectEqualToRect(caretRect, _oldRect)) {
            // No change
            return;
        }
    
        _oldRect = caretRect;
    
        //This is the visible rect of the textview.
        CGRect visibleRect = self.textView.frame;
    
        //We will scroll only if the caret falls outside of the visible rect.
        if (!CGRectContainsRect(visibleRect, caretRect))
        {
            // Work out how much the scroll position would have to change by to make the cursor visible
            CGFloat diff = (caretRect.origin.y + caretRect.size.height) - (visibleRect.origin.y + visibleRect.size.height);
    
            // If diff < 0 then this isn't to do with the iOS7 bug, so ignore
            if (diff > 0) {
                // Scroll just enough to bring the cursor back into view
                CGPoint newOffset = self.textView.contentOffset;
                newOffset.y += diff;
                [self.textView setContentOffset:newOffset animated:YES];
            }
        }
    }
    

    Works like a charm for me

提交回复
热议问题