activateConstraints: 和 deactivateConstraints: 在 IB 中创建的约束旋转后不持久 [英] activateConstraints: and deactivateConstraints: not persisting after rotation for constraints created in IB

查看:20
本文介绍了activateConstraints: 和 deactivateConstraints: 在 IB 中创建的约束旋转后不持久的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

新的 NSLayoutConstraint 方法 activateConstraints:deactivateConstraints: 似乎无法与 IB 创建的约束一起正常工作(它们确实可以正常工作对于代码创建的约束).我创建了一个简单的测试应用程序,其中一个按钮具有两组约束.已安装的一组具有 centerX 和 centerY 约束,而未安装的另一组具有顶部和左侧约束(常数 10).button 方法切换这些约束集.这是代码,

The new NSLayoutConstraint methods activateConstraints: and deactivateConstraints: don't appear to work correctly with IB-created constraints (they do work correctly for code-created constraints). I created a simple test app with one button that has two sets of constraints. One set, which is installed, has centerX and centerY constraints, and the other set, which is uninstalled, has top and left constraints (constant 10). The button method switches these constraints sets. Here is the code,

@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");

}

当应用启动时,按钮位于由其安装的约束定义的正确居中位置.在按钮的操作方法中执行激活/停用后,按钮会正确移动到其新位置,但是当我将视图旋转到横向时,它会移回其最初定义的位置(尽管日志仍将新激活的设置显示为活跃).当我旋转回纵向时,按钮保持在其初始位置(在屏幕中央),现在日志显示初始约束集为活动状态,而我激活的约束则为非活动状态.

When the app launches, the button is in the correct, centered position defined by its installed constraints. After I do the activation/inactivation in the button's action method, the button moves to its new position correctly, but when I rotate the view to landscape, it moves back to its initially defined position (though a log still shows the newly activated set as being active). When I rotate back to portrait, the button stays in its initial position (centered in the screen), and now the log shows that initial set of constraints as active, and the ones I activated, as inactive.

问题是,这是一个错误,还是这些方法不应该以这种方式与 IB 定义的约束一起工作?

The question is, is this a bug, or are these methods not supposed to work in this way with IB defined constraints?

推荐答案

问题是你做的事情与情节提要中的卸载"约束不一致.他们在那里,但不在那里.未安装"约束仅适用于大小类别!如果您要让 Xcode 在轮换时自动为您交换约束,则可以使用它们.Xcode 无法应付你正在做的事情.但是,如果您在代码中创建第二组约束,一切都会正常工作.

The problem is that you are doing something incoherent with "uninstalled" constraints in the storyboard. They are there but not there. "Uninstalled" constraints are for use only with size classes! You use them if you are going to let Xcode swap constraints for you automatically on rotation. Xcode can't cope with what you're doing. But if you create the second set of constraints in code, everything will work fine.

所以,这样做.删除两个卸载"约束,并删除 uninstalledConstraints 出口.现在用这个替换你的整个视图控制器代码:

So, do this. Delete the two "uninstalled" constraints, and delete the uninstalledConstraints outlet. Now replace your entire view controller code with this:

@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;
}

现在反复按下按钮.如您所见,它在两个位置之间跳转.现在旋转应用程序;按钮保持在原来的位置.

Now repeatedly press the button. As you see, it jumps between the two positions. Now rotate the app; the button stays where it is.

这篇关于activateConstraints: 和 deactivateConstraints: 在 IB 中创建的约束旋转后不持久的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆