我在UIStackView(垂直)中有一个UIStackView(水平)addArrangedSubview。
水平视图有3个单元格:第一个是带有UILabel的addArrangedSubview,第二个有UIImageView(宽度和高度常量约束以保持我想要的大小)。第三个单元格是带有UILabel的addArrangedSubview。 我希望UIStackView适合整个屏幕宽度
不幸的是,结果如下:
我的代码如下:
let sv = UIStackView()
sv.axis = .horizontal
sv.alignment = .center
sv.distribution = .fill
sv.spacing = 10
// Name
var label = UILabel()
label.numberOfLines = 0
label.textAlignment = .natural
label.text = poi.name
label.font = UIFont.preferredFont(forTextStyle: .title1)
sv.addArrangedSubview(label)
// Open/closed
let open = true
let _ = addImageView(open ? #imageLiteral(resourceName: "Open") : #imageLiteral(resourceName: "Closed"), to: sv)
// Stars
let maxRank = 5
let rank = 3
label = UILabel()
label.numberOfLines = 0
label.textAlignment = .natural
label.text = "".padding(right: rank, withPad: "★").padding(right: maxRank-rank, withPad: "☆")
sv.addArrangedSubview(label)
verticalStackView.addArrangedSubview(sv)
我的工具功能如下:
let w: CGFloat = 32.0
let r = CGRect(x: 0, y: 0, width: w, height: w)
func addImageView(_ image: UIImage, to sv: UIStackView) {
let iv = UIImageView()
iv.contentMode = .scaleAspectFit
iv.image = image
//iv.translatesAutoresizingMaskIntoConstraints = true
let constraints = [
iv.widthAnchor .constraint(equalToConstant: w),
iv.heightAnchor.constraint(equalToConstant: w)
]
//let _ = constraints.map { $0.priority = .defaultHigh }
NSLayoutConstraint.activate(constraints)
/*
iv.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 1000.0), for: .horizontal)
iv.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 1000.0), for: .vertical)
*/
if true {
sv.addArrangedSubview(iv)
} else {
let v = UIView()
v.layer.borderColor = UIColor.red.cgColor
v.layer.borderWidth = 1
v.addSubview(iv)
sv.addArrangedSubview(v)
}
}
注1:我做了一些实验,因此注释了代码。
注意2:屏幕截图上的红色条是我的手绘图,以便于理解细胞的布局。
[UPDATE]
为了清理事情,弄乱了一切,是我添加到UIImageView的约束,没有一个,一切都好。我添加约束的原因是保持UIImageView的平方和正确的尺寸。 出于这个原因,我添加了一个UIView作为中间元素,以吸收UIStackView约束设置到内部元素的强度(因此if false代码)。但后来我需要在UIView中添加额外的约束来使UIImageView居中,这听起来有点过度使用了布局系统。当然 我可能错过了一些简化整个事情的东西。
答案 0 :(得分:0)
感谢, Ĵ
答案 1 :(得分:0)
我终于解决了这个问题:我将阻力压缩优先级更改为.required标签和UIImageView:
label.setContentCompressionResistancePriority(UILayoutPriority.required, for: .horizontal)
现在,相同的代码片段如下:
// Name
var label = UILabel()
label.numberOfLines = 0
label.textAlignment = .natural
label.text = poi.name
label.font = UIFont.preferredFont(forTextStyle: .title1)
label.setContentCompressionResistancePriority(UILayoutPriority.required, for: .horizontal)
sv.addArrangedSubview(label)
// Open/closed
let open = true
let _ = addImageView(open ? #imageLiteral(resourceName: "Open") : #imageLiteral(resourceName: "Closed"), to: sv)
// Stars
let maxRank = 5
let rank = 3
label = UILabel()
label.numberOfLines = 0
label.textAlignment = .natural
label.text = "".padding(right: rank, withPad: "★").padding(right: maxRank-rank, withPad: "☆")
label.setContentCompressionResistancePriority(UILayoutPriority.required, for: .horizontal)
sv.addArrangedSubview(label)
verticalStackView.addArrangedSubview(sv)
和
func addImageView(_ image: UIImage, to sv: UIStackView) {
let iv = UIImageView()
iv.contentMode = .scaleAspectFit
iv.image = image
NSLayoutConstraint.activate([
iv.widthAnchor .constraint(equalToConstant: w),
iv.heightAnchor.constraint(equalToConstant: w)
])
iv.setContentCompressionResistancePriority(UILayoutPriority.required, for: .horizontal)
iv.setContentCompressionResistancePriority(UILayoutPriority.required, for: .vertical)
sv.addArrangedSubview(iv)
}