Swift 带UIImageView的UIStackView不';无法按预期处理约束
我有一个UIStackView(水平)将ArrangedSubView添加到UIStackView(垂直)中 水平视图有3个单元格:第一个是带有UILabel的addArrangedSubview,第二个是UIImageView(具有宽度和高度常量约束以保持我想要的大小)。第三个单元格是带有UILabel的addArrangedSubview。 我希望视图能适应整个屏幕的宽度 不幸的是,结果如下所示:Swift 带UIImageView的UIStackView不';无法按预期处理约束,swift,uiimageview,uistackview,Swift,Uiimageview,Uistackview,我有一个UIStackView(水平)将ArrangedSubView添加到UIStackView(垂直)中 水平视图有3个单元格:第一个是带有UILabel的addArrangedSubview,第二个是UIImageView(具有宽度和高度常量约束以保持我想要的大小)。第三个单元格是带有UILabel的addArrangedSubview。 我希望视图能适应整个屏幕的宽度 不幸的是,结果如下所示: let sv = UIStackView() sv.axis = .horiz
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)
}
}
// 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)
我的代码如下:
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)
}
}
// 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)
我的工具功能如下:
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)
}
}
// 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)
注1:我做了一些实验,因此得到了注释代码
注2:屏幕截图上的红色条是我的手绘,以便于理解细胞的布局
[更新]
为了澄清问题,我在UIImageView中添加了一个约束,但没有任何约束,一切都正常。我添加约束的原因是为了保持UIImageView的平方和正确的尺寸。
出于这个原因,我添加了一个UIView作为中间元素,以吸收UIStackView约束设置到内部元素的强度(因此if-false代码)。但是我需要在UIView中添加额外的约束以使UIImageView居中,这听起来有点过度使用布局系统。当然
我可能错过了一些可以简化整个过程的东西。你能帮我吗
-尝试为根StackView添加约束,尾部、顶部、底部和前导等于常量0。
-尝试使用.fill而不是.center更改根堆栈视图的对齐方式
- 如果要使标签更灵活,请使用比其他属性(251250750)小得多的值(通常为248748)来设置压缩阻力和上下文拥抱属性
J我终于解决了这个问题:我将电阻压缩优先级更改为。标签和UIImageView需要:
label.setContentCompressionResistancePriority(UILayoutPriority.required, for: .horizontal)
现在,相同的代码如下所示:
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)
}
}
// 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)
以及: