Reputation: 4451
I have UIScrollView which has some views including UITextView. UITextView is bigger that the screen and has some text and has scrolling disabled. If the user tap on text view I would like to scroll my main scroll view to the position of the cursor in the text view. How can I do it? I tried use selectedRange but it doesn't seem to work.
Upvotes: 2
Views: 2172
Reputation: 7344
Here is my a little more sofisticated solution:
- (void)scrollView:(UIScrollView *)scrollView scrollToTextInput:(UIResponder *)responder
{
if (!responder || ![responder conformsToProtocol:@protocol(UITextInput)] || ![responder isKindOfClass:[UIView class]]) {
return;
}
UIView<UITextInput> *textInput = (UIView<UITextInput> *)responder;
UIView *nextView = textInput;
while (nextView && (nextView != scrollView))
{
nextView = [nextView superview];
}
if (!nextView)
{
// Oh, this view is not from our `scrollView`.
return;
}
CGRect cursorRect = [textInput caretRectForPosition:textInput.selectedTextRange.start];
CGPoint cursorPoint = CGPointMake(CGRectGetMidX(cursorRect), CGRectGetMidY(cursorRect));
cursorPoint = [scrollView convertPoint:cursorPoint fromView:textInput];
CGFloat contentHeight = scrollView.contentSize.height;
CGFloat containerHeight = scrollView.frame.size.height;
CGFloat topInset = scrollView.contentInset.top;
CGFloat bottomInset = scrollView.contentInset.bottom;
CGFloat verticalInsets = scrollView.contentInset.top + scrollView.contentInset.bottom;
CGFloat offsetY = cursorPoint.y - (containerHeight - verticalInsets) / 2.f;
offsetY = MIN(MAX(offsetY, topInset), contentHeight - containerHeight + verticalInsets);
[scrollView setContentOffset:CGPointMake(scrollView.contentOffset.x, offsetY) animated:YES];
}
Upvotes: 1
Reputation: 4451
I did it in such way:
- (void)textViewDidBeginEditing:(UITextView *)textView
{
[self performSelector:@selector(scrollToCursorPosition:) withObject:textView afterDelay:0.05f];
}
- (void)scrollToCursorPosition:(UITextView *)textView
{
UITextRange *range = textView.selectedTextRange;
UITextPosition *position = range.start;
CGRect cursorRect = [textView caretRectForPosition:position];
CGPoint cursorPoint = CGPointMake(textView.frame.origin.x + cursorRect.origin.x, textView.frame.origin.y + cursorRect.origin.y);
[self setContentOffset:CGPointMake((cursorPoint.x - 10) * self.zoomScale, (cursorPoint.y - 10) * self.zoomScale) animated:NO];
}
if someone knows the better solution then please write the answer and I will accept it.
Upvotes: 0