7

我有自定义 UILabel 可以在 iOS6 和 iOS7 上正常工作。但是在 iOS8 上,这个标签的 (void)layoutSubviews 方法永远不会被调用。我用 initWithFrame 创建了这个标签,所以应该调用这个方法 - 它在另一个 iOS 版本上被调用。iOS8 中的自动布局系统会发生什么?

4

3 回答 3

5

我只想添加这个答案,因为问题标题可能会导致很多人在这里遇到类似的问题(比如我)。

使用 iOS 8 到 8.0.2LayoutSubviews调用是不可靠的。它们可能永远不会被调用,或者(在我的情况下)被循环调用。

即使您不应该这样做,在 LayoutSubviews 中分配东西也是非常安全的,但是这种错误(?!)行为可能会导致难以跟踪的错误。

我不知道 8.1 是否解决了所有问题,但客户设备运行 8.1 并且他们现在运行 8.0.2 还需要一段时间

于 2014-10-02T14:37:48.073 回答
4

我有同样的问题。实际上,iOS8 上的 UILabel 不再调用 layoutSubviews,因为 Apple 不希望有人将其用作超级视图。

我正在使用ReactiveCocoaLayout,因此可以通过订阅 rcl_frameSignal 或 rcl_boundsSignal 来完成。

-(void)awakeFromNib { [ self.rcl_boundsSignal subscribeNext: ^( NSValue* boundsValue ) { //layout changed } ]; }

或者您可以使用简单的 KVO 来了解帧何时更改:

-(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 ];
}
于 2014-09-10T12:44:17.567 回答
2

Apple 在 iOS 8.1(测试版)中修复了该错误。

于 2014-10-01T09:25:42.227 回答