UITextField中的自动布局:执行-layoutSubviews后仍需要自动布局



我正在对UITextField进行子类化,以便在左侧添加一个标签。我正在使用自动布局来布局标签。然而,我不断收到这个崩溃:

以下是我的布局代码:

- (void)updateConstraints {
self.segmentLabel.translatesAutoresizingMaskIntoConstraints = NO;
NSLayoutConstraint *constraint;
constraint = [NSLayoutConstraint constraintWithItem:self.segmentLabel attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0.0f];
[self addConstraint:constraint];
constraint = [NSLayoutConstraint constraintWithItem:self.segmentLabel attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeading multiplier:1.0 constant:0.0f];
[self addConstraint:constraint];
constraint = [NSLayoutConstraint constraintWithItem:self.segmentLabel attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0f];
[self addConstraint:constraint];
constraint = [NSLayoutConstraint constraintWithItem:self.segmentLabel attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:self.segmentWidth];
[self addConstraint:constraint];
[super updateConstraints];

}

当我不对文本字段进行任何调整时,这很好。

然而,如果我尝试设置占位符文本,我会得到以下异常:

由于未捕获的异常"NSInternalConsistencyException"而终止应用程序,原因:"执行-layoutSubviews后仍需要自动布局。"。DDSegmentedTextField对-layoutSubviews的实现需要调用super

但是,我并没有覆盖-layoutSubviews。

有人遇到过这种情况吗?我做错了什么?

谢谢!

所以几天前我也遇到了同样的错误。事实证明,我试图在UITextfield子类中布局子视图,设置它们的属性,移动它们,等等,但从未明确告诉视图布局自己(即调用[self layoutIfNeeded])。

iOS 8似乎会强制视图布局其所有子视图,然后在其上配置约束。iOS 7不会,如果您使用自动布局,则需要明确告诉视图在更改时重新绘制其子视图。

在我的例子中,我已经将UITextField子类化,并在边上添加了一个标签。我通过向UITextfield添加约束来配置标签的框架。我可以在课堂上调用的公共方法之一是

- (void)setLabelText:(NSString *)newText{
    self.sideLabel.text = newText;
}

当一个包含我的子类文本字段的视图控制器出现时,这导致我的应用程序崩溃。通过添加layoutIfNeeded,现在iOS7和iOS8中的一切都可以正常工作。

- (void)setLabelText:(NSString *)newText{
    self.sideLabel.text = newText;
    [self layoutIfNeeded];
}

每当您更改子类中视图的一部分时,都需要调用此函数。这包括添加子视图时的设置、更改视图属性时的设置,以及任何实际的设置。在更改视图的函数返回之前,请对视图调用layoutIfNeeded。这似乎适用于一些标准的UI控件,包括UITextfield、UITableView和UICollectionView,尽管我相信还有其他控件。我希望这一点足够清楚,并有助于解决你的问题。

你得到的错误并不是很有用,甚至不适用于我的情况。尽管我收到了完全相同的错误,但我的任何视图都没有实现layoutSubviews,因此都使用[super layoutSubviews]方法。

此问题出现在iOS<8

在创建UIView子类和添加视图时,我们可以指示控件首先构造和自动布局子视图。当UI需要更新时使用以下语句:

[self layoutIfNeeded];

iOS 8+正在内部自行处理这个问题。

我遇到了同样的问题。这可能是由错误的约束引起的,可能是由情节提要中的某些设置引起的。试着删除其中的一些,看看它是否能找出错误的

最新更新