横向和纵向模式的自动布局不同的约束

Posted

技术标签:

【中文标题】横向和纵向模式的自动布局不同的约束【英文标题】:Autolayout different constraints for landscape and portrait mode 【发布时间】:2016-02-21 22:49:05 【问题描述】:

我使用 Masonry 库来帮助以编程方式添加约束。 很好,但现在我面临的问题是,在用户将设备从横向旋转到纵向后,我需要卸载并添加新的约束。我尝试了相当“残酷”的解决方案,它确实改变了约束,但是,在几分之一秒内,我可以看到“旧”约束。用户旋转设备后是否有简单的方法来添加/删除约束?这就是我尝试过的(它有效,但正如我上面描述的那样,我可以在几分之一秒内看到“旧”帧):

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation

    if (UIInterfaceOrientationIsLandscape(self.interfaceOrientation))
        [bottomRight mas_updateConstraints:^(MASConstraintMaker *make) 

            NSLog(@"We are on landscape");
            make.top.equalTo(upperRight.mas_bottom).with.offset(20);
            make.left.equalTo(self.view.mas_centerX).with.offset(20);
            make.right.equalTo(bottomRightRight.mas_left).with.offset(-20);
            make.bottom.equalTo(self.view.mas_bottom).with.offset(-100);

            make.width.equalTo(bottomRightRight);

        ]; 
    else 
        NSLog(@"Swapped");
        [bottomRight mas_updateConstraints:^(MASConstraintMaker *make) 

            make.top.equalTo(upperRight.mas_bottom).with.offset(200);
            make.left.equalTo(self.view.mas_centerX).with.offset(200);
            make.right.equalTo(bottomRightRight.mas_left).with.offset(-200);
            make.bottom.equalTo(self.view.mas_bottom).with.offset(-200);

            make.width.equalTo(bottomRightRight);

        ];

    


【问题讨论】:

didRotateFromInterfaceOrientationios8 以来已被弃用。如果你没有支持 pre-ios8 的操作系统,你可以尝试使用- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection。可以激活和停用 NSLayoutConstraint,而不是添加和删除。我不知道 Masonry 是如何包装 NSLayoutConstraints 的,但是你可以在那里找到类比特征。 【参考方案1】:

在用户将设备从横向旋转到纵向后,我需要卸载并添加新的约束。我尝试了相当“残酷”的解决方案,它确实改变了约束,但是,在几分之一秒内我就可以看到“旧”约束。

但这就是问题所在:用户旋转设备之后,您正在更改约束。所以是造成你不喜欢的现象的人,即这发生在轮换结束后几分之一秒。

正确的解决方案是在用户旋转设备之前更改约束。如果你这样做了,约束的变化将神奇地动画以匹配旋转,并且变化将看起来绝对无缝。

例如,如果这是一个 iPhone 应用程序,您可以实现视图控制器的 willTransitionToTraitCollection... 并在那里进行约束更改,更改将神奇地与旋转匹配。

【讨论】:

不,这是 iPad 版本 :) 顺便说一下,这是 iOS 8 及更高版本的方法,请您提供 iOS 7 的解决方案吗?我们需要支持“旧”设备。 还是一样的答案。对于 iPad,请使用 viewWillTransitionToSize:withTransitionCoordinator:。对于 iOS 7,您会获得一组不同的“意志”事件。但这都是一样的。使用“将”,而不是“做了”。这就是我回答的重点。 我发现 -(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration 非常适合我的需要,但是看起来它已经被贬值了。 viewWillTransitionToSize:withTransitionCoordinator 也可以完美运行,但仅适用于 iOS > 8..

以上是关于横向和纵向模式的自动布局不同的约束的主要内容,如果未能解决你的问题,请参考以下文章

如何使用自动布局为纵向和横向方向配置不同的布局?

具有纵向和横向图像视图的自动布局

自动旋转时自动布局约束更新

如何针对不同的 iPhone 屏幕尺寸在纵向和横向中使用自动布局

使用自动布局和约束更改位置

纵向而不是横向的自动布局方向更改