新的NSLayoutConstraint
方法activateConstraints:
和deactivateConstraints:
似乎无法正常使用IB创建的约束(它们可以正确地用于代码创建的约束)。我用一个按钮创建了一个简单的测试应用程序,该按钮有两组约束。安装的一组具有centerX和centerY约束,而另一组(已卸载)具有顶部和左侧约束(常数10)。按钮方法切换这些约束集。这是代码,
@interface ViewController ()
@property (strong, nonatomic) IBOutletCollection(NSLayoutConstraint) NSArray *uninstalledConstraints;
@property (strong, nonatomic) IBOutletCollection(NSLayoutConstraint) NSArray *installedConstraints;
@end
@implementation ViewController
- (IBAction)switchconstraints:(UIButton *)sender {
[NSLayoutConstraint deactivateConstraints:self.installedConstraints];
[NSLayoutConstraint activateConstraints:self.uninstalledConstraints];
}
-(void)viewWillLayoutSubviews {
NSLog(@"installed: %@ uninstalled: %@", ((NSLayoutConstraint *)self.installedConstraints[0]).active ? @"Active" : @"Inactive", ((NSLayoutConstraint *)self.uninstalledConstraints[0]).active ? @"Active" : @"Inactive");
}
当应用程序启动时,按钮位于由其安装的约束定义的正确的居中位置。在按钮的操作方法中执行激活/取消激活后,按钮会正确移动到新位置,但是当我将视图旋转到横向时,它会移回到最初定义的位置(尽管日志仍会显示新激活的设置为活动状态)。当我旋转回肖像时,按钮保持在其初始位置(在屏幕中央),现在日志显示初始约束集合处于活动状态,而我激活的约束处于非活动状态。
问题是,这是一个错误,还是这些方法不应该以这种方式使用IB定义的约束?
答案 0 :(得分:30)
问题是你正在做一些与#34; uninstalled"无关的事情。故事板中的约束。他们在那里但不在那里。 "卸载"约束仅适用于大小类!如果要在旋转时让
所以,这样做。删除两个"卸载"约束,并删除uninstalledConstraints
出口。现在用以下代码替换整个视图控制器代码:
@property (strong, nonatomic) NSMutableArray *c1;
@property (strong, nonatomic) NSMutableArray *c2;
@property (strong, nonatomic) IBOutletCollection(NSLayoutConstraint) NSArray *installedConstraints;
@property (weak,nonatomic) IBOutlet UIButton *button;
@end
@implementation ViewController {
BOOL did;
}
- (void)viewDidLayoutSubviews {
NSLog(@"did");
if (!did) {
did = YES;
self.c1 = [self.installedConstraints mutableCopy];
self.c2 = [NSMutableArray new];
[self.c2 addObject:
[NSLayoutConstraint constraintWithItem:self.button attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTopMargin multiplier:1 constant:30]];
[self.c2 addObject:
[NSLayoutConstraint constraintWithItem:self.button attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeadingMargin multiplier:1 constant:30]];
}
}
- (IBAction)switchconstraints:(UIButton *)sender {
[NSLayoutConstraint deactivateConstraints:self.c1];
[NSLayoutConstraint activateConstraints:self.c2];
NSMutableArray* temp = self.c1;
self.c1 = self.c2;
self.c2 = temp;
}
现在反复按下按钮。如你所见,它在两个位置之间跳跃。现在旋转应用程序;按钮保持原样。
答案 1 :(得分:13)
我遇到了类似的情况。
我在界面构建器中创建了两组NSLayoutConstraints。每套一箱。安装了一套"安装了#34;另一个没有。
当我切换案例时,相应的布局约束集被激活而另一个被去除了。正如Qusteion中所描述的那样,前后旋转不能正常工作。
通过在界面构建器中安装两个集来解决这个问题。为了摆脱警告我第二组使用了较低优先级(999)。 这对我有用。
顺便说一下:Strang我使用了#34;已安装/未安装"另一个viewcontroller上的aproach,它的工作原理。
在不工作的情况下,viewcontroller嵌入在containerview中,也许这就是原因。
答案 2 :(得分:3)
你可以使用这个工作流程,尽管很明显这不是Apple目前支持的用例。
诀窍是不卸载约束(如@matt也指出的那样),但要在布局发生之前在viewDidLoad()
子类的UIViewController
中停用它们(而你的冲突约束会导致问题。)
我现在正在使用这种方法,它完美无缺。理想情况下,当然,我们有能力直观地创建约束组,并通过激活和停用它们(如中间有免费动画)将它们用作关键帧:)