如何在运行时更改约束优先级

Le'*_*dok 65 constraints objective-c ios autolayout

我有一个动态高度的视图,我试图在运行时更改此视图高度优先级.

这是我的代码部分;

if (index == 0) {

    surveyViewHeightConstraint.constant = 0;
    surveyViewHeightConstraint.priority = 1000;

} else if (index == 1) {

    surveyViewHeightConstraint.constant = 163;
    surveyViewHeightConstraint.priority = 500;

}
Run Code Online (Sandbox Code Playgroud)

我正在用按钮动作改变索引.当我运行此代码时,我收到此错误:

*** Assertion failure in -[NSLayoutConstraint setPriority:], /SourceCache/Foundation/Foundation-1141.1/Layout.subproj/NSLayoutConstraint.m:174
Run Code Online (Sandbox Code Playgroud)

这里的错误是什么?

Cyr*_*lle 146

NSLayoutConstraint课程参考中所述:

优先权不得从非要求变为必需,或从必要变为非要求.如果将NSLayoutPriorityRequiredOS X或UILayoutPriorityRequirediOS中的优先级更改为较低优先级,或者在将约束添加到视图后将较低优先级更改为所需优先级,则将引发异常.即使在视图上安装了约束,也允许从一个可选优先级更改为另一个可选优先级.

使用优先级999而不是1000.从技术上讲,它不是绝对必需的,但它将优先于其他任何东西.

  • 似乎这个限制在 iOS 13 中已被删除。我尝试将约束从“required”更改为“defaultLow”并且它起作用了。相同的代码曾经在 iOS 12 上崩溃。 (10认同)
  • 谢谢你的好答案,但如果我使用999而不是1000,我无法通过为高度约束分配0来隐藏我的视图. (4认同)
  • 真的吗?iOS开发中是否有正常工作?许多事情必须手动完成和/或必须实施大量的解决方法代码导致系统错误或不支持.很抱歉没有建设性的评论. (4认同)

Vip*_*pin 36

我想对Cyrille的回答做一点补充.

如果要在代码中创建约束,请确保在激活之前设置其优先级.例如:

surveyViewHeightConstraint = [NSLayoutConstraint constraintWithItem:self
                                               attribute:NSLayoutAttributeHeight
                                               relatedBy:NSLayoutRelationEqual
                                                  toItem:self.superview
                                               attribute:NSLayoutAttributeHeight
                                              multiplier:1
                                                constant:0];
surveyViewHeightConstraint.active = YES;
surveyViewHeightConstraint.priority = 999;
Run Code Online (Sandbox Code Playgroud)

这将导致运行时异常.

不支持将优先级从必需变为不安装约束(反之亦然).

正确的顺序是:

surveyViewHeightConstraint.priority = 999;
surveyViewHeightConstraint.active = YES;
Run Code Online (Sandbox Code Playgroud)


小智 6

我们总是处理这个问题的方法是不改变约束常数,只改变优先级.例如,在您的情况下有两个高度限制.

 heightConstraintOne (who's height is set in the storyboard at 150, and priority set at 750)
 heightConstraintTwo (who's height is set in the storyboard at 0, and priority set at 250)
Run Code Online (Sandbox Code Playgroud)

如果你想隐藏视图,你:

heightConstraintTwo.priority = 999;
Run Code Online (Sandbox Code Playgroud)

同样,如果你想显示视图:

heightConstraintTwo.priority = 250;
Run Code Online (Sandbox Code Playgroud)

  • 很酷,得到它:使用999而不是1000.谢谢 (2认同)

Ale*_*lex 6

迅捷版:

myContraint.priority = UILayoutPriority(999.0)
Run Code Online (Sandbox Code Playgroud)


小智 5

我希望这个场景对某人有所帮助:我有两个约束,它们彼此相反,我的意思是它们不能同时满足,在界面构建器中,其中一个优先级为 1000,另一个优先级低于 1000。当我在代码中更改它们时,出现以下错误:

由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“不支持将优先级从必需的更改为未安装的约束(或反之亦然)。您通过了优先级 250,现有的优先级为 1000。

然后我只是用 .defaultHigh 和 .defaultLow 值在 viewDidLoad 函数中初始化它们,这解决了我的问题。