Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UITextView contentOffset changes between viewDidLoad and viewDidAppear

On iOS 8 (I have not tested on iOS 7) I have a UITextView that has its text set in the storyboard. When the view actually appears, the text appears scrolled and I do not want it scrolled. In fact, I have no idea why anyone would. Can anyone explain how to change this behavior so it appears scrolled to the top as it should?

This is extremely easy to reproduce:

  1. Start a new project
  2. Add a UITextView with constraints to sticky it to the margins
  3. Fill it with more text than will fit in its bounds (helps to increase the font size to something like 36).
  4. Run.

It is immediately visually obvious, but if you log what is going on you will see something like the following:

2015-03-10 10:34:47.198 ScrollViewTest[61180:2610445] [Inside viewDidLoad] <UITextView: 0x7f9c79851200; frame = (0 0; 600 600); text = 'Lorem ipsum dolor sit er ...'; clipsToBounds = YES; autoresize = RM+BM; gestureRecognizers = <NSArray: 0x7f9c78c89df0>; layer = <CALayer: 0x7f9c78c8c220>; contentOffset: {0, 0}; contentSize: {600, 592}>
2015-03-10 10:34:47.288 ScrollViewTest[61180:2610445] [Inside viewDidAppear] <UITextView: 0x7f9c79851200; frame = (0 0; 375 667); text = 'Lorem ipsum dolor sit er ...'; clipsToBounds = YES; autoresize = RM+BM; gestureRecognizers = <NSArray: 0x7f9c78c89df0>; layer = <CALayer: 0x7f9c78c8c220>; contentOffset: {0, 457.5}; contentSize: {375, 1176}>

Presumably this is because of the frame and/or contentSize change from the initial load from the storyboard to the actual dimensions it needs to display.

This seems similar to UITextView contentOffset is set but the accepted answer to that question does not work. This is also not solved by setting self.automaticallyAdjustsScrollViewInsets = NO.

like image 286
colinbrash Avatar asked Mar 16 '23 19:03

colinbrash


1 Answers

My guess is that when auto layout is applied, the content offset is mangled. This happens right before -layoutSubviews is performed.

So to fix this issue, I could recommend two solutions.

  1. Subclass UITextView and set contentOffset in -layoutSubviews.
  2. Add -viewDidLayoutSubviews to your view controller and set contentOffset for any text views there.

Both of these are kind of hacky workarounds, but are better hacky workarounds than -viewDidAppear: or dispatch_async().


NOTE: Take care to ensure you only adjust the contentOffset in -layoutSubviews or -viewDidLayoutSubviews when appropriate.

like image 88
Jeffery Thomas Avatar answered Apr 07 '23 22:04

Jeffery Thomas