ios - 我可以使用自动布局为横向和纵向方向提供不同的约束吗?

标签 ios cocoa-touch uiview uiviewcontroller autolayout

是否可以在设备旋转时更改约束?如何实现?

一个简单的例子可能是两张图片,纵向时,一张堆叠在另一张上方,但横向时并排放置。

如果这不可能,我还能如何完成此布局?

我在代码中构建我的 View 和约束,而不是使用界面构建器。

最佳答案

编辑:使用 Size Classes 的新概念在 Xcode 6 中引入,您可以在 Interface Builder 中轻松地为特定大小类设置不同的约束。大多数设备(例如所有当前的 iPhone)在横向模式下都有一个紧凑垂直尺寸等级。

与确定设备的方向相比,这对于一般布局决策来说是一个更好的概念。

也就是说,如果您真的需要知道方向,UIDevice.currentDevice().orientation 是可行的方法。


原帖:

覆盖 UIViewControllerupdateViewConstraints 方法,为特定情况提供布局约束。这样,布局总是根据情况设置正确的方式。确保它们与 Storyboard 中创建的约束形成一套完整的约束。您可以使用 IB 来设置您的一般约束,并将那些受更改影响的标记标记为在运行时删除。

我使用以下实现为每个方向提供一组不同的约束:

-(void)updateViewConstraints {
    [super updateViewConstraints];

    // constraints for portrait orientation
    // use a property to change a constraint's constant and/or create constraints programmatically, e.g.:
    if (!self.layoutConstraintsPortrait) {
        UIView *image1 = self.image1;
        UIView *image2 = self.image2;
        self.layoutConstraintsPortrait = [[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[image1]-[image2]-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(image1, image2)] mutableCopy];
        [self.layoutConstraintsPortrait addObject:[NSLayoutConstraint constraintWithItem:image1 attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem: image1.superview attribute:NSLayoutAttributeCenterY multiplier:1 constant:0]];
        [self.layoutConstraintsPortrait addObject:[NSLayoutConstraint constraintWithItem:image2 attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:image2.superview attribute:NSLayoutAttributeCenterY multiplier:1 constant:0]];
    }

    // constraints for landscape orientation
    // make sure they don't conflict with and complement the existing constraints
    if (!self.layoutConstraintsLandscape) {
        UIView *image1 = self.image1;
        UIView *image2 = self.image2;
        self.layoutConstraintsLandscape = [[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[image1]-[image2]-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(image1, image2)] mutableCopy];
        [self.layoutConstraintsLandscape addObject:[NSLayoutConstraint constraintWithItem:image1 attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:image1.superview attribute:NSLayoutAttributeCenterY multiplier:1 constant:0]];
        [self.layoutConstraintsLandscape addObject:[NSLayoutConstraint constraintWithItem:image2 attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem: image2.superview attribute:NSLayoutAttributeCenterY multiplier:1 constant:0]];
    }

    BOOL isPortrait = UIInterfaceOrientationIsPortrait(self.interfaceOrientation);
    [self.view removeConstraints:isPortrait ? self.layoutConstraintsLandscape : self.layoutConstraintsPortrait];
    [self.view addConstraints:isPortrait ? self.layoutConstraintsPortrait : self.layoutConstraintsLandscape];        
}

现在,您需要做的就是在情况发生变化时触发约束更新。覆盖 willAnimateRotationToInterfaceOrientation:duration: 以在方向更改时为约束更新设置动画:

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];

    [self.view setNeedsUpdateConstraints];

}

关于ios - 我可以使用自动布局为横向和纵向方向提供不同的约束吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17772922/

相关文章:

ios - UITableView ContentInsets 水平滚动内容

ios - UIView 父引用

iphone - 在 iOS 上,有没有办法将方法 addTarget 添加到 UIImageView?

ios - UITableView 中缺少 UINavigationBar

ios - Alamofire 5 委托(delegate)中缺少 sessionDidReceiveChallenge

ios - UINavigationController - 检测何时导航回 Root View Controller

objective-c - 在类方法中访问同一类实例的 ivar

ios - UIDocumentInteractionController 防止 'Open in' 工作表中的 Airdrop

ios - 在iphone sdk中改变图像的颜色

ios - 尝试从下向上而不是自上而下为 UIView 高度设置动画