可以阻止在动画过程中遵守“自动布局”约束的内容



我正试图将视图捕捉到UITabBarController的tabBar(UITabBar),以使其永远不会隐藏(就像苹果在tvOS应用商店的"特色"选项卡中所做的那样)。

我可以通过在直接包含在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

这是一个bug还是预期的行为?

我正试图在另一个更复杂的应用程序中实现这种"视图不隐藏在选项卡栏下"的行为,但我得到了同样奇怪的行为。尽管在本例中没有涉及UINavigationController。视图直接位于UIViewController中(UIViewController是UITabBarController的viewControllers数组的一部分)。

什么可以阻止在动画过程中遵守"自动布局"约束?

在我链接到的演示项目中,我的视图控制器层次结构是这样的(UINavigationController中的视图控制器是在显示/隐藏选项卡栏时不动画的):

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

当您使用CoreAnimation API的用于动画时,布局约束在瞬态动画期间不尊重约束。

如果将NSLayoutconstraint的属性(类似于constant)用于动画,则自动布局在瞬态动画过程中会遵守约束。

核心动画API包括UIView的基于块的动画。如果你有兴趣进一步阅读,那么这里是wwdc视频

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

编辑---

我得到了关于这个问题的更多细节。所以,首先,它不是苹果公司的一个bug。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

相关内容

  • 没有找到相关文章

最新更新