iOS7或TextKit中,替代scrollRangeToVisible的方法是什么?

9
在之前的iOS版本中,我的UITextView会使用下面的代码滚动到底部:
[displayText scrollRangeToVisible:NSMakeRange(0,[displayText.text length])];

或者

CGFloat topCorrect = displayText.contentSize.height -[displayText bounds].size.height;
topCorrect = (topCorrect<0.0?0.0:topCorrect);
displayText.contentOffset = (CGPoint){.x=0, .y=topCorrect};

但是以前的方法会导致每次向视图添加文本时,从长段文字的顶部开始滚动并滚动到底部,这样会产生一种奇怪的效果。是否有一种方法可以在添加文本时跳转到文本底部?

5个回答

3
textView.scrollEnabled = NO;
[textView scrollRangeToVisible:NSMakeRange(textView.text.length - 1,0)];
textView.scrollEnabled = YES;

在iOS 7.1.2中,这对我非常有效。


3

对于未来的旅行者,借鉴@mikeho的帖子,我发现了一些对我非常有效的方法,但是比较简单。

1)确保你的UITextViewcontentInset设置正确,并且在执行此操作之前你的textView已经处于firstResponder()状态。
2)在我的插图准备好并且光标是活动状态后,我调用以下函数:

private func scrollToCursorPosition() {
    let caret = textView.caretRectForPosition(textView.selectedTextRange!.start)
    let keyboardTopBorder = textView.bounds.size.height - keyboardHeight!

   // Remember, the y-scale starts in the upper-left hand corner at "0", then gets
   // larger as you go down the screen from top-to-bottom. Therefore, the caret.origin.y
   // being larger than keyboardTopBorder indicates that the caret sits below the
   // keyboardTopBorder, and the textView needs to scroll to the position.
   if caret.origin.y > keyboardTopBorder {
        textView.scrollRectToVisible(caret, animated: true)
    }
 }

2

我认为这是iOS 7中的一个bug。在UITextView上切换scrollEnabled似乎可以解决它:

[displayText scrollRangeToVisible:NSMakeRange(0,[displayText.text length])];
displayText.scrollEnabled = NO;
displayText.scrollEnabled = YES;

1
@stian-høiland 看起来是正确的,这个解决方法不再可行。 - Peter Heide
@user3907849有一个可行的解决方案。重要的是在调用scrollRangeToVisible:之前设置scrollEnabled = NO。使用整个字符串或仅使用最后一个字符都可以滚动到底部。 - Peter Heide

0

最好的方式是为UITextView设置边界。它不会触发滚动,并立即重新定位可见内容。您可以通过找到光标的位置然后重新定位来实现:

- (void)userInsertingNewText {
    UITextView *textView;
    // find out where the caret is located
    CGRect caret = [textView caretRectForPosition:textView.selectedTextRange.start];
    // there are insets that offset the text, so make sure we use that to determine the actual text height
    UIEdgeInsets textInsets = textView.textContainerInset;
    CGFloat textViewHeight = textView.frame.size.height - textInsets.top - textInsets.bottom;
    // only set the offset if the caret is out of view
    if (textViewHeight < caret.origin.y) {
        [self repositionScrollView:textView newOffset:CGPointMake(0, caret.origin.y - textViewHeight)];
    }
}

/**
 This method allows for changing of the content offset for a UIScrollView without triggering the scrollViewDidScroll: delegate method.
 */
- (void)repositionScrollView:(UIScrollView *)scrollView newOffset:(CGPoint)offset {
    CGRect scrollBounds = scrollView.bounds;
    scrollBounds.origin = offset;
    scrollView.bounds = scrollBounds;
}

0

我认为你在NSMakeRange中的参数是颠倒的。位置是第一个参数,然后是你想选择的数量(长度)。

NSMakeRange(0,[displayText.text length])

...将创建一个从第0个(第一个?)字符开始并沿字符串的整个长度进行选择的选择。要滚动到底部,您可能只想选择末尾的单个字符。

在iOS SDK 7.1和Xcdoe 5.1.1中,这对我有效。

[textView scrollRangeToVisible:NSMakeRange(textView.text.length - 1,0)];
textView.scrollEnabled = NO;
textView.scrollEnabled = YES;

我这样做是因为我通过编程方式添加文本,而文本视图保持在底部,就像终端或命令行输出一样。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接