如何解决设置 centerXAnchor 的 UITableViewCell 自动布局问题
我正在尝试构建消息传递界面并遇到了这个问题。由于这是消息传递应用程序,因此消息气泡会对齐前导或尾随。我想做这种事情,创建一个名为 bubbleView
的子视图,它将使用一个名为 bubbleViewCenterXConstraintValue
的计算变量来对齐自己。
override var frame: CGRect {
didSet {
print(frame,bubbleView.frame)
self.setNeedsLayout()
}
}
private var bubbleViewCenterXConstraintValue: CGFloat {
print(UIScreen.main.bounds.width,contentView.frame.width,bubbleView.frame.width,((UIScreen.main.bounds.width - bubbleView.bounds.width) / 2))
return ((UIScreen.main.bounds.width - bubbleView.bounds.width) / 2)
}
override init(style: UITableViewCell.CellStyle,reuseIdentifier: String?) {
super.init(style: style,reuseIdentifier: reuseIdentifier)
backgroundColor = .clear
contentView.backgroundColor = .systemteal
bubbleView.addSubviews(messageLabel,hourLabel)
messageLabel.leadingAnchor.constraint(equalTo: bubbleView.leadingAnchor,constant: 12).isActive = true
messageLabel.trailingAnchor.constraint(equalTo: bubbleView.trailingAnchor,constant: -12).isActive = true
messageLabel.topAnchor.constraint(equalTo: bubbleView.topAnchor,constant: 12).isActive = true
hourLabel.trailingAnchor.constraint(equalTo: messageLabel.trailingAnchor).isActive = true
hourLabel.topAnchor.constraint(equalTo: messageLabel.bottomAnchor,constant: 4).isActive = true
hourLabel.bottomAnchor.constraint(equalTo: bubbleView.bottomAnchor,constant: -12).isActive = true
contentView.addSubview(bubbleView)
bubbleView.topAnchor.constraint(equalTo: contentView.topAnchor,constant: 4).isActive = true
bubbleView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor,constant: -4).isActive = true
bubbleView.centerXAnchor.constraint(equalTo: contentView.centerXAnchor,constant: bubbleViewCenterXConstraintValue).isActive = true
bubbleView.widthAnchor.constraint(lessthanorEqualToConstant: availableMaxWidth).isActive = true
}
但是,每当调用 bubbleViewCenterXConstraintValue
时,bubbleView
的框架为零,因此它错误地计算了我的逻辑。逻辑现在不包括左对齐或右对齐,它只是尝试向右对齐。
当我查看这些打印结果时,我意识到另一件奇怪的事情。 contentView
的宽度为 320,不等于 UIScreen.main.bounds.width(390)
。
(0.0,0.0,320.0,44.0) (0.0,0.0)
390.0 320.0 0.0 195.0
(0.0,390.0,100.66666666666667) (0.0,0.0)
(0.0,100.66666412353516) (243.66666666666666,4.0,292.6666666666667,92.66666666666667)
(0.0,92.66666666666667)
我需要一种方法来使这些自动布局代码在设置 bubbleView
的框架时进行更新。因为我知道如果它的宽度最初是 292,这个代码就可以工作。我尝试了当前无效的解决方案 setNeedsLayout()
并覆盖了 layoutSubviews
,但这也不起作用。
我知道我遗漏了一些东西,解决方案就在那里,但是我现在看不到,需要一些帮助。
提前感谢。
注意:也在网站上找了个解决办法也没找到类似的。如果您认为这是重复的,请随时告诉我或采取行动。
解决方法
我认为更简单的方法是为气泡设置前导和尾随约束。这样可以轻松决定要对齐到屏幕的哪一侧。您还可以为宽度参数使用自动布局,使用基于父视图宽度的乘数来使其适应任何尺寸的屏幕。
我不会将它添加到您的代码中,因为它会太长,但希望下面的示例函数将展示我推荐的原则:
func addBubble(alignLeft: Bool,offset: CGFloat) {
let bubble = UIView()
bubble.backgroundColor = .systemBlue
let parentView = view.safeAreaLayoutGuide //your parent view may be different
parentView.addSubview(bubble)
bubble.translatesAutoresizingMaskIntoConstraints = false
//quick and dirty top and bottom constraints for the example
bubble.topAnchor.constraint(equalTo: parentView.topAnchor,constant: 10 + offset).isActive = true
bubble.bottomAnchor.constraint(equalTo: parentView.topAnchor,constant: 40 + offset).isActive = true
//set the width of the bubble proportional to the size of the parent view
bubble.widthAnchor.constraint(equalTo: parentView.widthAnchor,multiplier: 2/3).isActive = true
// implement the left or right alignment
if alignLeft {
bubble.leadingAnchor.constraint(equalTo: parentView.leadingAnchor,constant: 4).isActive = true
} else {
bubble.trailingAnchor.constraint(equalTo: parentView.trailingAnchor,constant: -4).isActive = true
}
}
这样,您所要做的就是将气泡的子视图锚定到气泡的顶部/底部/前导/尾随约束,并且它们还将随着气泡调整大小以适应所有屏幕尺寸。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。