尽管这已经得到解答,但我在构建自己的UITextView
带有搜索突出显示的子类时遇到了同样的问题(如果您感兴趣,它可以在我的 GitHub 上找到scrollRangeToVisible:
)并提出了该方法的自定义实现。您需要做的就是按照您已经在做的那样调整您的contentInset
和scrollIndicatorInset
属性(阅读本文的普通 Google 员工的相关答案),然后致电:UITextView
[textView scrollRangeToVisible:range consideringInsets:YES];
我将相关代码封装在一个类别中,该类别还有一些其他有用的方法来解释 iOS 7 中的插入:
注意:由于我在子类中组织此代码的方式,您都需要它们。随意根据自己的喜好重新组织它。
@interface UITextView (insets)
// Scrolls to visible range, eventually considering insets
- (void)scrollRangeToVisible:(NSRange)range consideringInsets:(BOOL)considerInsets;
// Scrolls to visible rect, eventually considering insets
- (void)scrollRectToVisible:(CGRect)rect animated:(BOOL)animated consideringInsets:(BOOL)considerInsets;
// Returns visible rect, eventually considering insets
- (CGRect)visibleRectConsideringInsets:(BOOL)considerInsets;
@end
@implementation UITextView (insets)
// Scrolls to visible range, eventually considering insets
- (void)scrollRangeToVisible:(NSRange)range consideringInsets:(BOOL)considerInsets
{
if (considerInsets && (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1))
{
// Calculates rect for range
UITextPosition *startPosition = [self positionFromPosition:self.beginningOfDocument offset:range.location];
UITextPosition *endPosition = [self positionFromPosition:startPosition offset:range.length];
UITextRange *textRange = [self textRangeFromPosition:startPosition toPosition:endPosition];
CGRect rect = [self firstRectForRange:textRange];
// Scrolls to visible rect
[self scrollRectToVisible:rect animated:YES consideringInsets:YES];
}
else
[self scrollRangeToVisible:range];
}
// Scrolls to visible rect, eventually considering insets
- (void)scrollRectToVisible:(CGRect)rect animated:(BOOL)animated consideringInsets:(BOOL)considerInsets
{
if (considerInsets && (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1))
{
// Gets bounds and calculates visible rect
CGRect bounds = self.bounds;
UIEdgeInsets contentInset = self.contentInset;
CGRect visibleRect = [self visibleRectConsideringInsets:YES];
// Do not scroll if rect is on screen
if (!CGRectContainsRect(visibleRect, rect))
{
CGPoint contentOffset = self.contentOffset;
// Calculates new contentOffset
if (rect.origin.y < visibleRect.origin.y)
// rect precedes bounds, scroll up
contentOffset.y = rect.origin.y - contentInset.top;
else
// rect follows bounds, scroll down
contentOffset.y = rect.origin.y + contentInset.bottom + rect.size.height - bounds.size.height;
[self setContentOffset:contentOffset animated:animated];
}
}
else
[self scrollRectToVisible:rect animated:animated];
}
// Returns visible rect, eventually considering insets
- (CGRect)visibleRectConsideringInsets:(BOOL)considerInsets
{
CGRect bounds = self.bounds;
if (considerInsets)
{
UIEdgeInsets contentInset = self.contentInset;
CGRect visibleRect = self.bounds;
visibleRect.origin.x += contentInset.left;
visibleRect.origin.y += contentInset.top;
visibleRect.size.width -= (contentInset.left + contentInset.right);
visibleRect.size.height -= (contentInset.top + contentInset.bottom);
return visibleRect;
}
return bounds;
}
@end