Где добавить код ограничения автоматической компоновки в пользовательский UIView

Я часто вижу ограничения Auto-Layout, добавляемые в UIViewController, но для меня это кажется неправильным местом для логики компоновки.

Можно ли добавить NSLayoutConstraint в пользовательский UIView?

Где в UIView есть подходящее место для их добавления программно?

Ответы

Ответ 1

Можно ли добавлять NSLayoutConstraints в пользовательский UIView?

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

Прочитайте раздел подкласса от Apple Справочный документ UIView

Ограничения:

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

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

alignmentRectForFrame:, frameForAlignmentRect: - Внедрить эти методы переопределения того, как ваши представления совпадают с другими представлениями.

Где в UIView есть правильное место для их добавления программно?

Вот схема скелета пользовательского класса. Основная проблема заключается в том, что вы централизуете свои ограничения, иначе класс станет очень грязным, чем больше ограничений вы добавите. Также вы можете ввести другие параметры в методе updateConstraints() и условно добавить или удалить ограничения, установив свои значения конфигурации, а затем вызовите setNeedsUpdateConstraints().

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

Надеюсь, что это поможет:)

class MyCustomView: UIView {

    private var didSetupConstraints = false
    private let myLabel = UILabel(frame: CGRectZero)

    // MARK: Lifecycle
    override init(frame: CGRect) {
        super.init(frame: CGRectZero)
        self.setup()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.setup()
    }


    // Mark: - Setup
    private func setup() {

        // 1. Setup the properties of the view it self
        self.translatesAutoresizingMaskIntoConstraints = false
        backgroundColor = UIColor.orangeColor()
        clipsToBounds = true

        // 2. Setup your subviews
        setupMyLabel()

        // 3. Inform the contraints engine to update the constraints
        self.setNeedsUpdateConstraints()
    }


    private func setupMyLabel() {

        myLabel.translatesAutoresizingMaskIntoConstraints = false

    }


    override func updateConstraints() {
        super.updateConstraints()

        if didSetupConstraints == false {
            addConstraintsForMyLabel()
        }
    }

    private func addConstraintsForMyLabel() {

        // Add your constraints here
    }

}

Ответ 2

Мне нравится настраивать код AutoLayout в представлениях, когда это имеет смысл. Я также обнаружил, что проще всего установить все ограничения в одном месте как часть инициализации customView.

import UIKit

class customView:UIView
{
    var customLabel:UILabel = UILabel()

    override init(frame: CGRect) {
        super.init(frame: frame)
        self.setupUI()
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    func setupUI()
    {
        // Setup UI
        self.customLabel.translatesAutoresizingMaskIntoConstraints = false
        self.addSubview(customLabel)

        // Setup Constraints
        self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-10-[customLabel]|", options: NSLayoutFormatOptions.init(rawValue: 0), metrics: nil, views: ["customLabel":self.customLabel]))
        self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-10-[customLabel]-10-|", options: NSLayoutFormatOptions.init(rawValue: 0), metrics: nil, views: ["customLabel":self.customLabel]))
    }
}