且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2022-12-05 12:39:46

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

Using the new concept of Size Classes introduced in Xcode 6, you can easily setup different constraints for specific size classes in Interface Builder. Most devices (e.g. all current iPhones) have a Compact vertical size class in landscape mode.

对于一般布局决策而言,这是一个比确定设备方向更好的概念.

This is a much better concept for general layout decisions than determining the device's orientation.

话虽如此,如果你真的需要知道方向,UIDevice.currentDevice().orientation 是你要走的路.

That being said, if you really need to know the orientation, UIDevice.currentDevice().orientation is the way to go.

原帖:

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

Override the updateViewConstraints method of UIViewController to provide layout constraints for specific situations. This way, the layout is always set up the correct way according to situation. Make sure they form a complete set of constraints with those created within the storyboard. You can use IB to set up your general constraints and mark those subject to change to be removed at runtime.

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

I use the following implementation to present a different set of constraints for each orientation:

-(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: 以动画化方向变化的约束更新:

Now, all you need to do is trigger a constraint update whenever the situation changes. Override willAnimateRotationToInterfaceOrientation:duration: to animate the constraint update on orientation change:

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

    [self.view setNeedsUpdateConstraints];

}