问题:在某些情况下,
最简单的情况是当有大段文本和键盘时。只需添加 UITextView outlet,并将
UITextView
会默默地更改其 contentSize
。最简单的情况是当有大段文本和键盘时。只需添加 UITextView outlet,并将
- viewDidLoad
设置为以下内容:- (void)viewDidLoad {
[super viewDidLoad];
// expand default "Lorem..."
_textView.text = [NSString stringWithFormat:@"1%@\n\n2%@\n\n3%@\n\n4%@\n\n5", _textView.text, _textView.text, _textView.text, _textView.text];
_textView.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive;
_textView.contentInset = UIEdgeInsetsMake(0, 0, 216, 0);
}
现在,在某些情况下,显示或隐藏键盘会导致文本跳动。
我通过子类化 UITextView
找到了跳动的原因。我的子类中唯一的方法是:
- (void)setContentSize:(CGSize)contentSize {
NSLog(@"CS: %@", NSStringFromCGSize(contentSize));
[super setContentSize:contentSize];
}
当键盘隐藏时,contentSize
会缩小或扩展。类似于这样:
013-09-16 14:40:27.305 textView-bug2[11087:a0b] CS: {320, 651}
2013-09-16 14:40:27.313 textView-bug2[11087:a0b] CS: {320, 885}
2013-09-16 14:40:27.318 textView-bug2[11087:a0b] CS: {320, 902}
看起来iOS7中UITextView
的行为发生了很大变化。现在有些东西坏掉了。
进一步探索后,我发现我的textView的新layoutManager
属性也改变了。现在日志中有一些有趣的信息:
2013-09-16 14:41:59.352 textView-bug2[11115:a0b] CS: {320, 668}
<NSLayoutManager: 0x899e800>
1 containers, text backing has 2129 characters
Currently holding 2129 glyphs.
Glyph tree contents: 2129 characters, 2129 glyphs, 3 nodes, 96 node bytes, 5440 storage bytes, 5536 total bytes, 2.60 bytes per character, 2.60 bytes per glyph
Layout tree contents: 2129 characters, 2129 glyphs, 532 laid glyphs, 13 laid line fragments, 4 nodes, 128 node bytes, 1048 storage bytes, 1176 total bytes, 0.55 bytes per character, 0.55 bytes per glyph, 40.92 laid glyphs per laid line fragment, 90.46 bytes per laid line fragment
下一行内容的contentSize为{320, 885}
, 包含Layout tree contents: ..., 2127 laid glyphs, 51 laid line fragments
。看起来像是某种自动布局在键盘显示时尝试重新布局textView并更改了contentSize,即使布局尚未完成。即使在键盘显示/隐藏之间我的textView没有变化,它仍然运行。
问题是:如何防止contentSize发生变化?
lineFragmentUsedRectForGlyphAtIndex
)时,这对于布局管理器并不友好,因为它会忽略任何超出文本容器大小的内容。 - Joshua9999999
,则会出现跳跃现象,因此任何高度超过1000万(10 000 000
)的容器都会导致跳跃。我不确定为什么这个数字很特殊,但事实就是如此。 - Joshua