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

Я определил пользовательское представление в файле 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, устанавливаю его класс в свой собственный класс и макет его размера и сосредоточен на моей странице, снова используя автозапуск.

enter image description here

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

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

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]];

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

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

Ура!

Ответ 1

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

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

[self.topView setTranslatesAutoresizingMaskIntoConstraints:NO];

Ответ 2

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

    - (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: подход объясняется здесь. Я добавил ограничения макета масонства, чтобы он работал с ограничениями, определенными в построителе интерфейса.

Ответ 3

Отключение "Use Size Classes" работало для меня. Мне не нужно было делать то, что сказал mkrus.