加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

objective-c – 什么可以阻止在动画期间遵守自动布局约束?

发布时间:2020-12-16 07:15:59 所属栏目:百科 来源:网络整理
导读:我正试图将视图捕捉到UITabBarController的tabBar(UITabBar),从不隐藏它(Apple在tvOS App Store的’Featured’选项卡中的方式). 我可以通过在直接包含在UITabBarController中的UIViewController中设置约束来使其工作.当隐藏和显示标签栏时,视图(在我的例子中
我正试图将视图捕捉到UITabBarController的tabBar(UITabBar),从不隐藏它(Apple在tvOS App Store的’Featured’选项卡中的方式).

我可以通过在直接包含在UITabBarController中的UIViewController中设置约束来使其工作.当隐藏和显示标签栏时,视图(在我的例子中,是一个UICollectionView)完全跟随动画.但是当我的UIViewController在UINavigationController中时,它也不起作用.它最终更新,但是当UITabBar动画(隐藏和显示)时,它不会更新.

以下是我使用NSLayoutConstraints设置约束的方法:
UIView * targetView = self.collectionView;

NSLayoutConstraint *constraint1 = [NSLayoutConstraint constraintWithItem:targetView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.tabBarController.tabBar attribute:NSLayoutAttributeBottom multiplier:1 constant:0];  
NSLayoutConstraint *constraint2 = [NSLayoutConstraint constraintWithItem:targetView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1 constant:0];  
NSLayoutConstraint *constraint3 = [NSLayoutConstraint constraintWithItem:targetView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeHeight multiplier:1 constant:0];  
NSLayoutConstraint *constraint4 = [NSLayoutConstraint constraintWithItem:targetView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeWidth multiplier:1 constant:0];  

[self.view.window addConstraint:constraint1];  
[self.view addConstraints:@[constraint2,constraint3,constraint4]];

这是我如何用Masonry设置相同的约束(两者都有相同的结果,但这更具可读性):

[self.containerView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.width.height.equalTo(self.view);
        make.top.equalTo(self.tabBarController.tabBar.mas_bottom);
    }];

这是一个展示我的问题的示例项目:
https://www.dropbox.com/s/bxbi0gyidxhu2bz/SampleMovingWithTabBar.zip?dl=1

这是一个错误还是预期的行为?

我正试图在另一个更复杂的应用程序中实现这个“视图不隐藏在标签栏下”的行为,我得到了同样奇怪的行为.虽然在这种情况下没有涉及UINavigationController.该视图直接位于UIViewController(它是UITabBarController的viewControllers数组的一部分)中.

什么可以阻止在动画期间遵守自动布局约束?

这是我的View Controller层次结构在我链接到的演示项目中的样子(UINavigationController中的View Controller是在显示/隐藏标签栏时没有动画的那个):

<UITabBarController 0x7fca42d10bb0>,state: appeared,view: <UILayoutContainerView 0x7fca42f848b0>
   | <FirstViewController 0x7fca42d11340>,state: disappeared,view: <UIView 0x7fca42f96510>
   | <UINavigationController 0x7fca43812000>,view: <UILayoutContainerView 0x7fca42d46200>
   |    | <FirstViewController 0x7fca42f347f0>,view: <UIView 0x7fca42f8bd90>

解决方法

每当您在此时使用CoreAnimation API进行动画时,布局约束在瞬态动画期间不会受到约束.

当您使用NSLayoutconstraint的属性(如常量用于动画)时,自动布局会在瞬态动画期间遵循约束.

CoreAnimations API包括UIView的基于块的动画.如果您有兴趣进一步阅读,那么这里是wwdc video

但是,看看你的代码,我认为这不是你的问题.您希望在UITabbar动画时尊重布局约束.您只需要在viewDidLayoutSubviews中设置约束而不是videDidAppear,您应该使用现有代码进行设置.

编辑—

我得到了一些关于这个问题的更多细节.首先,这不是苹果的错误. UITabBar只负责它的直接子视图控制器.它没有关于它的子结构的任何信息.你有责任将这一责任归为一类.

解决这个问题的方法是监听UIViewController的转换调用并相应地设置动画.

这是神奇的代码.将其添加到视图控制器.

-(void)didUpdateFocusInContext:(UIFocusUpdateContext *)context withAnimationCoordinator:(UIFocusAnimationCoordinator *)coordinator{

    NSString *prevFocusViewClassName = NSStringFromClass([context.previouslyFocusedView class]);
    NSString *nextFocusedView = NSStringFromClass([context.nextFocusedView class]);

    // The tabbar is going to disappear
    if ([prevFocusViewClassName isEqualToString:kUITabBarButtonClassName] &&
        ![nextFocusedView isEqualToString:kUITabBarButtonClassName]) {
        [self.view layoutIfNeeded];

        [coordinator addCoordinatedAnimations:^{
            [self.view layoutIfNeeded];
        } completion:nil];
        // The tabbar is going to appear
    } else if (![prevFocusViewClassName isEqualToString:kUITabBarButtonClassName] &&
               [nextFocusedView isEqualToString:kUITabBarButtonClassName]) {
        [self.view layoutIfNeeded];

        [coordinator addCoordinatedAnimations:^{
            [self.view layoutIfNeeded];
        } completion:nil];
    }

}

我已修复了预期输出https://www.dropbox.com/s/c8jdw367a3bnb42/SampleMovingWithTabBar-2.zip?dl=0的代码

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读