ObjC,在以编程方式添加/删除后恢复为界面构建器自动布局约束?

Posted

技术标签:

【中文标题】ObjC,在以编程方式添加/删除后恢复为界面构建器自动布局约束?【英文标题】:ObjC, revert to interface builder autolayout constraints, after adding / removing programmatically? 【发布时间】:2015-05-25 07:44:01 【问题描述】:

我有我的应用程序的免费版本,我删除 + 添加自动布局约束(以隐藏高级功能),但是如果用户购买我的应用程序,我想恢复到界面生成器设置的约束。

我希望有一种方法可以实现这一点,但我到目前为止还没有找到它?

这就是我所拥有的

if (!purchased) 

[self.tblOtherAccounts addConstraints:[NSLayoutConstraint
   constraintsWithVisualFormat:@"V:[tblOtherAccounts(==0)]"
   options:0
   metrics:nil
   views:NSDictionaryOfVariableBindings(tblOtherAccounts)]];


NSDictionary *views = @ @"tblOtherAccounts" : self.tblOtherAccounts, 
   @"butBackAllAc" : butBackAllAc  ;

[self.view removeConstraints:[NSLayoutConstraint 
   constraintsWithVisualFormat:@"V:[tblOtherAccounts]-(12)-[butBackAllAc]"
   options:0
   metrics:nil
   views:views]];

[self.view addConstraints:[NSLayoutConstraint 
   constraintsWithVisualFormat:@"V:[tblOtherAccounts]-(0)-[butBackAllAc]"
   options:0
   metrics:nil
   views:views]];

【问题讨论】:

【参考方案1】:

添加一个 IBOutlet 以将您的约束存储在您的 ViewController 中:

@property (weak, nonatomic) IBOutlet NSLayoutConstraint *myConstraint;

然后更新它的值:

_myConstraint.constant = 100.0f;
[_myView setNeedsUpdateConstraints];
[_myView layoutIfNeeded];

关于您对将关系设置为“等于”的评论,我认为您无法做到这一点。

您可以做的一件事是使用情节提要生成的约束作为占位符:

NSLayoutConstraint *newConstraint = [NSLayoutConstraint constraintWithItem:_myConstraint.firstItem
                                                                 attribute:_myConstraint.firstAttribute
                                                                 relatedBy:_myConstraint.relation
                                                                    toItem:_myConstraint.secondItem
                                                                 attribute:_myConstraint.secondAttribute
                                                                multiplier:_myConstraint.multiplier
                                                                  constant:_myConstraint.constant];

[_myConstraint.secondItem removeConstraint:_myConstraint];
[constraint.secondItem addConstraint:newConstraint];

当然,上面的代码会创建一个与您的约束完全相同的副本,但您可以对其进行编辑以更改适当的值以满足您的需求。

【讨论】:

我的错,你应该在受影响的视图上调用最后两个方法,我编辑了我的答案。 我在答案中添加了一些代码,我不确定是否可以通过插座将关系更改为等于 @Jules :在您向问题添加代码之前,我添加了一些有关约束编辑的代码。如果需要,我会检查并增加我的答案的准确性。 再次感谢,所以将加载时间约束保持在变量中并在他们购买后使用它可能会更容易,否则我将松开我将覆盖的高度零。 这让我走上了正轨,这也有帮助blog.sigmapoint.pl/restoring-nslayoutconstraints-after-a-change【参考方案2】:

我认为,你不能完全做到这一点。 您需要在代码中执行该逻辑。 IE。应用一些约束,然后在用户操作时应用另一组约束。

示例: 您有 2 个约束:

@property ... topConstraint;
@property ... leadingConstraint;

一开始你给它们赋值:

topConstraint.constant = 100;
leadingConstraint.constant = 100;

在一些用户操作之后,修改它们:

topConstraint.constant = 150;
leadingConstraint.constant = 150;

【讨论】:

感谢您的输入,嗯,我想知道是否可以事先将它们分配给一个变量,然后再分配回来,仍在寻找.. 是的,这是一个选项。 没有办法。您只需将约束存储在属性中,然后根据需要进行修改。

以上是关于ObjC,在以编程方式添加/删除后恢复为界面构建器自动布局约束?的主要内容,如果未能解决你的问题,请参考以下文章

graphql-java:如何在以编程方式生成 graphql 模式时添加自定义标量类型?

在 UIScrollView 中滚动后,视图重置为原始界面构建器高度和约束

UIPickerView 委托在以编程方式创建时从不调用

Swift/iOS:UIPicker 显示在以编程方式更改数据源后点击后才会刷新

在需要时以编程方式添加滚动

以编程方式创建的 UIViewController 加载界面构建器 view.xib 文件