I have custom UILabel which works fine on iOS6 and iOS7. But on iOS8 this label's (void)layoutSubviews method never get called. I create this label with initWithFrame, so this method should be called - and it's called on another iOS versions. What happens with autoLayout system in iOS8?
-
The issue is even worse, as also when using autolayout for the subview, it does not get layoutet. – fabb Sep 23 '14 at 09:22
-
I created an example project showing the issue. Run on iOS 7 and 8 to see the difference. https://github.com/fabb/LabelTest – fabb Sep 26 '14 at 13:59
-
I am also facing same issue. Did you get any answer on this? – ABC1 Sep 26 '14 at 21:14
-
Seems issue has been fixed in iOS 8.1 beta version. – ABC1 Sep 30 '14 at 02:46
3 Answers
I just want to add this answer because the question title may lead a lot of ppl here with similar issues (like me).
With iOS 8 to 8.0.2 LayoutSubviews
calls are unreliable. They may not be called ever or (in my case) are called in a loop.
Even though you should not do it, it was pretty safe to alloc stuff in LayoutSubviews, but with this buggy (?!) behaviour it can cause hard-to-trace bugs.
I don't know if 8.1 fixes all the issues but it will be some time until customer devices will run 8.1 and they do run 8.0.2 NOW

- 2,209
- 1
- 16
- 31
-
Am facing the same issue here. "LayoutSubviews" is called in a loop In order to cover users using iOS 8.0.2, Is there any Fix for this bug? – Saru Aug 06 '15 at 05:54
-
no, to my knowledge there is no fix. But you should not try to support versions of iOS that were in-between-versions. If someone still uses 8.0 or 8.0.2 they can upgrade to a newer version and fix the problem themselves. – NikkyD Aug 06 '15 at 12:41
-
Yeah that's true. But, unfortunately in apps, we can't ask every customer stucked on that version to upgrade their device. ;) Well, i think i have found a way around. Thanks for your reply. :) – Saru Aug 06 '15 at 14:02
I had same issue. Really layoutSubviews is not called anymore for UILabel on iOS8, as Apple does not expect anybody uses it as superview.
I am using ReactiveCocoaLayout, so it can be done by subscribing to rcl_frameSignal or rcl_boundsSignal.
-(void)awakeFromNib
{
[ self.rcl_boundsSignal
subscribeNext:
^( NSValue* boundsValue )
{
//layout changed
} ];
}
Or you can use simple KVO to know when frame has been changed:
-(void)dealloc
{
[ self removeObserver: self forKeyPath: @"layer.bounds" ];
}
-(void)observeValueForKeyPath:( NSString* )keyPath
ofObject:( id )object
change:( NSDictionary* )change
context:( void* )context
{
if ( [ keyPath isEqualToString: @"layer.bounds" ] )
{
//layoutSubviews
}
else
{
[ super observeValueForKeyPath: keyPath
ofObject: object
change: change
context: context ];
}
}
-(void)awakeFromNib
{
[ self addObserver: self
forKeyPath: @"layer.bounds"
options: NSKeyValueObservingOptionNew
context: 0 ];
}

- 3,579
- 2
- 20
- 32
-
Note that UIKit is per documentation **NOT** KVO-compliant - even if it works for some cases, it might break in the future. – fabb Sep 23 '14 at 09:17
The bug was fixed by Apple in iOS 8.1 (beta).

- 11,660
- 13
- 67
- 111
-
-
-
I have filed a Radar with Apple. And I have created a sample project: github.com/fabb/LabelTest – fabb Oct 02 '14 at 06:57