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

时间:2014-08-29 18:04:11

标签: ios uitextfield autolayout

我将UITextField子类化为在左侧添加标签。我使用autolayout来布局标签。但是,我一直在崩溃:

以下是我的布局代码:

- (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];

}

当我不对文本字段进行任何调整时,这样可以正常工作。

但是,如果我尝试设置占位符文本,则会出现此异常:

  

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

但是,我没有覆盖-layoutSubviews。

有没有人遇到过这个?我做错了什么?

谢谢!

3 个答案:

答案 0 :(得分:8)

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

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]方法。

答案 1 :(得分:4)

此问题出现在 iOS< 8

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

[self layoutIfNeeded];

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

答案 2 :(得分:-2)

我有同样的问题。这可能是由错误的约束引起的,可能是由Storyboard中的一些设置引起的。尝试删除其中的一些,看看它是否能够找出错误的