2016-10-22 2 views
1

Есть несколько вопросов, задающих это вопрос SO, но никто не спросил об этом правильно.Просмотр 1000x1000 на initWithCoder:

Я использую пользовательский индикатор выполнения, который является классом UIView с этой реализацией.

@implementation MCProgressBarView { 
    UIImageView * _backgroundImageView; 
    UIImageView * _foregroundImageView; 
    CGFloat minimumForegroundWidth; 
    CGFloat availableWidth; 
} 

- (instancetype)initWithCoder:(NSCoder *)aDecoder { 
    self = [super initWithCoder:aDecoder]; 
    // [self bounds] is 1000x1000 here... what? 
    if (self) [self initialize]; 
    return self; 
} 


- (instancetype)initWithFrame:(CGRect)frame { 
    self = [super initWithFrame:frame]; 
    if (self) [self initialize]; 
    return self; 
} 

- (void) initialize { 
    UIImage * backgroundImage = [[[UIImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"progress-bg" ofType:@"png"]] 
           resizableImageWithCapInsets:UIEdgeInsetsMake(0.0f, 10.0f, 0.0f, 10.0f)]; 

    UIImage * foregroundImage = [[[UIImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"progress-bg" ofType:@"png"]] 
           resizableImageWithCapInsets:UIEdgeInsetsMake(0.0f, 10.0f, 0.0f, 10.0f)]; 

    _backgroundImageView = [[UIImageView alloc] initWithFrame:self.bounds]; 
    _backgroundImageView.image = backgroundImage; 
    [self addSubview:_backgroundImageView]; 

    _foregroundImageView = [[UIImageView alloc] initWithFrame:self.bounds]; 
    _foregroundImageView.image = foregroundImage; 
    [self addSubview:_foregroundImageView]; 

    UIEdgeInsets insets = foregroundImage.capInsets; 
    minimumForegroundWidth = insets.left + insets.right; 

    availableWidth = self.bounds.size.width - minimumForegroundWidth; 

    [self adjustProgress:0.0f]; 
} 

Я создал UIView на интерфейсе строителя быть 200x20 точек и назначен этот вид быть из этого пользовательского класса MCProgressBarView я использую. Когда приложение запускается, initWithCoder запускает и создает представление прогресса с размером 1000x1000 точек без учета размера, которое имеет вид на IB.

Как заставить initWithCoder работать с соответствующим размером, назначенным на IB?

ПРИМЕЧАНИЕ. Я не хочу жестко подключать это к 200x20, и я не хочу устанавливать это по коду во время выполнения. Есть ли способ сделать эту работу?

ответ

2

TL; Переместить логику фреймов/границ в положение viewDidLayoutSubviews.

initWithCoder: небезопасен для выполнения логики кадра. Вы должны использовать для этого viewDidLayoutSubviews. Apple использует 1000x1000 границ, начиная с iOS 10. Неясно, есть ли ошибка или преднамеренная, но, похоже, имеет чистый положительный результат - люди приходят сюда и спрашивают об этом. ;-)

Фактически, initWithCoder: никогда не был в безопасности для такой логики. Раньше у вас было бы представление, чьи границы были бы связаны с экраном iPhone 5, потому что это то, что вы использовали в IB, но тогда представление увеличилось бы до размера iPhone 6 Plus или iPad, и это вызовет зрительные проблемы.

Теперь Apple просто устанавливает границы 1000x1000, что является неправильным для всех случаев. Оценки корректируются после выполнения макета на представлении.

+1

В классе класса UIView нет viewDidLayoutSubviews. Если я использую viewController для правильного отображения размера представления, все это плохо задумывается Apple как много вещей на ios. – SpaceDog

+0

@SpaceDog Используйте 'layoutSubviews'. –

+0

Хорошо. Я реализовал 'layoutSubviews' в классе. Когда этот метод запускается, представление имеет нужный размер без необходимости делать что-либо, но когда оно отображается в приложении, оно равно 1000x1000. – SpaceDog

Смежные вопросы