How to fix titleView being masked to navigation ba

2019-05-26 21:27发布

In my view controller I am setting the titleView to a UIView which contains a UIImageView which is made into a circle using setCornerRadius on its layer.

The top half of the circle is positioned over the navbar, and the bottom half over the view, like this:

A

Now when I push this view controller, as it animates in, the bottom half of the circle is cut off until the animation completes. Only the part that's in the navbar is shown, something like this:

B

As soon as the push animation ends, the full circle is shown. Is there any way I can stop the navigation bar from masking/cutting off the titleView while the animation takes place, so that the full circle is shown during the animation?

1条回答
神经病院院长
2楼-- · 2019-05-26 22:00

I'm not sure you should want to do this.

Anyway: add the circle to your UIWindow (on top of your UINavigationController). I suppose you want to position the circle in the center of your screen (horizontally). You can use a transition coordinator (iOS 7.0 +) to animate the circle alongside the transition of your view controller (push or pop). Note that this only works for animated transitions (i.e. when animated is set). Therefore, we need to set the new frame manually when animated isn't set.

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    /* Add the circle to the key window (instead of the navigation bar). */
    UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
    [keyWindow addSubview:_circle];

    /* Screen width: the initial position of the circle = center + screen width. */
    CGFloat width = self.view.bounds.size.width;

    CGRect destination = _circle.frame;
    destination.origin.x = 110.f;

    /* The transition coordinator is only available for animated transitions. */
    if (animated) {
        CGRect frame = destination;
        frame.origin.x += width;
        _circle.frame = frame;

        void (^animation)(id context) = ^(id context) {
            _circle.frame = destination;
        };

        [self.transitionCoordinator animateAlongsideTransitionInView:_circle
                                                           animation:animation
                                                          completion:animation];
    }else {
        _circle.frame = destination;
    }
}

Replace 110.f with your position (110.f = ((320.f - 100.f) / 2.f)).

Now, you need to use a transition coordinator to animate the pop as well.

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];

    /* Screen width: the initial position of the circle = center + screen width. */
    CGFloat width = self.view.bounds.size.width;

    CGRect destination = _circle.frame;
    destination.origin.x = 110.f + width;

    /* The transition coordinator is only available for animated transitions. */
    if (animated) {
        CGRect frame = destination;
        frame.origin.x = 110.f;
        _circle.frame = frame;

        void (^animation)(id context) = ^(id context) {
            _circle.frame = destination;
        };

        [self.transitionCoordinator animateAlongsideTransitionInView:_circle
                                                           animation:animation
                                                          completion:animation];
    }else {
        _circle.frame = destination;
    }
}

And finally, remove the circle from your key window as soon as your view controller has disappeared (note that this does not necessarily mean your view controller is popped, and you can always readd the circle view to the key window again in viewWillAppear:).

- (void)viewDidDisappear:(BOOL)animated {
    [super viewDidDisappear:animated];

    /* Remove the circle from your key window. */
    [_circle removeFromSuperview];
}
查看更多
登录 后发表回答