Поиск…


Вступление

Автоматическая компоновка динамически вычисляет размер и положение всех представлений в вашей иерархии представлений на основе ограничений, размещенных на этих представлениях. Источник

Синтаксис

  • NSLayoutConstraint (item: Any, attribute: NSLayoutAttribute, relatedBy: NSLayoutRelation, toItem: Any ?, attribute: NSLayoutAttribute, множитель: CGFloat, константа: CGFloat) // Создавать противопоказание программно

Настройка ограничений программно

Пример кода котельной

override func viewDidLoad() {
    super.viewDidLoad()

    let myView = UIView()
    myView.backgroundColor = UIColor.blueColor()
    myView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(myView)

    // Add constraints code here
    // ...
}

В приведенных ниже примерах стиль Anchor является предпочтительным методом над NSLayoutConstraint , однако он доступен только для iOS 9, поэтому, если вы поддерживаете iOS 8, вам все равно следует использовать стиль NSLayoutConstraint .

Закрепление

Анкерный стиль

let margins = view.layoutMarginsGuide
myView.leadingAnchor.constraintEqualToAnchor(margins.leadingAnchor, constant: 20).active = true
  • В дополнение к leadingAnchor , есть также trailingAnchor , topAnchor и bottomAnchor .

Стиль NSLayoutConstraint

NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.Leading, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.LeadingMargin, multiplier: 1.0, constant: 20.0).active = true
  • В дополнение к .Leading также есть .Trailing , .Top и .Bottom .
  • В дополнение к .LeadingMargin также есть .TrailingMargin , .TopMargin и .BottomMargin .

Стиль визуального форматирования

NSLayoutConstraint.constraintsWithVisualFormat("H:|-20-[myViewKey]", options: [], metrics: nil, views: ["myViewKey": myView])

Ширина и высота

Анкерный стиль

myView.widthAnchor.constraintEqualToAnchor(nil, constant: 200).active = true
myView.heightAnchor.constraintEqualToAnchor(nil, constant: 100).active = true

Стиль NSLayoutConstraint

NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: 200).active = true
NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: 100).active = true

Стиль визуального форматирования

NSLayoutConstraint.constraintsWithVisualFormat("H:[myViewKey(200)]", options: [], metrics: nil, views: ["myViewKey": myView])
NSLayoutConstraint.constraintsWithVisualFormat("V:[myViewKey(100)]", options: [], metrics: nil, views: ["myViewKey": myView])

Центр в контейнере

Анкерный стиль

myView.centerXAnchor.constraintEqualToAnchor(view.centerXAnchor).active = true
myView.centerYAnchor.constraintEqualToAnchor(view.centerYAnchor).active = true

Стиль NSLayoutConstraint

NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.CenterX, multiplier: 1, constant: 0).active = true
NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.CenterY, multiplier: 1, constant: 0).active = true

Стиль визуального форматирования

NSLayoutConstraint.constraintsWithVisualFormat("V:[viewKey]-(<=0)-[myViewKey]", options: NSLayoutFormatOptions.AlignAllCenterX, metrics: nil, views: ["myViewKey": myView, "viewKey": view])
NSLayoutConstraint.constraintsWithVisualFormat("H:[viewKey]-(<=0)-[myViewKey]", options: NSLayoutFormatOptions.AlignAllCenterY, metrics: nil, views: ["myViewKey": myView, "viewKey": view])

Как использовать автоматический макет

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

Автоматический макет включен по умолчанию, но вы можете дважды проверить это. Если вы нажмете Main.storyboard в Навигаторе проектов, а затем покажете Инспектор файлов. Убедитесь, что отмечены флажки Auto Layout и Size Classes:

введите описание изображения здесь

Ограничения автоматической компоновки можно задать в построителе интерфейса или в коде. В интерфейсе Builder вы найдете инструменты автоматического макета в правом нижнем углу. Нажав на них, вы увидите различные варианты установки ограничений для представления.

введите описание изображения здесь

Если вы хотите иметь разные ограничения для разных размеров или ориентации устройства, вы можете установить их в WAny hayny Size Class, которые находятся в нижней части.

введите описание изображения здесь

Центровые ограничения

Выберите свою кнопку (или любой другой вид, который хотите центрировать) на раскадровке . Затем нажмите кнопку выравнивания в правом нижнем углу. Выберите « Horizontally in Container и « Vertically in Container . Нажмите «Добавить 2 ограничения».

Выравнивание - метод 1

Если бы он не был полностью центрирован, вам, возможно, понадобится сделать еще одну вещь. Нажмите кнопку «Обновить фреймы», расположенную на два слева от кнопки «Вставить в стек» на нижней панели. Обновление фреймов

Вы также можете «обновлять фреймы по мере необходимости», нажимая вместе + + = (Command + Option и equals) после выбора представления, это может сэкономить некоторое время.

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

Другой способ просмотра точек с помощью Interface Builder - это перетаскивание с помощью элемента управления. Предположим, вы хотите UILabel в представлении. Откройте Document Outline в своем раскадровке, нажав кнопку боковой панели внизу слева. Нажмите и перетащите ярлык в представление, удерживая ctrl (control), и появится синяя линия:

Синяя линия

После выпуска появится меню параметров ограничения:

меню параметров ограничения

Выберите «Центр по горизонтали в контейнере» и «Центрировать по вертикали в контейнере». Обновляйте кадры по мере необходимости и вуаля! Центральная этикетка.

В качестве альтернативы вы можете добавлять ограничения программно. Создайте ограничения и добавьте их в нужные элементы пользовательского интерфейса и представления, как описано в следующем примере, где мы создаем кнопку и выравниваем ее по центру, по горизонтали и по вертикали в ее супервизор:

Objective-C

- (void)viewDidLoad
{
    [super viewDidLoad];
    UIButton *yourButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 100, 18)];
    [yourButton setTitle:@"Button" forState:UIControlStateNormal];


    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:yourButton attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterY multiplier:1 constant:0]]; //Align veritcally center to superView

    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:yourButton attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1 constant:0]]; //Align horizontally center to superView

    [self.view addSubview:yourButton]; //Add button to superView
}

стриж

override func viewDidLoad() 
{
    super.viewDidLoad()
    let yourButton: UIButton = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 18))
    yourButton.setTitle("Button", forState: .Normal)

    let centerVertically = NSLayoutConstraint(item: yourButton,
                                   attribute: .CenterX,
                                   relatedBy: .Equal,
                                      toItem: view,
                                   attribute: .CenterX,
                                  multiplier: 1.0,
                                    constant: 0.0)
    let centerHorizontally = NSLayoutConstraint(item: yourButton,
                                   attribute: .CenterY,
                                   relatedBy: .Equal,
                                      toItem: view,
                                   attribute: .CenterY,
                                  multiplier: 1.0,
                                    constant: 0.0)
    NSLayoutConstraint.activateConstraints([centerVertically, centerHorizontally])
}

Пространственные виды

введите описание изображения здесь

Обычно требуется, чтобы два вида были бок о бок, в центре их наблюдения. Общий ответ, заданный в Stack Overflow, заключается в том, чтобы вставлять эти два представления в UIView и UIView . Это необязательно или рекомендуется. Из документов UILayoutGuide :

Существует ряд затрат, связанных с добавлением фиктивных представлений в вашу иерархию представлений. Во-первых, есть затраты на создание и поддержание самого представления. Во-вторых, фиктивный вид является полноправным членом иерархии представлений, что означает, что он добавляет служебные данные для каждой задачи, выполняемой иерархией. Хуже всего, невидимый фиктивный вид может перехватывать сообщения, предназначенные для других представлений, что вызывает проблемы, которые очень трудно найти.

Вы можете использовать UILayoutGuide для этого, вместо добавления кнопок в ненужный UIView . UILayoutGuide - это, по сути, прямоугольное пространство, которое может взаимодействовать с Auto Layout. Вы устанавливаете UILayoutGuide с левой и правой сторон кнопок и устанавливаете их ширину равными. Это будет центрировать кнопки. Вот как это сделать в коде:

Стиль визуального форматирования

view.addSubview(button1)
view.addSubview(button2)

let leftSpace = UILayoutGuide()
view.addLayoutGuide(leftSpace)

let rightSpace = UILayoutGuide()
view.addLayoutGuide(rightSpace)

let views = [
    "leftSpace" : leftSpace,
    "button1" : button1,
    "button2" : button2,
    "rightSpace" : rightSpace
]

// Lay the buttons and layout guides out horizontally in a line. 
// Put the layout guides on each end.
NSLayoutConstraint.activateConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[leftSpace][button1]-[button2][rightSpace]|", options: [], metrics: nil, views: views))

// Now set the layout guides widths equal, so that the space on the 
// left and the right of the buttons will be equal
leftSpace.widthAnchor.constraintEqualToAnchor(rightSpace.widthAnchor).active = true

Анкерный стиль

let leadingSpace = UILayoutGuide()
let trailingSpace = UILayoutGuide()
view.addLayoutGuide(leadingSpace)
view.addLayoutGuide(trailingSpace)

leadingSpace.widthAnchor.constraintEqualToAnchor(trailingSpace.widthAnchor).active = true
    
leadingSpace.leadingAnchor.constraintEqualToAnchor(view.leadingAnchor).active = true
leadingSpace.trailingAnchor.constraintEqualToAnchor(button1.leadingAnchor).active = true
    
trailingSpace.leadingAnchor.constraintEqualToAnchor(button2.trailingAnchor).active = true
trailingSpace.trailingAnchor.constraintEqualToAnchor(view.trailingAnchor).active = true

Вам также нужно будет добавить к этому вертикальные ограничения, но это будет центрировать кнопки в представлении без добавления каких-либо «фиктивных» представлений! Это избавит систему от потери времени процессора при отображении этих «фиктивных» представлений. В этом примере используются кнопки, но вы можете поменять кнопки для любого вида, на которое вы хотите установить ограничения.

Если вы поддерживаете iOS 8 или ранее, самым простым способом создания этого макета является добавление скрытых фиктивных представлений. С помощью iOS 9 вы можете заменить фиктивные виды макетами.

Примечание. Интерфейс Builder еще не поддерживает макеты (Xcode 7.2.1). Поэтому, если вы хотите их использовать, вы должны создать свои ограничения в коде. Источник .

Внутренний размер UILabel

Мы должны создать представление, которое будет иметь префикс изображения для текста. текст может иметь переменную длину. Мы должны достичь результата, когда текст изображения + всегда находится в центре родительского представления.

введите описание изображения здесь

Шаг 1: Сначала создайте проект с одним видом и назовите его чем-то по своему выбору и откройте кулак из раскрывающегося списка. Сделайте вид с некоторым разумным размером и установите его цвет фона на желтый. Я изменил размер моего монитора представления на 3.5 ". взгляд должен выглядеть примерно так

введите описание изображения здесь

Шаг 2. Теперь мы добавим ограничения на желтый вид. Для начала добавим ограничения ширины и высоты. Подождите минуту, мы не сказали, что представление будет иметь динамическую ширину? Хорошо, мы вернемся к нему позже. Добавьте следующие ограничения в соответствии с приведенным ниже изображением не беспокоятся о значении ширины, любое значение будет просто отлично для ширины, просто держите его достаточно большим, чтобы мы могли правильно добавлять автоопределения.

введите описание изображения здесь

После добавления этих двух ограничений вы увидите, что XCode дает вам ошибки, как показано на рисунке ниже, чтобы увидеть их и понять. введите описание изображения здесь

У нас есть две ошибки (красная означает ошибку). Как обсуждалось выше, можно пересмотреть часть двусмысленности

Недостающие ограничения: Необходимые ограничения для: X-позиции: - Как обсуждалось выше, мы дали представление ширину и высоту, чтобы определить ее «БОЛОНЫ», но мы не дали ее происхождения, поэтому ее «РАМКА» не определена. Autolayout не может определить, какова будет позиция X нашего желтого вида

Отсутствующие ограничения: Необходимые ограничения для: Y-позиции: - Как обсуждалось выше, мы дали представление ширину и высоту, чтобы определить ее «BOUNDS», но мы не дали ее происхождения, поэтому ее «FRAME» не определена. Autolayout не может определить, какова будет Y-позиция нашего желтого обзора. Чтобы решить эту проблему, мы должны дать автоопределению что-то, чтобы изменить X и Y. Поскольку мы не можем установить фреймы, мы сделаем это автоматически. Добавьте следующие ограничения в соответствии с ниже, я объясню позже

введите описание изображения здесь

Что мы сделали, мы добавили «Вертикальный центр» и «Горизонтальный центр», которые ограничивают автоспуск, что наш желтый вид всегда будет находиться в центре по горизонтали: так что X в определенном порядке с вертикальным ограничением и определяется Y (вы возможно, придется отрегулировать рамку).

Шаг 3: Теперь наш базовый желтый вид готов. Мы добавим префиксное изображение в качестве подсмотра нашего желтого представления со следующими ограничениями. Вы можете выбрать любое изображение по вашему выбору.

введите описание изображения здесь

Поскольку у нас фиксированный размер для нашего префикса, мы будем иметь фиксированную ширину ширины для этого изображения. Добавьте ограничения и переходите к следующему шагу.

Шаг 4: добавьте UILabel в качестве дополнительного представления нашего желтого представления и добавьте следующие ограничения

введите описание изображения здесь

Как вы можете видеть, я дал только относительные ограничения для нашего UILabel.Its 8 баллов из префикса и 0,0,0 верхний трейлинг и снизу из желтого представления. Поскольку мы хотим, чтобы ширина была динамической, мы не будем ограничивать ширину или высоту ,

В: Почему мы не получаем никаких ошибок сейчас, мы не дали никакой ширины и высоты? Ans: - Мы получаем сообщение об ошибке или предупреждении только в том случае, если автомат не может разрешить любую вещь, которая необходима для визуализации представления на экране. Пусть это ширина или начало по высоте. Поскольку наша метка относится к желтому представлению и префиксному изображению и их кадрам четко определен автозапуск, способный вычислить рамку нашей метки.

Шаг 5: Теперь, если вспомнить, мы поймем, что мы дали фиксированный взгляд на желтый вид, но хотим, чтобы он был динамически зависим от текста нашей метки. Поэтому мы изменим нашу ширину. Ограничение желтого цвета. Ширина желтого вида необходимо устранить двусмысленность, но мы хотим, чтобы он был отменен во время выполнения на основе содержимого UILabel. Поэтому мы выберем наш желтый вид и перейдем к диспетчеру размера и уменьшим приоритет ограничения ширины до 1, чтобы он был превышен. Следуйте приведенному ниже изображению.

введите описание изображения здесь

Шаг 6: Мы хотим, чтобы UILabel расширялась в соответствии с текстом и выдвигала наш желтый вид. Итак, мы уменьшили приоритет желтой ширины. Теперь мы увеличим приоритет сопротивления сжатию текста нашего UILabel. Мы хотим, чтобы наше мнение уменьшалось как так что мы увеличим приоритет обнимания содержимого UILabel.

введите описание изображения здесь

Как вы можете видеть, мы увеличили приоритет обхода контента до 500 и приоритет сопротивления сжатию до 751, который будет успешно превышать 1 приоритет ограничения ширины.

Теперь создадим и запустим, вы увидите что-то следующее.

введите описание изображения здесь

Как анимировать с помощью автоматической компоновки

Без автоматической компоновки анимация выполняется с изменением фрейма представления с течением времени. С помощью Auto Layout ограничения задают рамку представления, поэтому вам нужно анимировать ограничения. Это направление делает анимацию сложнее визуализировать.

Ниже приведены способы анимации с помощью Auto Layout:

  1. Измените константу ограничения после создания с помощью периодических вызовов ( CADisplayLink , dispatch_source_t , dispatch_after , NSTimer ). Затем вызовите layoutIfNeeded чтобы обновить ограничение. Пример:

Objective-C:

self.someConstraint.constant = 10.0;
[UIView animateWithDuration:0.25 animations:^{
    [self.view layoutIfNeeded];
}];

Swift:

self.someConstraint.constant = 10.0
UIView.animate(withDuration: 0.25, animations: self.view.layoutIfNeeded)
  1. Измените ограничения и вызовите [view layoutIfNeeded] внутри блока анимации. Это интерполирует между двумя положениями, игнорируя ограничения во время анимации.
[UIView animateWithDuration:0.5 animations:^{
    [view layoutIfNeeded];
}]
  1. Измените приоритет ограничений . Это менее интенсивно процессор, чем добавление и удаление ограничений.

  2. Удалите все ограничения и используйте маски автосохранения . Для более поздних вам нужно установить view.translatesAutoresizingMaskIntoConstraints = YES .

  3. Используйте ограничения, которые не мешают намеченной анимации .

  4. Используйте представление контейнера . Поместите надпись с использованием ограничений. Затем добавьте subview с ограничениями, которые не сражаются с анимацией, например: центр относительно супервизора. Это выгружает часть ограничений в супервизор, поэтому они не сражаются с анимацией в подвью.

  5. Анимированные слои вместо этого видят . Преобразования слоев не вызывают автоматический макет.

CABasicAnimation* ba = [CABasicAnimation animationWithKeyPath:@"transform"];
ba.autoreverses = YES;
ba.duration = 0.3;
ba.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(1.1, 1.1, 1)];
[v.layer addAnimation:ba forKey:nil];
  1. Переопределить layoutSubviews . Вызовите [super layoutSubviews] и настройте ограничения.

  2. Измените рамку в viewDidLayoutSubviews . layoutSubviews применяется в layoutSubviews , поэтому после его выполнения измените его в viewDidLayoutSubviews .

  3. Откажитесь от автоматического макета и вручную установите представления. Вы можете сделать это переопределением layoutSubviews / layout без вызова реализации суперкласса.

Быстрый совет: если родительский layoutIfNeeded() анимированного представления не интерполируется (т. layoutIfNeeded() Анимация переходит из состояния начала в конец), вызовите layoutIfNeeded() в самом глубоком представлении, layoutIfNeeded() родителем анимированного представления (другими словами , на которые не влияет анимация). Я точно не знаю, почему это работает.

Разрешить конфликт приоритетов UILabel

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

введите описание изображения здесь

Как мы можем исправить это предупреждение ?

Решение . Мы рассчитываем и устанавливаем приоритеты в порядке. Приоритеты должны отличаться от ярлыков. Это означает, что важно, получит более высокий приоритет. Например, в моем случае я устанавливаю вертикальные приоритеты для своих ярлыков следующим образом:

Я установил наивысший приоритет для 1-й метки и самый низкий для 4-й метки.

введите описание изображения здесь

введите описание изображения здесь

В ViewController, я думаю, вам трудно увидеть эффект этих приоритетов. Тем не менее, очень ясно, что UITableViewCell + оценивает высоту ячейки.

Надеюсь, эта помощь.

Размер UILabel и Parentview Согласно тексту в UILabel

Пошаговое руководство: -

Шаг 1: - Установите ограничение на UIView

  1. Ведущий. 2) Верх. 3) Трейлинг. (Из основного окна)

введите описание изображения здесь

Шаг 2: - Установите ограничение на метку 1

  1. Leading 2) Top 3) Trailing (Из его супервизора)

введите описание изображения здесь

Шаг 3: - Установите ограничение на метку 2

  1. Leading 2) Top 3) Trailing (из своего супервизора)

введите описание изображения здесь

Шаг 4: - Самое сложное дать нижнюю часть UILabel из UIView.

введите описание изображения здесь

Шаг 5: - (Необязательно) Установите ограничение на UIButton

  1. Ведущий 2) Нижний 3) Трейлинг 4) Фиксированная высота (из основного вида)

введите описание изображения здесь

Выход :-

введите описание изображения здесь

Примечание. - Убедитесь, что вы установили Number of lines = 0 в свойстве Label.

введите описание изображения здесь

Я надеюсь, что эта информация достаточно, чтобы понять Autoresize UIView в соответствии с высотой UILabel и Autoresize UILabel. Согласно тексту.

Основы языка Visual Format: ограничения в коде!

HVFL - это язык, предназначенный для ограничения элементов пользовательского интерфейса простым и быстрым способом. Как правило, VFL имеет преимущество перед традиционной настройкой пользовательского интерфейса в Interface Builder, потому что он гораздо читабельнее, доступен и компактен.

Вот пример VFL, в котором три UIViews ограничены слева направо, заполняя superView.width , с помощью aGradeView

"H:|[bgView][aGradeView(40)][bGradeView(40)]|"

Есть две оси, в которых мы можем ограничить объекты пользовательского интерфейса, по горизонтали и по вертикали.

Каждая строка VFL всегда начинается с H: или V: Если ни один из них не присутствует, по умолчанию используется значение H:

Двигаясь дальше, у нас есть конвейер. | Этот символ или труба относится к надзору. Если вы более подробно рассмотрите фрагмент кода VFL выше, вы заметите два из этих конвейеров.

Это означает два горизонтальных конца надзора, внешние и внешние границы.

Затем вы увидите квадратные скобки, в первом наборе квадратных скобок у нас есть bgView . Когда у нас есть квадратные скобки, это относится к элементу пользовательского интерфейса, теперь вы можете задаться вопросом, как установить связь между именем и фактическим элементом пользовательского интерфейса, возможно, выходом?

Я расскажу об этом в конце сообщения.

Если вы посмотрите на вторую пару квадратных скобок [aGradeView(50)] , мы также [aGradeView(50)] круглые скобки внутри, когда это присутствует, она определяет ширину / высоту в зависимости от осей, которая в этом случае равна 50 пикселей в ширину.

Первые квадратные скобки [bgView] не имеют явно определенной ширины, что означает, что она будет охватывать как можно больше.

Хорошо, это все для основ, больше о передовых материалах в другом примере.


например:
VFL_demo

    // 1. create views
    UIView *blueView = [[UIView alloc] init];
    blueView.backgroundColor = [UIColor blueColor];
    [self.view addSubview:blueView];

    UIView *redView = [[UIView alloc] init];
    redView.backgroundColor = [UIColor redColor];
    [self.view addSubview:redView];

    // 2. forbid Autoresizing
    blueView.translatesAutoresizingMaskIntoConstraints = NO;
    redView.translatesAutoresizingMaskIntoConstraints = NO;

    // 3. make contraints
    // horizontal
    NSArray *blueH = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-20-[blueView]-20-|" options:NSLayoutFormatAlignAllLeft metrics:nil views:@{@"blueView" : blueView}];
    [self.view addConstraints:blueH];

    // vertical
    NSArray *blueVandRedV = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-20-[blueView(50)]-20-[redView(==blueView)]" options:NSLayoutFormatAlignAllTrailing metrics:nil views:@{@"blueView" : blueView, @"redView" : redView}];
    [self.view addConstraints:blueVandRedV];

    NSLayoutConstraint *redW = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeWidth multiplier:0.5 constant:0];
    [self.view addConstraint:redW];

Смешанное использование автоматической компоновки с неавтоматической компоновкой

Иногда вы можете выполнить некоторые дополнительные действия для вычислений Auto Layout, выполненных самим UIKit .

Пример: если у вас есть UIView , который имеет maskLayer , возможно , потребуется обновить maskLayer как только Auto Layout меняет UIView «S frame

// CustomView.m
- (void)layoutSubviews {
    [super layoutSubviews];
    // now you can assume Auto Layout did its job
    // you can use view's frame in your calculations
    CALayer maskLayer = self.maskLayer;
    maskLayer.bounds = self.bounds;
    ...
}

или если вы хотите предпринять дополнительные действия для автоматического макета в ViewController

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    // now you can assume all your subviews are positioned/resized correctly
    self.customView.frame = self.containerView.frame;
}

Пропорциональный макет

Ограничение, созданное как

NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.Leading, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.LeadingMargin, multiplier: 1.0, constant: 20.0)

или, с математической точки зрения:

view.attribute * multiplier + constant          (1)

Вы можете использовать множитель для создания пропорционального макета для разного коэффициента.

Пример:

Бирюзовый вид (V1) представляет собой квадрат с шириной пропорциональной ширины супервизора с отношением 1: 1.1

Квадрат Гэри (V2) является подпунктом V1. Нижнее пространство, заданное константой = 60, Конечное пространство, заданное множителем = 1.125 и константой = 0

Пространственное пространство устанавливается пропорционально, нижнее пространство устанавливается как константа.

введите описание изображения здесь

Примечание: если view.attribute равен 0 (например, ведущее пространство), формула ограничения (1), будет равна 0. Вам нужно изменить второй элемент ограничения или установить ограничение относительно поля, чтобы view.attribute! = 0.

NSLayoutConstraint: Препятствия в коде!

Когда мы работаем над фреймворком, если ограничения не слишком сложны, нам лучше использовать Interface Builder или NSLayoutConstraint в коде, чтобы сделать его достаточно небольшим, вместо импорта масонства или SnapKit.

например:
введите описание изображения здесь

  • Objective-C
    // 1. create views
    UIView *blueView = [[UIView alloc] init];
    blueView.backgroundColor = [UIColor blueColor];
    [self.view addSubview:blueView];

    UIView *redView = [[UIView alloc] init];
    redView.backgroundColor = [UIColor redColor];
    [self.view addSubview:redView];

    // 2. forbid Autoresizing
    blueView.translatesAutoresizingMaskIntoConstraints = NO;
    redView.translatesAutoresizingMaskIntoConstraints = NO;

    // 3. make contraints
    // 3.1 blueView
    NSLayoutConstraint *blueLeft = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1 constant:20];
    [self.view addConstraint:blueLeft];

    NSLayoutConstraint *blueTop = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1 constant:20];
    [self.view addConstraint:blueTop];

    NSLayoutConstraint *blueRight = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:1 constant:-20];
    [self.view addConstraint:blueRight];

    NSLayoutConstraint *blueHeight = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:50];
    [self.view addConstraint:blueHeight];

    // 3.2 redView
    NSLayoutConstraint *redTop = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeBottom multiplier:1 constant:20];
    [self.view addConstraint:redTop];

    NSLayoutConstraint *redRight = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:1 constant:-20];
    [self.view addConstraint:redRight];

    NSLayoutConstraint *redHeight = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeHeight multiplier:1 constant:0];
    [self.view addConstraint:redHeight];

    NSLayoutConstraint *redWidth = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeWidth multiplier:0.5 constant:0];
    [self.view addConstraint:redWidth];


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow