编辑
简单的解决方案是将任何帧计算从viewDidLoad移到viewDidAppear:
我很难让下面的代码正常工作
该代码返回给定NSRange在UITextView中的第一个帧。
如果没有换行,它就能工作,但是当我在UITextView中添加换行时,我会得到一些奇怪的行为。
@implementation UITextView (TextFrame)
- (CGRect)frameOfTextRange:(NSRange)range {
UITextPosition *beginning = self.beginningOfDocument;
UITextPosition *start = [self positionFromPosition:beginning offset:range.location];
UITextPosition *end = [self positionFromPosition:start offset:range.length];
UITextRange *textRange = [self textRangeFromPosition:start toPosition:end];
CGRect rect = [self firstRectForRange:textRange];
return [self convertRect:rect fromView:self.textInputView];
}
@end
@implementation DetailViewController
- (void)viewDidLoad
{
[super viewDidLoad];
if (self.searchString) {
CGRect rect = [self.textView frameOfTextRange:[self.textView.text rangeOfString:self.searchString]];
...
}
}发布于 2014-08-19 17:19:04
很明显,firstRectForRange:似乎不在viewDidLoad工作
将计算从viewDidLoad转移到viewDidAppear: 解决了问题
旧码
- (void)viewDidLoad
{
[super viewDidLoad];
if (self.searchString) {
CGRect rect = [self.textView frameOfTextRange:[self.textView.text rangeOfString:self.searchString]];
[self.textView scrollRangeToVisible:[self.textView.text rangeOfString:self.searchString]];
UIView *markerView = [[UIView alloc] initWithFrame:rect];
markerView.backgroundColor = [UIColor colorWithRed:0.810 green:0.735 blue:0.000 alpha:0.660];
[self.textView addSubview:markerView];
_searchString = nil;
}
}新代码和工作代码
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
if (self.searchString) {
CGRect rect = [self.textView frameOfTextRange:[self.textView.text rangeOfString:self.searchString]];
[self.textView scrollRangeToVisible:[self.textView.text rangeOfString:self.searchString]];
UIView *markerView = [[UIView alloc] initWithFrame:rect];
markerView.backgroundColor = [UIColor colorWithRed:0.810 green:0.735 blue:0.000 alpha:0.660];
[self.textView addSubview:markerView];
_searchString = nil;
}
}发布于 2015-04-11 11:16:53
我找到了下面的解决方案。不使用只返回一个rect的firstRectForRange:,而是使用selectionRectsForRange:,然后遍历所有rect并使用CGRectUnion组合它们。
- (CGRect)frameOfTextRange:(NSRange)range
{
UITextPosition *beginning = self.beginningOfDocument;
UITextPosition *start = [self positionFromPosition: beginning offset: range.location];
UITextPosition *end = [self positionFromPosition: start offset: range.length];
UITextRange *textRange = [self textRangeFromPosition: start toPosition: end];
CGRect rect = CGRectZero;
NSArray *selectionRects = [self selectionRectsForRange: textRange];
for (UITextSelectionRect *selectionRect in selectionRects)
{
rect = CGRectUnion(rect, selectionRect.rect);
}
return rect;
}发布于 2014-08-21 05:12:43
可以强制self.textView确保在以下情况下立即进行布局:
[self.textView.layoutManager ensureLayoutForTextContainer:self.textView.textContainer];将其放置在frameOfTextRange:电话前将使您正确地重新定位。
当然,您可以在frameOfTextRange:方法中调用它:
- (CGRect)frameOfTextRange:(NSRange)range {
[self.layoutManager ensureLayoutForTextContainer:self.textContainer];
...这使得可以安全地从任何地方调用frameOfTextRange:方法。
https://stackoverflow.com/questions/25146850
复制相似问题