Xcode6, iOS8 и (void)layoutSubviews
У меня есть пользовательский UILabel, который отлично работает на iOS6 и iOS7. Но на iOS8 этот метод layoutSubviews (void) никогда не вызывается. Я создаю эту метку с помощью initWithFrame, поэтому этот метод должен вызываться - и он вызывается в других версиях iOS. Что происходит с системой autoLayout в iOS8?
3 ответа
Я просто хочу добавить этот ответ, потому что заголовок вопроса может привести много людей здесь с похожими проблемами (как я).
С iOS 8 до 8.0.2 LayoutSubviews
звонки ненадежны. Они не могут быть вызваны никогда или (в моем случае) вызваны в цикле.
Несмотря на то, что вы не должны этого делать, было довольно безопасно размещать вещи в LayoutSubviews, но с таким ошибочным (?!) Поведением это может привести к трудным для отслеживания ошибкам.
Я не знаю, исправит ли 8.1 все проблемы, но через некоторое время клиентские устройства будут работать под управлением 8.1, и они будут работать под управлением 8.0.2 СЕЙЧАС
У меня была такая же проблема. Действительно, layoutSubviews больше не вызывается для UILabel на iOS8, так как 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 ];
}