Отказаться от автоматического макета для одного представления?

У меня есть представление, которое выполняет компоновку своих подпредставлений в коде. Макет слишком сложен для автоматического макета, а автоматический макет ломает код макета. Есть ли способ заставить автоматическую компоновку оставить только подвиды этого представления? Я пытался переопределить layoutSubviews, но безуспешно.

Спасибо за любую помощь.


person Dan Wesnor    schedule 08.10.2012    source источник


Ответы (3)


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

person Scott Berrevoets    schedule 08.10.2012
comment
Помещение его в собственный NIB кажется единственным решением. - person Dan Wesnor; 17.10.2012
comment
Да, это отстой, вы не можете включить или выключить его для каждой сцены. - person Flea; 19.07.2013
comment
Вы можете размещать подпредставления вручную (т.е. устанавливать их фреймы) для данного представления, если вы делаете это после работы механизма автоматической компоновки с ними (см. мой ответ ниже) . - person wcochran; 23.01.2016

Нашел ответ в видеороликах WWDC. layoutSubviews не работает с автоматической компоновкой так же, как раньше. Это не останавливает автоматическую компоновку, а скорее дает возможность добавлять/изменять/удалять ограничения во время компоновки.

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

person Dan Wesnor    schedule 17.10.2012

Вы можете верстка и ручная верстка!

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

class MyView : UIView {

    //
    // mySubview is not involved in any constraints 
    // that would trigger another layout pass.
    // e.g., no explicit constraints set in IB.
    // 
    @IBOutlet weak var mySubview: UIView!

    override func layoutSubviews() {
       super.layoutSubviews()  // let auto layout engine run first

       //
       // Auto layout engine now done with this view so we can
       // set the frames how ever we wish since we have the last
       // word! 
       //
       mySubview.frame  = CGRectMake(...)
       ...

    }

}

Причина, по которой это работает, заключается в том, что после вызова super.layoutSubviews() изменение фреймов в любых подпредставлениях не запускает другой проход компоновки (все ограничения, связанные с подпредставлениями, выполняются, и с ними выполняется механизм автоматической компоновки); поэтому этот метод получает последнее слово о позиции своих подпредставлений!

  • Обратите внимание, что экземпляры MyView могут иметь связанные ограничения автоматической разметки, и все работает нормально.

  • IB не выдает никаких предупреждений, пока вы не устанавливаете какие-либо ограничения для подпредставлений.

person wcochran    schedule 23.01.2016
comment
В macOS метод создания подкласса будет layout. - person Demitri; 14.06.2016