iPhone:在显示/隐藏导航条时不能动画contentInset

时间:2021-07-27 19:38:22

In my app, I have a table view. When the user clicks a button, a UIView overlays part of that table view. It's essentially a partial modal. That table view is intentionally still scrollable while that modal is active. To allow the user to scroll to the bottom of the table view, I change the contentInset and scrollIndicatorInsets values to adjust for the smaller area above the modal. When the modal is taken away, I reset those inset values.

在我的app中,我有一个表格视图。当用户单击按钮时,UIView会覆盖该表视图的一部分。它本质上是部分模态。当模式是活动的时候,这个表视图仍然是可滚动的。为了让用户滚动到表视图的底部,我更改了contentInset和scrollIndicatorInsets值,以调整模式上方的较小区域。当模态被移除时,我重置那些inset值。

The problem is that when the user has scrolled to the bottom of the newly adjusted inset and then dismisses the modal, the table view jumps abruptly to a new scroll position because the inset is changed instantly. I would like to animate it so there is a transition, but the beginAnimation/commitAnimations methods aren't affecting it for some reason.

问题是,当用户滚动到新调整的inset的底部,然后取消模式时,表视图会突然跳转到一个新的滚动位置,因为inset会立即更改。我想让它动画化,这样就有了一个过渡,但是beginAnimation/ commitanimation方法不会因为某些原因影响它。

Edit: More info. I found the conflict. When presenting the modal, I also hide the navigation bar. The navigation bar natively animates the table view up and down as it shows and hides. When I stop animating the navigation bar, the inset animation works fine. Does anyone know what I can do to work around this conflict? Do I have to wait for the navigation bar animation to finish before adjusting the inset? If so, how to I hook onto that?

编辑:更多信息。我发现冲突。当呈现模式时,我也隐藏导航栏。导航栏在表视图显示和隐藏时自动地上下显示。当我停止动画导航栏时,inset动画效果很好。有人知道我能做些什么来解决这个矛盾吗?是否需要等待导航条动画完成后才能调整inset?如果是的话,我该怎么做呢?

Any help is greatly appreciated!

非常感谢您的帮助!

The relevant code from the table view controller is here:

表视图控制器的相关代码如下:

- (void)viewDidLoad {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(modalOpened) name:@"ModalStartedOpening" object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(modalDismissed) name:@"ModalStartedClosing" object:nil];
    [super viewDidLoad];
}

- (void)modalOpened {
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.5];
    [UIView setAnimationDelegate:self];
    self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 201, 0);
    self.tableView.scrollIndicatorInsets = UIEdgeInsetsMake(0, 0, 201, 0);
    [UIView commitAnimations];
}

- (void)modalDismissed {
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.5];
    [UIView setAnimationDelegate:self];
    self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
    self.tableView.scrollIndicatorInsets = UIEdgeInsetsMake(0, 0, 0, 0);
    [UIView commitAnimations];
}

1 个解决方案

#1


3  

I found a fix, but it isn't ideal. I wait to show the navigation bar after the inset is done animating. I'm still curious if concurrent animation is possible. Also I would like to know if it is possible to do the reverse. (To call the inset animation after the nav bar is done animating)

我找到了解决办法,但并不理想。在inset完成动画之后,我等待显示导航栏。我仍然想知道并发动画是否可能。我还想知道是否有可能反过来做。(在导航栏完成动画后调用内嵌动画)

Here is the code for my fix:

这是我修复的代码:

This is in the Table View Controller:

这在表视图控制器中:

- (void)modalDismissed {
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.3];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(modalDismissedEnded:finished:context:)];
    self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
    self.tableView.scrollIndicatorInsets = UIEdgeInsetsMake(0, 0, 0, 0);
    [UIView commitAnimations];
}

- (void)modalDismissedEnded:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
    [[NSNotificationCenter defaultCenter] postNotificationName:@"InsetFinishedAnimating" object:nil];
}

Then this in the Nav Controller:

在导航控制器中:

- (void)viewDidLoad {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(modalDismissed) name:@"InsetFinishedAnimating" object:nil];
    [super viewDidLoad];
}

- (void)modalDismissed {
    [self setNavigationBarHidden:NO animated:YES];
}

#1


3  

I found a fix, but it isn't ideal. I wait to show the navigation bar after the inset is done animating. I'm still curious if concurrent animation is possible. Also I would like to know if it is possible to do the reverse. (To call the inset animation after the nav bar is done animating)

我找到了解决办法,但并不理想。在inset完成动画之后,我等待显示导航栏。我仍然想知道并发动画是否可能。我还想知道是否有可能反过来做。(在导航栏完成动画后调用内嵌动画)

Here is the code for my fix:

这是我修复的代码:

This is in the Table View Controller:

这在表视图控制器中:

- (void)modalDismissed {
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.3];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(modalDismissedEnded:finished:context:)];
    self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
    self.tableView.scrollIndicatorInsets = UIEdgeInsetsMake(0, 0, 0, 0);
    [UIView commitAnimations];
}

- (void)modalDismissedEnded:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
    [[NSNotificationCenter defaultCenter] postNotificationName:@"InsetFinishedAnimating" object:nil];
}

Then this in the Nav Controller:

在导航控制器中:

- (void)viewDidLoad {
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(modalDismissed) name:@"InsetFinishedAnimating" object:nil];
    [super viewDidLoad];
}

- (void)modalDismissed {
    [self setNavigationBarHidden:NO animated:YES];
}