iOS中UITextField的自动布局问题

4

我在storyboard中创建了一个UITextField,并添加了它的约束。我想要在UITextField左侧添加搜索图标。添加搜索图标的代码如下:

self.searchTextField.leftView = searchIconImage;
    self.searchTextField.leftViewMode = UITextFieldViewModeAlways;
    [self.searchTextField addTarget:self
                  action:@selector(textFieldDidChange:)
        forControlEvents:UIControlEventEditingChanged];

我的应用在iOS8上运行良好,在iOS7上崩溃。错误如下:

-[UITextField layoutSublayersOfLayer:]中的断言失败,/SourceCache/UIKit/UIKit-2935.138/UIView.m:8794 2014-11-05 12:54:33.377 WattUp[1722:60b] 终止应用程序,原因:未捕获的异常 'NSInternalInconsistencyException',原因:执行-layoutSubviews后仍需要自动布局。UITextField的-layoutSubviews实现需要调用super。


2
看一下错误的最后一条语句。UITextField 的 -layoutSubviews 实现需要调用 super。你继承了 UITextField 吗? - Khaled Barazi
@Spectravideo328 是的,我子类化了UITextField。我的应用在iOS8上运行良好。问题只出现在iOS7上。 - Rakesh
你是否按照注释所说调用了super? - Khaled Barazi
@Spectravideo328 非常感谢您的回复。我通过在我的UITextField上调用loadSubViews来解决了这个问题。它在iOS8和iOS7上都可以工作。 - Rakesh
2个回答

8

我前几天也遇到了同样的错误。后来我发现,我试图在我的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上一切都正常,但在iOS 7上却不行。 - Endama
谢谢!在我的情况下,我编写了一个自定义范围滑块,并且遇到了与原始问题中列出的相同错误。我已经重写了layoutSubViews来处理调整大小期间滑块拇指的重新定位。在我的情况下,错误消息部分正确,因为我忘记在layoutSubviews中调用超类。除此之外,我需要您的解决方案,即在重新定位拇指的调用之后添加[self layoutIfNeeded] - Jason McClinsey

0
我通过子类化 UITextField 并重新实现了两个方法来解决这个问题:
- (void)setText:(NSString *)text
{
    [super setText:text];
    [self layoutIfNeeded];
}

- (void)layoutSubviews
{
    [super layoutSubviews];
}

真的很烦人的事情。苹果经常让程序员哭泣。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接