The problem: UITextView
silently changes it's contentSize
in some situations.
The simplest case textView with large text and keyboard. Just add UITextView outlet and set - viewDidLoad
as:
- (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);
}
Now showing and hiding keyboard will cause text jumps in some cases.
I've found the reason of jumping by subclass UITextView
. The only method in my subclass is:
- (void)setContentSize:(CGSize)contentSize {
NSLog(@"CS: %@", NSStringFromCGSize(contentSize));
[super setContentSize:contentSize];
}
And it show contentSize
shrinks and expands on keyboard hide. Something like this:
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}
Looks like behavior of UITextView
was changed a lot in iOS7. And some things are broken now.
Discovering further I've found that new layoutManager
property of my textView changes too. There some interesting info in log now:
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
And next line with contentSize = {320, 885}
contains Layout tree contents: ..., 2127 laid glyphs, 51 laid line fragments
. So it looks like some kind of autolayout tries to re-layout textView on keyboard show and changes contentSize even if layout is not finished yet. And it runs even if my textView is not changes between keyboard show/hide.
The question is: how to prevent contentSize changes?