Подпредставления UIStackView имеют внутренний размер c, но при этом игнорируют приоритеты захвата контента. - PullRequest
0 голосов
/ 10 июля 2020

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

class ShelfVC: UIViewController {

    let shelfContentView = UIStackView()
    
    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(shelfContentView)
        shelfContentView.translatesAutoresizingMaskIntoConstraints = false
        shelfContentView.layoutEqualTo(view: view)
        shelfContentView.spacing = 16

        shelfContentView.isLayoutMarginsRelativeArrangement = true
        let shelfMargin = CGFloat(16)
        shelfContentView.directionalLayoutMargins = NSDirectionalEdgeInsets(top: shelfMargin, leading: shelfMargin, bottom: shelfMargin, trailing: shelfMargin)
        
        createTestBlocks()
    }

    func createTestBlocks() {

            let view1 = UIView()
            shelfContentView.addArrangedSubview(view1)
            view1.widthAnchor.constraint(equalToConstant: 100).isActive = true
            view1.backgroundColor = .systemRed
            view1.setContentHuggingPriority(.defaultHigh, for: .horizontal)

            let view2 = UIView()
            shelfContentView.addArrangedSubview(view2)
            view2.widthAnchor.constraint(equalToConstant: 100).isActive = true
            view2.backgroundColor = .systemPurple
            view2.setContentHuggingPriority(.defaultLow, for: .horizontal)
            
            let view3 = UIView( )
            shelfContentView.addArrangedSubview(view3)
            view3.widthAnchor.constraint(equalToConstant: 100).isActive = true
            view3.backgroundColor = .systemBlue
            view3.setContentHuggingPriority(.defaultHigh, for: .horizontal)
    }
}

Я ожидал увидеть это:

enter image description here

But instead, I see this:

введите описание изображения здесь

Почему синий вид растягивается, когда приоритет объятия выше, чем фиолетовый?

Ответы [ 2 ]

0 голосов
/ 10 июля 2020

Приоритет обнимания содержимого отличается от приоритета ограничения, и ограничения не определяют внутреннее c Размер содержимого.

Приоритет обнимания содержимого (и сопротивление сжатию содержимого) основан на Внутреннем c размер содержимого.

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

У вас есть два варианта:

  • указать ограничения разные приоритеты
  • дают представлениям внутренний c размер содержимого и устанавливают объятия приоритет

Здесь это первый пример:

class ConstraintHuggingShelfVC: UIViewController {
    
    let shelfContentView = UIStackView()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.addSubview(shelfContentView)
        shelfContentView.translatesAutoresizingMaskIntoConstraints = false
        
        NSLayoutConstraint.activate([
            
            shelfContentView.topAnchor.constraint(equalTo: view.topAnchor, constant: 0.0),
            shelfContentView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0.0),
            shelfContentView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 0.0),
            shelfContentView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0.0),
            
        ])
        
        //shelfContentView.layoutEqualTo(view: view)
        shelfContentView.spacing = 16
        
        shelfContentView.isLayoutMarginsRelativeArrangement = true
        let shelfMargin = CGFloat(16)
        shelfContentView.directionalLayoutMargins = NSDirectionalEdgeInsets(top: shelfMargin, leading: shelfMargin, bottom: shelfMargin, trailing: shelfMargin)
        
        createTestBlocks()
    }
    
    func createTestBlocks() {
        
        let view1 = UIView()
        shelfContentView.addArrangedSubview(view1)
        view1.backgroundColor = .systemRed

        let wc1 = view1.widthAnchor.constraint(equalToConstant: 100)
        wc1.isActive = true
        wc1.priority = .defaultHigh

        let view2 = UIView()
        shelfContentView.addArrangedSubview(view2)
        view2.backgroundColor = .systemPurple

        let wc2 = view2.widthAnchor.constraint(equalToConstant: 100)
        wc2.isActive = true
        wc2.priority = .defaultLow

        let view3 = UIView( )
        shelfContentView.addArrangedSubview(view3)
        view3.backgroundColor = .systemBlue
        
        let wc3 = view3.widthAnchor.constraint(equalToConstant: 100)
        wc3.isActive = true
        wc3.priority = .defaultHigh
        
    }
}

, а вот второй пример:

class IntrinsicView: UIView {
    var myIntrinsicSize: CGSize = .zero
    override var intrinsicContentSize: CGSize {
        return myIntrinsicSize
    }
}

class IntrisicSizeShelfVC: UIViewController {
    
    let shelfContentView = UIStackView()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.addSubview(shelfContentView)
        shelfContentView.translatesAutoresizingMaskIntoConstraints = false
        
        NSLayoutConstraint.activate([
            
            shelfContentView.topAnchor.constraint(equalTo: view.topAnchor, constant: 0.0),
            shelfContentView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0.0),
            shelfContentView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 0.0),
            shelfContentView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0.0),
            
        ])

//      shelfContentView.layoutEqualTo(view: view)
        shelfContentView.spacing = 16
        
        shelfContentView.isLayoutMarginsRelativeArrangement = true
        let shelfMargin = CGFloat(16)
        shelfContentView.directionalLayoutMargins = NSDirectionalEdgeInsets(top: shelfMargin, leading: shelfMargin, bottom: shelfMargin, trailing: shelfMargin)
        
        createTestBlocks()
    }
    
    func createTestBlocks() {
        
        let view1 = IntrinsicView()
        shelfContentView.addArrangedSubview(view1)
        view1.backgroundColor = .systemRed

        view1.myIntrinsicSize = CGSize(width: 100, height: 0)
        view1.setContentHuggingPriority(.defaultHigh, for: .horizontal)
        
        let view2 = IntrinsicView()
        shelfContentView.addArrangedSubview(view2)
        view2.backgroundColor = .systemPurple

        view2.myIntrinsicSize = CGSize(width: 100, height: 0)
        view2.setContentHuggingPriority(.defaultLow, for: .horizontal)
        
        let view3 = IntrinsicView( )
        shelfContentView.addArrangedSubview(view3)
        view3.backgroundColor = .systemBlue

        view3.myIntrinsicSize = CGSize(width: 100, height: 0)
        view3.setContentHuggingPriority(.defaultHigh, for: .horizontal)
    }
}

Оба создают идентичный макет:

введите описание изображения здесь

0 голосов
/ 10 июля 2020

UIStackView сжимается и расширяется с использованием .fill в зависимости от приоритета сжатия содержимого, если упорядоченные подвиды не заполняют представление стека. Таким образом, попробуйте изменить setContentHuggingPriority на setContentCompressionResistancePriority.

См. https://developer.apple.com/documentation/uikit/uistackview/distribution/fill для получения дополнительной информации о свойстве UIStackView.Distribution.fill.

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