4
votes

I created UITextField in storyboard. And added its constraints also. I want search icon on left side of UITextField. The code for adding search icon is as follows:

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

My application is working fine on iOS8 and its crashing on iOS7. The error is as follows:

Assertion failure in -[UITextField layoutSublayersOfLayer:], /SourceCache/UIKit/UIKit-2935.138/UIView.m:8794 2014-11-05 12:54:33.377 WattUp[1722:60b] Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Auto Layout still required after executing -layoutSubviews. UITextField's implementation of -layoutSubviews needs to call super.'

2
See last statement in error. UITextField's implementation of -layoutSubviews needs to call super.' Did you subclass UITextfield?Khaled Barazi
@Spectravideo328 yes I subclass UITextField. My app is working fine on iOS8. The issue is only on iOS7.Rakesh
Are you calling super as the comment says?Khaled Barazi
@Spectravideo328 thank you very much for your reply. I managed to resolve this issue bay calling loadSubViews on my UITextField. It's working on both iOS8 and iOS7.Rakesh

2 Answers

8
votes

So I ran into this same error a few days ago as well. It turns out I was trying to layout subviews inside my UITextfield subclass, setting properties on them, moving them, etc, but was never explicitly telling the view to lay itself out (i.e. calling [self layoutIfNeeded]).

iOS 8 seems to force to a view to layout all its subviews, and then configures constraints on it. iOS 7 won't, and needs you to explicitly tell views to redraw their subviews when you change if you're using autolayout.

In my case, I had subclassed UITextField and added a label to the side. I configured the frame of the label by adding constraints to the UITextfield. One of the public methods I could call on my class was

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

This caused my application to crash when a view controller appeared containing my subclassed textfield. By add layoutIfNeeded everything works fine in iOS7 and iOS8.

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

This needs to be called every time you change a part of the view in your subclass. This includes the setup when you add subviews, when you change view properties, anything really. Before the function that's changing your view returns, call layoutIfNeeded on your view. This seems to apply for a few standard UI controls including UITextfield, UITableView and UICollectionView, though I'm sure there are others. I hope this was clear enough and helped solve your problem.

The error you're getting isn't super useful, and didn't even apply in my case. Though I was receiving the exact same error, none of my views implementing layoutSubviews, and thus were all using the [super layoutSubviews] method.

0
votes

I solved this by subclassing UITextField and reimplementing 2 methods:

- (void)setText:(NSString *)text
{
    [super setText:text];
    [self layoutIfNeeded];
}

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

really annoing thing. Apple makes programmers cry so often