2013-06-15 2 views
10

Я определил пользовательский вид в файле NIB и хотел бы создать экземпляр в StoryBoard, но у меня возникли проблемы с автозапуском.Проблемы с AutoLayout с пользовательскими представлениями, определенными в файле NIB и используемыми в StoryBoard

В простом примере пользовательский вид имеет единую метку с фиксированным размером и центрирован как по вертикали, так и по горизонтали, все с использованием автозапуска.

enter image description here

Владелец файла устанавливается в мой класс, он имеет выход на вид сверху. При осуществлении вида в я:

- (id)initWithCoder:(NSCoder *)aDecoder 
{ 
    self = [super initWithCoder:aDecoder]; 
    if(self) 
    { 
     [[NSBundle mainBundle] loadNibNamed:@"FMCompassView" owner:self options:nil]; 
     [self addSubview:self.topView]; 
    } 
    return self; 
} 

Теперь в моей раскадровке добавить UIView, установите это класс моего пользовательского класс и макет его размер и расположение на моей странице, снова используя autolayout.

enter image description here

И мой виджет установлен и размер правильно, но его содержание не изменяется, как показано ниже: enter image description here

Я пытался добавить больше ограничений после загрузки из СИБ, что-то вдоль линий:

UIView* subV = self.topView; 
NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(subV); 
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[subV]|" options:NSLayoutFormatAlignAllBaseline metrics:nil views:viewsDictionary]]; 
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[subV]|" options:NSLayoutFormatAlignAllBaseline metrics:nil views:viewsDictionary]]; 

Но это вызывает недопустимые ограничения компоновки.

Любые идеи о том, как заставить это работать?

Cheers!

+0

думаю, что я нашел причину: представление, созданное при загрузке NIB, должно быть сказано, чтобы не преобразовывать маску автоматического изменения в ограничения, * EVEN *, если содержимое NIB фактически создано с включенным автозапуском. Итак, после загрузки NIB и перед добавлением его верхнего вида в пользовательское представление мне нужно позвонить: '[self.topView setTranslatesAutoresizingMaskIntoConstraints: NO];' – mkrus

+0

Вы можете найти правильный ответ здесь: http://stackoverflow.com/а/34524346/971329. См. Мой комментарий ниже для быстрой реализации многократного просмотра, который заботится обо всех вещах. – blackjacx

ответ

20

Представление, созданное при загрузке NIB, должно быть указано, чтобы не преобразовывать маску с автоматическим изменением размера в ограничения, EVEN, если содержимое NIB фактически создано с включенным автозапуском.

Таким образом, после загрузки СИБ и перед добавлением его вид сверху на настраиваемое представление, мне нужно позвонить:

[self.topView setTranslatesAutoresizingMaskIntoConstraints:NO]; 
+3

Хотя это будет работать, принято считать лучшей практикой переопределить метод класса, т. Е.'+ (BOOL) translatesAutoresizingMaskIntoConstraints {return YES;}' – Ash

0

Отключение «Использование размерных классов» работал для меня. Мне не нужно было делать то, что сказал mkrus.

+0

Я пробовал это, но не работал. –

1

В дополнение к тому, что mkrus предполагает выше, это то, что мой initWithCoder: выглядит для пользовательского класса СИБ:

- (instancetype)initWithCoder:(NSCoder *)aDecoder 
    { 
     self = [super initWithCoder:aDecoder]; 
     if (self) { 
      NSString *className = NSStringFromClass([self class]); 
      self.view = [[[NSBundle mainBundle] loadNibNamed:className owner:self options:nil] firstObject]; 
      [self.view setTranslatesAutoresizingMaskIntoConstraints:NO]; 
      [self addSubview:self.view]; 
      [self.view mas_makeConstraints:^(MASConstraintMaker *make) { 
       make.edges.equalTo(self); 
      }]; 
     } 
     return self; 
    } 

Причина этого initWithCoder: подход объясняется here. Я добавил ограничения макета масонства, чтобы он работал с ограничениями, определенными в построителе интерфейса.