Ограничения программно не работают так же, как ограничения в раскадровке.

Я пытаюсь использовать автоматический макет программно, чтобы мой пользовательский вид адаптировал свой размер при изменении границ. Чего я пытаюсь добиться:
1) сделать вид на экране максимально большим, но сохранить соотношение сторон между его высотой и размером 8/5
2) никогда не выходить за пределы безопасной зоны
3) всегда оставайтесь посередине
Когда я использую этот набор ограничений в раскадровке, все работает отлично, но когда я делаю то же самое в коде, xcode нарушает мое ограничение по высоте (которое я использую для соотношения сторон для представления). Я играл с приоритетами, но безуспешно. Что я делаю не так? Вот мой код и скриншот моих ограничений раскадровки:

скриншот ограничений раскадровки

private func setupLayout () {

    playingCardView.translatesAutoresizingMaskIntoConstraints = false

    //makes the maxim width possible
    let playingCardViewWidthConstraint = playingCardView.widthAnchor.constraint(equalToConstant: 800)
    playingCardViewWidthConstraint.priority = UILayoutPriority(rawValue: 250)
    playingCardViewWidthConstraint.identifier = "width"

    //for aspect ratio
    let playingCardViewHeightConstraint = playingCardView.heightAnchor.constraint(equalTo: playingCardView.widthAnchor, multiplier: 8.0/5.0)
    playingCardViewHeightConstraint.identifier = "height"

    //make the view stay within bounds
    //add some padding top
    let playingCardTopConstraint = playingCardView.topAnchor.constraint(lessThanOrEqualTo: view.safeAreaLayoutGuide.topAnchor, constant: Constants.offsetFromTheEdge)

    //add some padding bottom
    let plaingCardViewBottomConstraint = playingCardView.bottomAnchor.constraint(lessThanOrEqualTo: view.safeAreaLayoutGuide.bottomAnchor, constant: Constants.offsetFromTheEdge)

    //add some padding leading
    let playingCardViewLeadingConstraint = playingCardView.leadingAnchor.constraint(lessThanOrEqualTo: view.layoutMarginsGuide.leadingAnchor, constant: Constants.offsetFromTheEdge)

    ////add some padding trailing
    let playingCardViewTrailingConstraint = playingCardView.trailingAnchor.constraint(lessThanOrEqualTo: view.layoutMarginsGuide.trailingAnchor, constant: Constants.offsetFromTheEdge)

    NSLayoutConstraint.activate([
        playingCardViewWidthConstraint,
        playingCardViewHeightConstraint,
        playingCardView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
        playingCardView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
        playingCardTopConstraint,
        playingCardViewBottomConstraint,
        playingCardViewLeadingConstraint,
        playingCardViewTrailingConstraint
            ])
    }
}

person Ana Viktoriv    schedule 20.10.2018    source источник
comment
Изучили ли вы какую-либо из своих настроек с помощью инструмент отладки просмотра иерархии?   -  person Paul Patterson    schedule 22.10.2018
comment
@PaulPatterson Да, я сделал. Xcode нарушает мое ограничение по высоте и вместо этого добавляет новое с соотношением сторон 1,6. Проблема в том, что я только учусь программировать, поэтому есть вероятность, что я упущу что-то важное.   -  person Ana Viktoriv    schedule 22.10.2018


Ответы (2)


Когда дело доходит до ограничений, вам нужно подумать о 4 вещах

x => ведущий / замыкающий / левый / правый / центрX

y => верх, низ, центрY

ширина => статическая/пропорциональная

высота => статическая/пропорциональная

Я думаю, здесь вы запускаете все возможные конфликты вне зависимости от приоритетов.

вы даете представление шириной 800 и даете ему начало и конец, что наверняка меньше, чем это, как??

вы задаете соотношение сторон вида и зацепляете его сверху и снизу, как??

вы даете ведущую и конечную и дает centerX, почему??

вы даете верх и низ и даете centerY , Почему??

Не добавляйте ограничение, если оно не добавит никакой ценности

person Sh_Khan    schedule 20.10.2018
comment
чего я действительно не понимаю, так это почему это работает, когда мы добавляем этот набор ограничений в раскадровку без ошибок? (Я использую логику из курса Стэндфордского университета) Почему одна и та же логика дает разные результаты? - person Ana Viktoriv; 20.10.2018

В вашем опубликованном коде...

Вам не хватает y в let plaingCardViewBottomConstraint = ...

Помимо этого, вы устанавливаете для верхних и нижних ограничений значение view.safeAreaLayoutGuide, а для ведущих и конечных ограничений вы устанавливаете значение layoutMarginsGuide.

Измените view.layoutMarginsGuide на view.safeAreaLayoutGuide, и вы получите то, что ожидаете.

person DonMag    schedule 22.10.2018