What is Causing this Unwanted Content Inset with UITextView in iOS 8 (not there in iOS 7)?
Asked Answered
S

2

5

I've been creating UITextViews programatically, using auto layout, in iOS 7. Something like this:

_textView = [UITextView new];
_textView.translatesAutoresizingMaskIntoConstraints = NO;
_textView.font = [UIFont systemFontOfSize:18.0];
_textView.delegate = self;
[self.view addSubview:_textView];

In addition to the other constraints I've created, I have this one for the bottom of the text view:

_textViewBottomConstraint = 
       [NSLayoutConstraint constraintWithItem:_textView
                                                     attribute:NSLayoutAttributeBottom
                                                     relatedBy:NSLayoutRelationEqual
                                                        toItem:self.bottomLayoutGuide
                                                     attribute:NSLayoutAttributeTop
                                                    multiplier:1.0
                                                      constant:0.0];

[self.view addConstraint:_textViewBottomConstraint];

So that I can change the constraint when the keyboard shows:

- (void)keyboardDidShow:(NSNotification*)sender
{
    CGRect keyboardFrame = 
                        [sender.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    CGRect convertedFrame = 
                        [self.view convertRect:keyboardFrame fromView:self.view.window];
    _textViewBottomConstraint.constant = -convertedFrame.size.height;
    [_textView layoutIfNeeded];
}

That's all been working fine...

Problem

I've just switched over to Xcode 6 and iOS 8 (late, I know) - and the text within the UITextView now has an inset at the top. E.g. (Text view background is yellow):

enter image description here

What's causing the inset? Is it connected to NSTextContainer and textContainerInset?

  • Is working with NSTextContainer and textContainerInset the correct way to use UITextView from iOS 7 and onward?
  • Does it have to be done that way in iOS 8?

If yes, I'd appreciate some guidance for programatically creating a UITextView along with the necessary NSTextContainer and NSLayoutManager; then setting textContainerInset. (I'll be using auto layout, programatically).

Thanks.

Selene answered 11/9, 2014 at 8:9 Comment(0)
T
9

I think automaticallyAdjustsScrollViewInsets works a bit differently in iOS 8. In 7, it only applied if the controller's view property was a scrollView. In 8, it seems to apply to scroll views that are subviews of the controllers' view.

Tortoise answered 16/9, 2014 at 20:44 Comment(0)
S
7

It's the contentInset from the UIViewController.

It seems that with iOS 8, with my UITextView as it is within my UIViewController, there's a need to explicitly set:

self.automaticallyAdjustsScrollViewInsets = NO;

Without explicitly setting that, I've checked the difference between a physical iPhone 5s running iOS 7 and the Simulator iPhone 5s running iOS 8.

Here is some log output, checking the top value for textContainerInset, contentInset and scrollIndicatorInset. In each case, after viewDidLoad and keyboardDidShow.

iPhone 5s Device running iOS 7:

2014-09-12 07:55:01.244 Alter[19147:60b] viewDidLoad
2014-09-12 07:55:01.249 Alter[19147:60b] textContainerInset Top: 8.000000
2014-09-12 07:55:01.252 Alter[19147:60b] contentInset Top: 0.000000
2014-09-12 07:55:01.253 Alter[19147:60b] scrollIndicatorInset Top: 0.000000

2014-09-12 07:55:02.515 Alter[19147:60b] keyboardDidShow
2014-09-12 07:55:02.516 Alter[19147:60b] textContainerInset Top: 8.000000
2014-09-12 07:55:02.516 Alter[19147:60b] contentInset Top: 0.000000
2014-09-12 07:55:02.516 Alter[19147:60b] scrollIndicatorInset Top: 0.000000

Simulator iPhone 5s (or 6, or 6 Plus) running iOS 8:

2014-09-12 07:55:39.395 Alter[2120:109535] viewDidLoad
2014-09-12 07:55:39.395 Alter[2120:109535] textContainerInset Top: 8.000000
2014-09-12 07:55:39.396 Alter[2120:109535] contentInset Top: 0.000000
2014-09-12 07:55:39.396 Alter[2120:109535] scrollIndicatorInset Top: 0.000000

2014-09-12 07:55:39.939 Alter[2120:109535] keyboardDidShow
2014-09-12 07:55:39.939 Alter[2120:109535] textContainerInset Top: 8.000000
2014-09-12 07:55:39.939 Alter[2120:109535] contentInset Top: 64.000000
2014-09-12 07:55:39.939 Alter[2120:109535] scrollIndicatorInset Top: 64.000000

To answer my own question, I don't need to manually set up the NSTextContainer and the NSLayoutManager. Though it might be better to start using the textContainerInset approach, I have the option to adjust the frame if I set this in the parent view controller:

self.automaticallyAdjustsScrollViewInsets = NO;
Selene answered 12/9, 2014 at 7:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.