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

Posted

技术标签:

【中文标题】如何使用自动布局为纵向和横向方向配置不同的布局?【英文标题】:How to configure different layouts for Portrait and Landscape Orientations using Auto Layout? 【发布时间】:2013-12-19 14:01:56 【问题描述】:

我有一个像附图中一样的视图

现在我正在添加约束,这样当方向更改为横向时,视图中的 UITextview 必须位于屏幕的右侧。在 UItextview 上,我添加了以下约束,

    尾随空格到:Superview 底部空间到:Superview

这些约束虽然显示了一些关于歧义的警告,但为我完成了这项工作。下面是横屏模式的截图。

我的问题是,虽然 UItextview 移到了右侧,但当它处于横向模式时,我希望从 superview 顶部增加一些宽度。换句话说,我希望 UITextview 从现在处于横向模式的位置向下移动一点。我正在考虑如何在 IB 中使用自动布局来做到这一点,但我不知道该怎么做。

请给点建议。

【问题讨论】:

【参考方案1】:

您可以通过多种方式使用约束来执行此操作,但仅使用您在 IB 中创建的约束无法自动执行此操作。通过在方法constraintWithItem:attribute:relatedBy:toItem:attribute:multiplier:constant: 中同时使用乘数和常数值,您可以有一个约束来评估纵向和横向的不同距离。计算这些值的用途是很痛苦的,所以我在 NSLayoutConstraint 上写了一个类别来做到这一点。其中一种方法的示例如下:

+(NSLayoutConstraint *)topConstraintForView:(UIView *)subview viewAttribute:(NSLayoutAttribute) att superview:(UIView *)superview portraitValue:(CGFloat)pValue landscapeValue:(CGFloat)lValue 
    CGFloat multiplier = (pValue - lValue)/(superview.bounds.size.height - superview.bounds.size.width);
    CGFloat constant = pValue - (superview.bounds.size.height * multiplier);
    NSLayoutConstraint *con = [NSLayoutConstraint constraintWithItem:subview attribute:att relatedBy:0 toItem:superview attribute:NSLayoutAttributeBottom multiplier:multiplier constant:constant];
     NSLog(@"top coeffs: %f   %f",multiplier,constant);
    return con;

您使用这些的方式是在情节提要中添加起始肖像约束,但在约束的属性检查器中选中“占位符 - 构建时删除”框,然后在 viewDidLoad 中替换它,像这样:

- (void)viewDidLoad 
    [super viewDidLoad];
    [self.view addConstraint:[NSLayoutConstraint topConstraintForView:self.textView viewAttribute:NSLayoutAttributeTop superview:self.view portraitValue:225 landscapeValue:50]];

这将根据设备的旋转自动调整文本视图的位置,无需任何进一步的代码。您可能必须更改文本字段的宽度以使所有内容都适合——我将它们和“获取”标签包含在视图中,以便更轻松地将它们定位为一个组。该视图和文本视图具有高度和宽度约束,以及视图的顶部和左侧,以及文本视图的顶部和右侧。该类别也有调整其他约束的方法,可以在http://jmp.sh/b/S4exMJBWftlCeO5GybNO找到。

另一种方法是使 IBOutlets 适应您在 IB 中所做的约束,并在其中一个旋转回调方法中调整它们(常量值),或者删除一些并重新制作其他的。

【讨论】:

假设用户在安装了 category 方法返回的约束后旋转了设备。必须在旋转期间移除并重新安装约束。换句话说,必须再次调用类别方法。对吗? @bilobatum,不,这就是这个方法的重点,你不必这样做。乘数和常数值的组合根据方向评估为不同的长度。 如果我使用类似 [self.view addConstraint:[NSLayoutConstraint bottomConstraintForView:self.firstImageView viewAttribute:NSLayoutAttributeBottom superview:self.view portraitValue:10 LandscapeValue:20]] 的东西不能正常工作[self.view addConstraint:[NSLayoutConstraint bottomConstraintForView:self.thirdImageView viewAttribute:NSLayoutAttributeBottom superview:self.view PortraitValue:10 LandscapeValue:170]];并且相应地设置了左侧约束

以上是关于如何使用自动布局为纵向和横向方向配置不同的布局?的主要内容,如果未能解决你的问题,请参考以下文章

如何在颤动中显示横向和纵向的不同布局

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

Android小部件不同的纵向和横向方向

iOS 自动布局:如何在 Xcode 故事板中为 iPad 横向和 iPad 纵向设计不同的布局?

播放 VideoView 的不同纵向和横向布局

处理略有不同的纵向和横向布局的单个 Android 布局 xml 文件?