2

In my application I'm using a custom toolbar (just another UIView) at the top of the screen; it sits above a UITextView. I'm using auto layout.

Because I'm using this custom toolbar - I'm doing the following to make the UITextView look correct with respect to margins and scroll indicators:

// the height of the custom toolbar is 55
_textView.textContainerInset = UIEdgeInsetsMake(68, 5, 8, 5);
_textView.scrollIndicatorInsets = UIEdgeInsetsMake(54, 0, 0, 0);

When the keyboard is showing, I remove the toolbar. When the keyboard is dismissed, I show the toolbar. I animate the change of the toolbar's position, like this:

- (void)animateTopToolbarOn
{
    [self.view removeConstraints:_topToolbarOffScreenVerticalConstraints];
    [self.view addConstraints:_topToolbarOnScreenVerticalConstraints];

    [UIView animateWithDuration:0.6 animations:^{
        [self.view layoutIfNeeded];
    }];

    // this is the bit I need to get right:
    _textView.textContainerInset = UIEdgeInsetsMake(68, 5, 8, 5);
    _textView.scrollIndicatorInsets = UIEdgeInsetsMake(54, 0, 0, 0);
}

- (void)animateTopToolbarOff
{
    [self.view removeConstraints:_topToolbarOnScreenVerticalConstraints];
    [self.view addConstraints:_topToolbarOffScreenVerticalConstraints];

    [UIView animateWithDuration:0.6 animations:^{
        [self.view layoutIfNeeded];
    }];

    // this is the bit I need to get right:
    _textView.textContainerInset = UIEdgeInsetsMake(8, 5, 8, 5);
    _textView.scrollIndicatorInsets = UIEdgeInsetsMake(0, 0, 0, 0);
}

// For reference:
id topGuide = self.topLayoutGuide;
_topToolbarOffScreenVerticalConstraints = [NSLayoutConstraint
                                               constraintsWithVisualFormat:@"V:[_topToolbar][topGuide]"
                                               options:0
                                               metrics:nil
                                               views:views];

_topToolbarOnScreenVerticalConstraints = [NSLayoutConstraint
                                              constraintsWithVisualFormat:@"V:[topGuide][_topToolbar]"
                                              options:0
                                              metrics:nil
                                              views:views];

The animation of the toolbar's position / constraints, works fine, as you'd expect.

The problem is changing the values of the textContainerInset.

Note: I know that I could put the change in the completion block of the animation. Whilst it makes a difference to how it looks/feels, the problem remains, the change to the top margin occurs instantly, so it appears as a jump. It's jarring.

I could anchor the top constraint of the UITextView to the bottom constraint of the toolbar; then I wouldn't need to change either the textContainerInset values or the scrollIndicatorInsets. However, if I do that, the text won't scroll underneath the toolbar. I want to avoid this fallback position, if possible.

Any ideas?

I don't think the values of the textContainerInset can be animated? It doesn't match with the animatable UIView properties...

How can I achieve this setup using a plain UIView acting as a custom toolbar, which animates on and off the screen, to which the margins of the UITextView respond to?

Gavin Hope
  • 2,173
  • 24
  • 38
  • Any progress on this? – W Dyson Feb 24 '16 at 14:32
  • Not from me - I haven't made any changes to this. I think that, because the values of `textContainerInset` *cannot* be animated, I have to work within the restrictions that I've described above. – Gavin Hope Feb 24 '16 at 14:41
  • 1
    Running into this myself—the Apple docs you posted don't list `UIEdgeInset` as being animatable (which `textContainerInset` is); however, this link seems to suggest you can indeed animate `UIEdgeInset` changes: http://stackoverflow.com/q/30136973/482557. So, I'm wondering if it's something particular to `UITextView`. Tried mucking about with its `layoutManager` and `textContainer` but that's not working either, and I'm calling `layoutIfNeeded`. – Evan R Jul 19 '16 at 21:03

0 Answers0