7

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?

fabb
  • 11,660
  • 13
  • 67
  • 111
Maria
  • 755
  • 1
  • 11
  • 29

3 Answers3

5

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

NikkyD
  • 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
4

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 ];
}
Igor Palaguta
  • 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
2

The bug was fixed by Apple in iOS 8.1 (beta).

fabb
  • 11,660
  • 13
  • 67
  • 111