Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Xcode6, iOS8 and (void)layoutSubviews

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?

like image 360
Maria Avatar asked Jul 01 '14 12:07

Maria


2 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

like image 91
NikkyD Avatar answered Oct 13 '22 00:10

NikkyD


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 ];
}
like image 36
Igor Palaguta Avatar answered Oct 12 '22 23:10

Igor Palaguta