简体   繁体   English

UIStackView 的子视图具有固有大小,但仍然忽略内容拥抱优先级

[英]UIStackView's subviews have intrinsic size, yet still ignore content hugging priorities

I'm trying to programmatically create a stack view with a fill distribution that allows me to choose which subview stretches to fill the extra space, but so far I can't seem to control which view is expanding.我正在尝试以编程方式创建一个带有填充分布的堆栈视图,它允许我选择哪些子视图拉伸以填充额外的空间,但到目前为止我似乎无法控制哪个视图正在扩展。

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)
    }
}

I'm expecting to see this:我期待看到这个:

在此处输入图像描述

But instead, I see this:但相反,我看到了这个:

在此处输入图像描述

Why does the blue view stretch when it's hugging priority is higher than the purple view?当拥抱优先级高于紫色视图时,为什么蓝色视图会拉伸?

UIStackView shrinks and expands using .fill based on the content compression priority if the arranged subviews don't fill the stack view.如果排列的子视图未填充堆栈视图,则.fill根据内容压缩优先级使用UIStackView收缩和扩展。 Thus, try changing setContentHuggingPriority to setContentCompressionResistancePriority .因此,尝试将setContentHuggingPriority更改为setContentCompressionResistancePriority

See https://developer.apple.com/documentation/uikit/uistackview/distribution/fill for more information on the UIStackView.Distribution.fill property.有关UIStackView.Distribution.fill属性的更多信息,请参阅https://developer.apple.com/documentation/uikit/uistackview/distribution/fill

Content Hugging Priority is not the same as Constraint Priority, and Constraints do not define Intrinsic Content Size.内容拥抱优先级与约束优先级不同,约束不定义内在内容大小。

Content Hugging (and Content Compression Resistance) Priority is based on Intrinsic content size.内容拥抱(和内容压缩阻力)优先级基于内在内容大小。

You've given each view a Width constraint, and your stack view is using that to begin the arrangement.您已为每个视图提供了一个宽度约束,并且您的堆栈视图正在使用它来开始排列。 It then breaks one of the constraints because it cannot satisfy all of them.然后它打破了其中一个约束,因为它不能满足所有这些约束。

You have two options:你有两个选择:

  • give the constraints different priorities约束不同的优先级
  • give the views an intrinsic content size and set Hugging priority给视图一个内在的内容大小并设置拥抱优先级

Here is the first example:这是第一个例子:

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
        
    }
}

and here's the second example:这是第二个例子:

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)
    }
}

Both produce the identical layout:两者都产生相同的布局:

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 没有内在内容大小的 UIViews 的拥抱/压缩? - Hugging/compression for UIViews without intrinsic content size? 如何用视觉语言格式编写内容大小优先级的内容? - How to write content hugging priority of intrinsic size in visual language format? 带有大小类的UIStackView子视图 - UIStackView subviews with size classes UIStackView 内容拥抱在 UITableViewCell 中无法按预期工作 - UIStackView content hugging is not working as expected in UITableViewCell UIStackView 中标签的内容拥抱和压缩问题设置 - Trouble settings content hugging and compression for labels in UIStackView UITableviewCell中UIImageView的固有内容大小 - UIImageView's intrinsic content size in UITableviewCell 在屏幕上显示之前确定 UIStackView 的固有大小 - determining the intrinsic size of a UIStackView before display on the screen 内容拥抱优先级不适用于 UIStackView 中的自定义视图和 label - Content hugging priority not working with custom view and label in UIStackView 修复了UIStackview子视图的高度约束 - Fixed Height Constraints for UIStackview's subviews iOS 13 测试版中 WKWebView 的内在内容大小问题 - WKWebView's Intrinsic Content Size issue in iOS 13 beta
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM