2015-05-09 7 views
1

Скажем, у меня есть три UILabels, чьи позиции, как показано ниже:ИОС autolayout динамическую высоту UILabel

[Label1] [Label2]

[Label3]

Label1 и Label2 находятся в одной и той же строке и Label3 ниже них. Все метки будут иметь фиксированную ширину и будут содержать динамический текст, поэтому их высота будет различной.

Как сделать Label3 10 баллов ниже метки, которая имеет более высокую высоту, используя AutoLayout?

Например, если Label1 «Высота ы составляет 100 пунктов, Label2» Высота с 120 точками (их позиции Y являются одинаковыми), то Label3 должно быть 10 пунктов ниже Label2, но если Label1 120 баллов высокой и Label2 составляет 100 пунктов, то Label3 должно быть на 10 пунктов ниже Label1.

+0

Ограничение, как «объект А должен быть N пунктов ниже объекта B» чрезвычайно прост в Автокомпоновка. Можете ли вы показать код, который вы пробовали в первую очередь? –

+0

Да, но я хочу, чтобы объект А был N точками ниже того, который имеет более высокую высоту, скажем, объект B и объект C находятся в одной строке, но их высоты не фиксированы (например, какой-то динамический текст), мне нужен объект A чтобы быть N точками ниже Объекта, который выше. –

+0

Можете ли вы поместить Label1 и Label2 вместе в NSView, который будет расти вместе с метками? А потом, но Label3 под NSView? –

ответ

7

Вы просто устанавливаете ограничения между Label3-> Label1 и Label3-> Label2. Использовать неравенство ограничений. Будет только один способ удовлетворить оба!

Вам также потребуется верхнее ограничение для Label3; его constant должен быть очень маленьким, а его priority должен быть очень низким. Это даст двум ограничениям неравенства что-то «нацелиться».

Вот пример. Это, как достигнуто полностью без кода - кнопки имеют код для добавления текста к ярлыкам, конечно, но ограничения полностью настраиваются в Interface Builder; этикетки изменяются, а нижняя метка перемещается вниз, автоматически. (Вы можете построить такое же расположение в коде, если вы хотите, естественно.)

enter image description here

+1

Это не полный ответ, потому что в этом случае нижняя 'label3' по-прежнему будет иметь ограничение Y. Я имею в виду, что установка двух ограничений неравенства не может однозначно идентифицировать фрейм 'label3' – Azat

+0

@Azat. Вы правы, я исправил это. – matt

+0

Также добавлен скринкаст, демонстрирующий, что он работает. – matt

1

Я предлагаю вам обернуть два label топ с до UIView и ограничения установки, так что эти label s приспосабливать все пространство внутри этого view , Затем вы просто добавьте vertical spacing constraint в конец label3 с constant = 10. В этом случае верхний view будет иметь размер больше label и удовлетворит ваши условия

0

Я думал, что это будет интересное занятие, поэтому я создаю небольшой тестовый проект. Суть кода ниже. Вы можете просто скопировать/вставить его в стандартный шаблон Single View iOS.

(Обратите внимание, что я использую SnapKit для программной Auto Layout, потому что это гораздо проще, чем UIKit API. Я считаю, это даже намного проще, чем делать вещи в Xcode.)

Результат точно такой же, как и Мэтт отличный скринкаст.

// ViewController.swift 

import UIKit 
import SnapKit 

class ViewController: UIViewController 
{ 
    override func viewDidLoad() { 
     super.viewDidLoad() 

     let leftLabel = UILabel() 
     leftLabel.addGestureRecognizer(UITapGestureRecognizer(target: self, action: "addText:")) 
     leftLabel.userInteractionEnabled = true 
     view.addSubview(leftLabel) 
     leftLabel.numberOfLines = 0 
     leftLabel.text = "All the world's a stage, and all the men and women merely players: they have their exits and their entrances; and one man in his time plays many parts, his acts being seven ages." 
     leftLabel.snp_makeConstraints { (make) -> Void in 
      make.top.equalTo(40) 
      make.left.equalTo(self.view) 
      make.right.equalTo(self.view.snp_centerX) 
     } 

     let rightLabel = UILabel() 
     rightLabel.addGestureRecognizer(UITapGestureRecognizer(target: self, action: "addText:")) 
     rightLabel.userInteractionEnabled = true 
     view.addSubview(rightLabel) 
     rightLabel.numberOfLines = 0 
     rightLabel.text = "There is a tide in the affairs of men, Which taken at the flood, leads on to fortune. Omitted, all the voyage of their life is bound in shallows and in miseries. On such a full sea are we now afloat. And we must take the current when it serves, or lose our ventures." 
     rightLabel.snp_makeConstraints { (make) -> Void in 
      make.top.equalTo(40) 
      make.right.equalTo(self.view) 
      make.left.equalTo(self.view.snp_centerX) 
     } 

     let bottomView = UIView() 
     view.addSubview(bottomView) 
     bottomView.backgroundColor = UIColor.redColor() 
     bottomView.snp_makeConstraints { (make) -> Void in 
      make.height.equalTo(20) 
      make.left.right.equalTo(self.view) 
      make.top.greaterThanOrEqualTo(leftLabel.snp_bottom) 
      make.top.greaterThanOrEqualTo(rightLabel.snp_bottom) 
     } 
    } 

    @objc func addText(recognizer: UIGestureRecognizer) { 
     if let label = recognizer.view as? UILabel { 
      label.text = label.text! + " I like cheese." 
     } 
    } 
} 

Обновлен код для добавления дополнительного текста к меткам при нажатии.

+0

Я так не думаю. Добавьте функциональность моих кнопок (добавьте текст в каждую из меток поочередно) и посмотрите, продолжает ли ваш «нижний вид» правильно подчиняться. – matt

+0

Работает отлично @matt ... См. Мой обновленный пример, который добавляет текст ярлыкам при нажатии на них. Любопытно, почему ты думаешь, что это не так? –

+0

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

0

В первую очередь высоты удалить ограничений и установить все 3 этикетки вертикальной Содержание Приоритет Прочность на сжатие до 1000. Это самая важная часть.

Затем добавьте вертикальное пространство от Label3 к Label 1 и установите вместо Equal, Greater Than или Equal с приоритетом 500. Добавьте такое же ограничение пространства в Label2.

Последняя добавить ограничение из LABEL3 в Top = 0, но установить приоритет 1.