Несогласованное поведение автоматической разметки между создателем интерфейса и программно созданными представлениями - PullRequest
0 голосов
/ 20 января 2020

Я пытаюсь программно добавить подпредставление к представлению внутри представления вертикального стека. Он должен попытаться максимизировать свой размер, чтобы заполнить родительское представление, но при этом сохранить соотношение сторон. Я пытаюсь добиться этого, добавив ограничение соотношения сторон с приоритет по умолчанию . И добавьте ограничения сверху, снизу, впереди, трейлинг и centerX, centerY с низким приоритетом . Мой прототип в построителе интерфейсов работает отлично, но когда я перевожу его в коды, интервал на границах отсутствует. Чего-то не хватает в версии программы c? Вот код:

class ViewController: UIViewController {
    @IBOutlet var greenView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()
        let testView = UIView()
        testView.backgroundColor = .red
        greenView.addSubview(testView)

        testView.translatesAutoresizingMaskIntoConstraints = false
        let aspectRatioConstraint = NSLayoutConstraint(item: testView,
                            attribute: .width,
                            relatedBy: .equal,
                            toItem: testView,
                            attribute: .height,
                            multiplier: 6.0 / 10.0,
                            constant: 0)

        let leadingConstraint = NSLayoutConstraint(item: testView,
                                             attribute: .leading,
                                             relatedBy: .equal,
                                             toItem: greenView,
                                             attribute: .leading,
                                             multiplier: 1,
                                             constant: 5)

        let trailingConstraint = NSLayoutConstraint(item: testView,
                                             attribute: .trailing,
                                             relatedBy: .equal,
                                             toItem: greenView,
                                             attribute: .trailing,
                                             multiplier: 1,
                                             constant: 5)

        let topConstraint = NSLayoutConstraint(item: testView,
                                             attribute: .top,
                                             relatedBy: .equal,
                                             toItem: greenView,
                                             attribute: .top,
                                             multiplier: 1,
                                             constant:5)

        let bottomConstraint = NSLayoutConstraint(item: testView,
                                             attribute: .bottom,
                                             relatedBy: .equal,
                                             toItem: greenView,
                                             attribute: .bottom,
                                             multiplier: 1,
                                             constant: 5)

        let centerXConstraint = NSLayoutConstraint(item: testView,
                                             attribute: .centerX,
                                             relatedBy: .equal,
                                             toItem: greenView,
                                             attribute: .centerX,
                                             multiplier: 1,
                                             constant: 0)

        let centerYConstraint = NSLayoutConstraint(item: testView,
                                             attribute: .centerY,
                                             relatedBy: .equal,
                                             toItem: greenView,
                                             attribute: .centerY,
                                             multiplier: 1,
                                             constant: 0)

        leadingConstraint.priority = .defaultLow
        trailingConstraint.priority = .defaultLow
        topConstraint.priority = .defaultLow
        bottomConstraint.priority = .defaultLow
        centerXConstraint.priority = .defaultLow
        centerYConstraint.priority = .defaultLow

        NSLayoutConstraint.activate([aspectRatioConstraint, leadingConstraint, trailingConstraint, topConstraint, bottomConstraint, centerXConstraint, centerYConstraint])

    }
}

Неработающая версия, созданная программно: отсутствуют верхний и нижний интервалы.

enter image description here

ожидаемый вид, построенный с помощью Interface Builder:

built with interface builder

Вот настройки в IB:

here is the setting in IB

1 Ответ

1 голос
/ 20 января 2020

Я думаю, что вы хотите, чтобы использовать greaterThanOrEqual для верхней и ведущей, и lessThanOrEqual для правой и нижней.

Попробуйте это так:

class ThiniumViewController: UIViewController {
    @IBOutlet var greenView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()
        let testView = UIView()
        testView.backgroundColor = .red

        greenView.addSubview(testView)

        testView.translatesAutoresizingMaskIntoConstraints = false

        let tvHeightConstraint = testView.heightAnchor.constraint(equalTo: testView.widthAnchor, multiplier: 10.0 / 6.0)
        tvHeightConstraint.priority = .defaultHigh

        let tvWidthConstraint = testView.widthAnchor.constraint(equalTo: greenView.widthAnchor, multiplier: 1.0)
        tvWidthConstraint.priority = .defaultHigh

        NSLayoutConstraint.activate([

            // center testView in greenView
            testView.centerXAnchor.constraint(equalTo: greenView.centerXAnchor),
            testView.centerYAnchor.constraint(equalTo: greenView.centerYAnchor),

            // constrain top and leading of redView to *at least* 5-points
            testView.topAnchor.constraint(greaterThanOrEqualTo: greenView.topAnchor, constant: 5.0),
            testView.leadingAnchor.constraint(greaterThanOrEqualTo: greenView.leadingAnchor, constant: 5.0),

            // constrain height of testView to width of testView at 10:6 ratio at Priority 750
            tvHeightConstraint,

            // constrain width of testView to width of greenView at Priority 750
            tvWidthConstraint,

            // constrain bottom and trailing of redView to *at least* 5-points
            testView.bottomAnchor.constraint(lessThanOrEqualTo: greenView.bottomAnchor, constant: -5.0),
            testView.trailingAnchor.constraint(lessThanOrEqualTo: greenView.trailingAnchor, constant: -5.0),

        ])

    }
}

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

Результат:

enter image description here

...