Центрировать большой UIView, используя NSLayoutConstraint

Я новичок в использовании Autolayouts, даже это моя первая попытка. Что бы я ни делал с этим, я заканчиваю на белом экране. Вот моя попытка.

У меня есть UIView, скажем a parentView кадра (60, 154, 200, 200). Это подзаголовок self.view.

Затем у меня есть динамический вид, скажем dynamicView фрейма (0, 0, 260, 100) и label фрейма (15, 25, 230, 50), который является подвью к dynamicView.

Когда я добавляю dynamicView как подпункт к parentView, он выходит за пределы parentView. Поэтому я хотел бы отрегулировать размер dynamicView и его дочернего элемента (label), чтобы его положение было центральным для parentView и dynamicView в пределах parentView.

Моя первая попытка заключалась в установке clipsToBounds, которая не работает в Xcode5, iOS7. Итак, следующим вариантом является достижение этого с помощью NSLayoutConstraint. Я понятия не имею об этом. Я приветствую ваши идеи.

Ответ 1

Я просто рассмотрю, как dyanmicView является частью проблемы parentView, а затем отпустите оттуда

first: если вы создаете представление динамически, тогда вам хорошо идти, но если вы создали его из раскадровки, вам придется отделить его от родителя, а затем снова подключить это то, что вы избавитесь от него предыдущих NSConstraints (которые обычно представляет собой раскадровка), которые могут конфликтовать с вашими новыми.

вы также должны установить setTranslatesAutoresizingMaskIntoConstraints значение NO b/c, которое также может помешать вашим nsconstraints.

Обычно я делаю эти последние два шага, используя mapObjectsUsingBlock, чтобы сделать весь утомительный процесс создания ограничений немного более приятным и естественным

    [@[view_1, view_2, /../, view_n] mapObjectsApplyingBlock:^(UIView *view) {
        [view removeFromSuperview];
        [view setTranslatesAutoresizingMaskIntoConstraints:NO];
        [view setHidden:NO];
        [superView addSubview:view];
    }];

, затем перед применением nsconstraints, вы должны убедиться, что представление, к которому вы хотите применить ограничения, уже привязано к нему parent:

[parentView addSubview:dynamicView];

, затем вы хотите создать словарь привязок:

NSDictionary *buttonBindingsDictionary = @{ @"parentView" : parentView,
                                            @"dynamicView" : dynamicView};

то вы хотите добавить ограничения, используя язык визуальных форматов. Я также использую mapObjectsUsingBlock здесь (я объясню каждый ограничение на английском языке):

NSArray *buttonConstraints = [@[@"V:|-[dynamicView(>=200)]-|",
                                @"|-[dynamicView(>=260)]-|",
                                ] mapObjectsUsingBlock:^id(NSString *formatString, NSUInteger idx){
    return [NSLayoutConstraint constraintsWithVisualFormat:formatString options:0 metrics:nil views:buttonBindingsDictionary];
}];

V:|-[dynamicView(>=200)]-| означает, что вертикально говоря.. верхнее и нижнее расстояние между dynamicView и его родительское должно быть равным.. также dynamicView's высота должна быть не меньше 200

|-[dynamicView(>=260)]-| означает, что по горизонтали.. левое и правое расстояние между dyanmicview и его родительское должно быть равным.. также dyanmicView's ширина должна быть не меньше 260

Примечание: вы можете сами сделать математику и точно установить расстояние между левым/правым/нижним/верхним расстоянием между dyanicView и родительским. Это просто проще.. но иногда nsconstraints запутывается, и я должен это делать себя.

в этом случае он будет выглядеть примерно так, где x - это расстояние, на которое вы пришли:

V:|-x-[dynamicView(>=200)]-x-|
|-x-[dynamicView(>=260)]-x-|

тогда вы должны добавить ограничения в родительский вид:

[parentView addConstraints:[buttonConstraints flattenArray]];

Обратите внимание, что я использовал flatten array, опять же, что метод из моей библиотеки b/ci хочет передать ему один уровень, а не массив массивов.

и вам хорошо идти!

note: Я знаю, что это может не сработать отлично, но это дает вам представление о том, что делать + некоторые вспомогательные файлы. Это требует некоторой практики, и вы наверняка посмотрите на некоторые из учебники. Я предлагаю вам начать с nsconstraints с помощью раскадровки (вы можете выбрать вид.. затем перейдите в редактоp > pin > .. затем выберите что-то.. получите немедленную визуальную обратную связь.. также вы можете имитировать то, что ваши взгляды будут выглядеть в 3.5 "дисплеях vs 4.0" отображает сразу на раскадровке, выбирая представление контроллер, затем переход к атрибутам инспекторов и выбор разных размеров при моделируемых показателях)

возьмите свое время, но одно можно сказать наверняка: как только вы пойдете nsconstraints, вы никогда не оглянетесь! это полностью стоит!

p.s. вы также можете animate просматривать с помощью nsconstraints.. на всякий случай, когда вам интересно.

Ответ 2

Ограничения автоматической компоновки - лучший подход к тому, чего вы пытаетесь достичь. Автоматические ограничения компоновки автоматически добавляются при проверке опции Использовать автозапуск в IB.

Ознакомьтесь с этим учебным пособием, в котором рассказывается больше об автоматических макетах в iOS6 http://www.raywenderlich.com/20881/beginning-auto-layout-part-1-of-2

то вы можете проверить эту ссылку для обновленного автозапуска в iOS7 http://www.doubleencore.com/2013/09/auto-layout-updates-in-ios-7/