我有自定义 UILabel 可以在 iOS6 和 iOS7 上正常工作。但是在 iOS8 上,这个标签的 (void)layoutSubviews 方法永远不会被调用。我用 initWithFrame 创建了这个标签,所以应该调用这个方法 - 它在另一个 iOS 版本上被调用。iOS8 中的自动布局系统会发生什么?
3 回答
我只想添加这个答案,因为问题标题可能会导致很多人在这里遇到类似的问题(比如我)。
使用 iOS 8 到 8.0.2LayoutSubviews
调用是不可靠的。它们可能永远不会被调用,或者(在我的情况下)被循环调用。
即使您不应该这样做,在 LayoutSubviews 中分配东西也是非常安全的,但是这种错误(?!)行为可能会导致难以跟踪的错误。
我不知道 8.1 是否解决了所有问题,但客户设备运行 8.1 并且他们现在运行 8.0.2 还需要一段时间
我有同样的问题。实际上,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 ];
}
Apple 在 iOS 8.1(测试版)中修复了该错误。