我在一个superview中创建了两个视图,然后在视图之间添加了约束:
_indicatorConstrainWidth = [NSLayoutConstraint constraintWithItem:self.view1 attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.view2 attribute:NSLayoutAttributeWidth multiplier:1.0f constant:0.0f];
[_indicatorConstrainWidth setPriority:UILayoutPriorityDefaultLow];
_indicatorConstrainHeight = [NSLayoutConstraint constraintWithItem:self.view1 attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self.view2 attribute:NSLayoutAttributeHeight multiplier:1.0f constant:0.0f];
[_indicatorConstrainHeight setPriority:UILayoutPriorityDefaultLow];
[self addConstraint:_indicatorConstrainWidth];
[self addConstraint:_indicatorConstrainHeight];
Run Code Online (Sandbox Code Playgroud)
现在我想用动画更改乘数属性,但我无法弄清楚如何更改多重属性.(我在头文件NSLayoutConstraint.h中的私有属性中找到了_coefficient,但它是私有的.)
如何更改多重属性?
我的解决方法是删除旧约束并添加具有不同值的新约束multipler.
我看到设置约束的不同示例.有些人将它们设置在viewDidLoad/中loadView(在添加子视图之后).其他人在方法中设置它们updateViewConstraints,它们被调用viewDidAppear.
当我尝试设置约束时updateViewContraints,可能会出现跳转到布局,例如在视图出现之前稍有延迟.另外,如果我使用这种方法,我应该首先清除现有的约束[self.view [removeConstraints:self.view.constraints]吗?
我有一个简单的(我认为)问题:我有一个UIImageView,我在故事板中设置了多个约束.
有时,我需要禁用约束,并frame手动设置它,但稍后,我将要重新启用这些约束并让视图返回到约束所决定的位置.
我以为我可以这样做:
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var constraint: NSLayoutConstraint!
func example() {
//to set its location and size manually
imageView.removeConstraint(constraint)
imageView.frame = CGRectMake(...)
//to cause it to return to its original position
imageView.addConstraint(constraint)
}
Run Code Online (Sandbox Code Playgroud)
但是,有了这个,我得到了错误2015-08-26 01:14:55.417 Constraints[18472:923024] The view hierarchy is not prepared for the constraint: <NSLayoutConstraint:0x7fbb72815f90 V:[_UILayoutGuide:0x7fbb72814c20]-(100)-[UIImageView:0x7fbb72814540]>.有谁知道为什么会出现这个错误?
view通过调用添加约束来self.view.addConstraint(...)消除错误,但仍然没有将图像视图带回到它应该的位置.
我注意到我甚至不必删除或停用约束,以便能够设置imageView没有问题的框架,只要我不打电话setTranslatesAutoresizingMaskIntoConstraints(true).
我已经看过这个问题,但答案似乎不必要地复杂,可能已经过时,甚至不适用.
我也看到了这个问题,但这并没有涵盖可以重新启用的约束 - 只能禁用它们.
试图设置active属性:
self.top.active = …Run Code Online (Sandbox Code Playgroud) 我的IBOutlet NSLayoutConstraint应用程序中有一个.非常简单:
@property (nonatomic, weak) IBOutlet NSLayoutConstraint* leftConstraint;
Run Code Online (Sandbox Code Playgroud)
在某些时候,我想停用此约束:
self.leftConstraint.active = NO;
Run Code Online (Sandbox Code Playgroud)
它发生在一个名为from的方法中cellForRowAtIndexPath:.并且约束在上面的行之后变为零.但是,如果我声明这个属性,strong那么它没关系,它不会变为零.任何人都能解释为什么会这样吗?
新的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");
}
Run Code Online (Sandbox Code Playgroud)
当应用程序启动时,按钮处于由其安装的约束定义的正确的居中位置.在按钮的操作方法中执行激活/取消激活后,按钮会正确移动到新位置,但是当我将视图旋转到横向时,它会移回到最初定义的位置(尽管日志仍然显示新激活的设置为活跃).当我旋转回肖像时,按钮保持在其初始位置(在屏幕中央),现在日志显示初始约束集合处于活动状态,而我激活的约束处于非活动状态.
问题是,这是一个错误,还是这些方法不应该以这种方式使用IB定义的约束?
我在情节提要中进行了约束,并连接到了视图控制器中的变量。在updateViewConstraints我将约束的active属性设置为false。
当我做
self.view.setNeedsUpdateConstraints()
self.view.layoutIfNeeded()
Run Code Online (Sandbox Code Playgroud)
在中viewDidLoad,layoutIfNeeded调用updateViewConstraints将约束设置为非活动状态,但是在此之后的某个位置,它将约束设置为活动状态,然后UIViewAlertForUnsatisfiableConstraints由于与其他约束发生冲突而出现了符号断点。当我.active在此断点处检查堆栈进一步的值时,它为true。
这仅在中发生viewDidLoad。在视图updateViewConstraints再次显示在屏幕上之前,将再次调用该视图,这一次将约束设置为非活动杆,并且布局正确。我仍然在控制台中收到冲突的约束错误。这是错误吗?
编辑:这是导致将约束设置为活动的堆栈跟踪:
