是否可以在设备旋转时更改约束?如何实现?
一个简单的例子可能是两张图片,纵向时,一张堆叠在另一张上方,但横向时并排放置。
如果这不可能,我还能如何完成此布局?
我在代码中构建我的 View 和约束,而不是使用界面构建器。
最佳答案
编辑:使用 Size Classes 的新概念在 Xcode 6 中引入,您可以在 Interface Builder 中轻松地为特定大小类设置不同的约束。大多数设备(例如所有当前的 iPhone)在横向模式下都有一个紧凑垂直尺寸等级。
与确定设备的方向相比,这对于一般布局决策来说是一个更好的概念。
也就是说,如果您真的需要知道方向,UIDevice.currentDevice().orientation
是可行的方法。
原帖:
覆盖 UIViewController
的 updateViewConstraints
方法,为特定情况提供布局约束。这样,布局总是根据情况设置正确的方式。确保它们与 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/