为什么弱 IBOutlet NSLayoutConstraint 在我使其处于非活动状态时变为 nil?

Why weak IBOutlet NSLayoutConstraint turns to nil when I make it inactive?

我的应用程序中有一个 IBOutlet NSLayoutConstraint。很简单:

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

有时我想停用此约束:

self.leftConstraint.active = NO;

它发生在从 cellForRowAtIndexPath: 调用的方法中。约束在上面一行之后变为 nil。但是,如果我将此 属性 声明为 strong 那么没关系,它不会变为 nil。谁能解释为什么会这样?

当您的出口是 weak 时,唯一的 strong 参考来自视图 constraints 属性。停用约束会将其从该数组中删除,因此不再有强引用。

一种可能的解决方法是更改​​约束优先级而不是使其处于非活动状态:

@property (nonatomic, weak) IBOutlet NSLayoutConstraint* leftConstraint;
(...)
self.leftConstraint.priority = 250;

那么,self.leftConstraint就不处理了。

编辑:

Xcode 不支持更改所需 (=1000) 约束的优先级,因此请确保在 1...999 之间的范围内切换。

首先将 IBOutlet 变量更改为可选变量。即:

来自 :

@IBOutlet weak var myConstraint : NSLayoutConstraint!

至:

@IBOutlet weak var myConstraint : NSLayoutConstraint?

现在,为了将来更容易从情节提要中 manage/change,添加一个新变量(例如 myConstraint_DefualtValue)并将其设置为myConstraintviewDidLoad

中的值
var myConstraint_DefualtValue = CGFloat(0)
override func viewDidLoad() {
    super.viewDidLoad()

    self.myConstraint_DefualtValue = self.myConstraint.constant

}

我想很明显为什么你需要在 viewDidLoad 中设置它而不是在其他地方

然后当你想停用它时:

self.myConstraint?.isActive = false

当你想重新激活它时(假设你有一个出口视图(myViewThatHasTheConstraint)并且约束是高度约束):

self.myConstraint = self.myViewThatHasTheConstraint.heightAnchor.constraint(equalToConstant: self.myConstraint_DefualtValue);
self.myConstraint?.isActive = true