swift 使用UIImageView的内容拥抱优先级

cld4siwp  于 2022-11-28  发布在  Swift
关注(0)|答案(1)|浏览(139)

我正在布局一个类似于Twitter的作者布局的UIStackView,如下所示;

然而,我并没有从确定各种优先事项中得到预期的效果;

setContentHuggingPriority(UILayoutPriority(rawValue: 1), for: .horizontal)

UIStackView包含以下项目:
1.显示名称UILabel
1.已验证徽章UIImageView
1.手柄UILabel
1.时间戳UILabel
我正在寻找的功能如下:
1.时间戳和已验证徽章在任何时候都不得缩小。
1.如果UIStackView未填充宽度,则时间戳必须占用剩余空间
1.手柄将首先收缩
1.显示名称将最后缩小
任何帮助都是非常感谢的。

rjee0c15

rjee0c151#

您可以按照您所写的 “我要寻找的功能” 列表进行操作...
1.时间戳和已验证徽章在任何时候都不得缩小。

// don't let Timestamp compress
 timeStampLabel.setContentCompressionResistancePriority(.required, for: .horizontal)

 // don't let "Dot" compress
 dotLabel.setContentCompressionResistancePriority(.required, for: .horizontal)

 // badge image view is square (1:1 ratio)
 //  Width Anchor prevents both compression and expansion
 badgeImageView.widthAnchor.constraint(equalTo: badgeImageView.heightAnchor).isActive = true

1.如果UIStackView未填满宽度,则时间戳必须占用剩余空间

// don't let Display Name, Handle or Dot expand Horizontally
 displayNameLabel.setContentHuggingPriority(.required, for: .horizontal)
 handleLabel.setContentHuggingPriority(.required, for: .horizontal)
 dotLabel.setContentHuggingPriority(.required, for: .horizontal)

1.手柄将首先收缩

// Handle shrink first
 handleLabel.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)

1.显示名称将最后缩小

// Display Name shrink next
 displayNameLabel.setContentCompressionResistancePriority(.defaultLow + 1, for: .horizontal)

1.你没说具体是谁,所以...

// Handle *could* to shrink to "no width"
 //  so use a min-Width to show at least a char or two
 // if you want to allow it to disappear, comment out this line
 handleLabel.widthAnchor.constraint(greaterThanOrEqualToConstant: 24.0).isActive = true

下面是一个完整的例子--它有两个按钮......一个用于循环浏览一些样本数据,另一个用于切换标签的背景颜色以查看它们的框架。stackView被添加到主视图中,但当它在单元格中使用时(我假设是这样),它的工作方式是相同的:

class TwitLineVC: UIViewController {

    let displayNameLabel = UILabel()
    let badgeImageView = UIImageView()
    let handleLabel = UILabel()
    let dotLabel = UILabel()
    let timeStampLabel = UILabel()
    
    let sampleData: [[String]] = [
        ["Stack Overflow", "@StackOverflow", "Nov 13"],
        ["Longer Display Name", "@LongerHandle", "Nov 14"],
        ["Much Longer Display Name", "@ThisHandleWillCompress", "Nov 15"],
        ["Much Longer Display Name Will Also Compress", "@ThisHandleWillCompress", "Nov 16"],
    ]
    var idx: Int = 0
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.backgroundColor = .black
        
        guard let img = UIImage(named: "twcheck") else {
            fatalError("Could not load image!")
        }
        badgeImageView.image = img
        
        let stackView = UIStackView()
        stackView.spacing = 4
        
        stackView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(stackView)
        
        let g = view.safeAreaLayoutGuide
        NSLayoutConstraint.activate([
            stackView.topAnchor.constraint(equalTo: g.topAnchor, constant: 20.0),
            stackView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
            stackView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -20.0),
        ])

        // don't let Display Name, Handle or Dot expand Horizontally
        displayNameLabel.setContentHuggingPriority(.required, for: .horizontal)
        handleLabel.setContentHuggingPriority(.required, for: .horizontal)
        dotLabel.setContentHuggingPriority(.required, for: .horizontal)
        
        // don't let Timestamp compress
        timeStampLabel.setContentCompressionResistancePriority(.required, for: .horizontal)
        
        // don't let "Dot" compress
        dotLabel.setContentCompressionResistancePriority(.required, for: .horizontal)
        
        // badge image view is square (1:1 ratio)
        //  Width Anchor prevents both compression and expansion
        badgeImageView.widthAnchor.constraint(equalTo: badgeImageView.heightAnchor).isActive = true
        
        // Handle shrink first
        handleLabel.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
        
        // Display Name shrink next
        displayNameLabel.setContentCompressionResistancePriority(.defaultLow + 1, for: .horizontal)
        
        // Handle *could* to shrink to "no width"
        //  so use a min-Width to show at least a char or two
        // if you want to allow it to disappear, comment out this line
        handleLabel.widthAnchor.constraint(greaterThanOrEqualToConstant: 24.0).isActive = true
        
        // use Display Name label height to control stack view height
        displayNameLabel.setContentHuggingPriority(.required, for: .vertical)
        
        // add to stack view
        stackView.addArrangedSubview(displayNameLabel)
        stackView.addArrangedSubview(badgeImageView)
        stackView.addArrangedSubview(handleLabel)
        stackView.addArrangedSubview(dotLabel)
        stackView.addArrangedSubview(timeStampLabel)
        
        displayNameLabel.textColor = .white
        handleLabel.textColor = .lightGray
        dotLabel.textColor = .lightGray
        timeStampLabel.textColor = .lightGray

        let fSize: CGFloat = 12.0
        displayNameLabel.font = .systemFont(ofSize: fSize, weight: .bold)
        handleLabel.font = .systemFont(ofSize: fSize, weight: .regular)
        dotLabel.font = handleLabel.font
        timeStampLabel.font = handleLabel.font

        // this never changes
        dotLabel.text = "•"

        // a button to cycle through sample data
        let btn1 = UIButton(type: .system)
        btn1.setTitle("Next Data Set", for: [])
        btn1.addTarget(self, action: #selector(updateData(_:)), for: .touchUpInside)
        btn1.translatesAutoresizingMaskIntoConstraints = false
        
        view.addSubview(btn1)
        
        // a button to toggle background colors
        let btn2 = UIButton(type: .system)
        btn2.setTitle("Toggle Colors", for: [])
        btn2.addTarget(self, action: #selector(toggleColors(_:)), for: .touchUpInside)
        btn2.translatesAutoresizingMaskIntoConstraints = false
        
        view.addSubview(btn2)
        
        NSLayoutConstraint.activate([
            btn1.topAnchor.constraint(equalTo: stackView.bottomAnchor, constant: 40.0),
            btn1.centerXAnchor.constraint(equalTo: g.centerXAnchor),
            btn2.topAnchor.constraint(equalTo: btn1.bottomAnchor, constant: 20.0),
            btn2.centerXAnchor.constraint(equalTo: g.centerXAnchor),
        ])
        
        // fill with the first data set
        updateData(nil)

    }
    
    @objc func updateData(_ sender: Any?) {

        displayNameLabel.text = sampleData[idx % sampleData.count][0]
        handleLabel.text = sampleData[idx % sampleData.count][1]
        timeStampLabel.text = sampleData[idx % sampleData.count][2]

        idx += 1
        
    }
    @objc func toggleColors(_ sender: Any?) {

        if displayNameLabel.backgroundColor == .clear {
            displayNameLabel.backgroundColor = .systemGreen
            handleLabel.backgroundColor = .systemBlue
            dotLabel.backgroundColor = .systemYellow
            timeStampLabel.backgroundColor = .systemRed
        } else {
            displayNameLabel.backgroundColor = .clear
            handleLabel.backgroundColor = .clear
            dotLabel.backgroundColor = .clear
            timeStampLabel.backgroundColor = .clear
        }
        
    }
}

相关问题