【发布时间】:2020-11-15 19:37:43
【问题描述】:
我正在以编程方式在 UITableViewCell 内创建 UIStackView。 StackView 包含 3 个消息气球,由容器 UIView、UIImageView 和 UILabel 组成。
我试图使容器视图的高度大于图像视图,因为它应该在 UIImageView 之上包含更多元素,但高度被削减到 UIImageView 的高度,并且控制台显示Unable to simultaneously satisfy constraints。
从this answer 获得建议我将 UIImageView 的 translateAutoResizingMAskIntoConstraints 设置为 false,所以现在容器视图确实比图像视图高,但图像视图的宽度不适合 UILabel。
代码:
import UIKit
import PureLayout
@objc class ChatCell: UITableViewCell {
@IBOutlet weak var view: UIView!
@IBOutlet weak var headerView: UIView!
@IBOutlet weak var showMoreButton: UIButton!
override func awakeFromNib() {
super.awakeFromNib()
// stack view
let stackView = UIStackView()
stackView.axis = NSLayoutConstraint.Axis.vertical
stackView.distribution = UIStackView.Distribution.equalSpacing
stackView.alignment = UIStackView.Alignment.center
stackView.spacing = 16.0
stackView.translatesAutoresizingMaskIntoConstraints = false
// bubble colors
var colors = [UIColor]()
colors.append(UIColor(red: 30/255, green: 222/255, blue: 38/255, alpha: 1))
colors.append(UIColor(red: 20/255, green: 80/255, blue: 210/255, alpha: 1))
colors.append(UIColor(red: 150/255, green: 120/255, blue: 30/255, alpha: 1))
for color in colors {
stackView.addArrangedSubview(addMessage(color: color, text: "לורם איפסום דולור סיט אמט, קונסקטורר אדיפיסינג אלית קולורס מרגשי ומרגשח. עמחליף לורם איפסום דולור סיט אמט, קונסקטורר אדיפיסינג אלית. סת אלמנקום ניסי נון ניבאה."))
}
view.addSubview(stackView)
stackView.autoPinEdge(.top, to: .bottom, of: headerView, withOffset: 30)
stackView.autoPinEdge(.bottom, to: .top, of: showMoreButton, withOffset: -30)
stackView.autoCenterInSuperview()
}
func addMessage(color: UIColor, text: String) -> UIView {
let containerView = UIView(frame: .zero)
let label = UILabel()
var messageView = UIImageView()
setText(label, text)
setTextBubble(label, &messageView, color)
containerView.addSubview(messageView)
containerView.translatesAutoresizingMaskIntoConstraints = false
containerView.autoMatch(.width, to: .width, of: messageView)
containerView.autoPinEdge(.bottom, to: .bottom, of: messageView)
containerView.autoPinEdge(.top, to: .top, of: messageView, withOffset: -20)
containerView.autoAlignAxis(.horizontal, toSameAxisOf: messageView)
containerView.backgroundColor = .red
label.center = messageView.center
containerView.addSubview(label)
view.addSubview(containerView)
return containerView
}
fileprivate func setText(_ label: UILabel, _ text: String) {
label.numberOfLines = 2
label.font = UIFont.init(name: "South-Light", size: 18)
label.textColor = .white
label.text = text
label.textAlignment = NSTextAlignment.right
// set text frame
let TEXT_FRAME_HEIGHT = 60.0
let constraintRect = CGSize(width: 0.66 * Double(view.frame.width), height: TEXT_FRAME_HEIGHT)
let boundingBox = text.boundingRect(with: constraintRect,
options: .usesLineFragmentOrigin,
attributes: [.font: label.font],
context: nil)
label.frame.size = CGSize(width:ceil(boundingBox.width),
height: ceil(boundingBox.height))
}
fileprivate func setTextBubble(_ label: UILabel, _ messageView: inout UIImageView, _ color: UIColor) {
// set text bubble
let bubbleImageSize = CGSize(width: label.frame.width + 28,
height: label.frame.height + 20)
messageView = UIImageView(frame:
CGRect(x: 0,
y: 0,//view.frame.height - bubbleImageSize.height - 5,
width: bubbleImageSize.width,
height: bubbleImageSize.height))
let bubbleImage = UIImage(named: "incoming-message-bubble")?
.resizableImage(withCapInsets: UIEdgeInsets(top: 17, left: 21,
bottom: 17, right: 21), resizingMode: .stretch)
.withRenderingMode(UIImage.RenderingMode.alwaysTemplate)
messageView.image = bubbleImage
messageView.tintColor = color
// this line changes layout
messageView.translatesAutoresizingMaskIntoConstraints = false
}
}
控制台日志:
2020-07-26 13:13:54.040496+0300 Sport5[10267:1581233] [LayoutConstraints] Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want.
(1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
"<NSLayoutConstraint:0x2801c7570 V:[UIImageView:0x155dc1dd0]-(0)-| (active, names: '|':UIView:0x155dc0570 )>",
"<NSLayoutConstraint:0x2801c75c0 UIView:0x155dc0570.top == UIImageView:0x155dc1dd0.top - 20 (active)>",
"<NSLayoutConstraint:0x2801c7610 UIView:0x155dc0570.centerY == UIImageView:0x155dc1dd0.centerY (active)>"
ng constraint
<NSLayoutConstraint:0x2801c7610 UIView:0x155dc0570.centerY == UIImageView:0x155dc1dd0.centerY (active)>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
2020-07-26 13:13:54.041636+0300 Sport5[10267:1581233] [LayoutConstraints] Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want.
(1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
"<NSLayoutConstraint:0x2801c77f0 V:[UIImageView:0x155dc27d0]-(0)-| (active, names: '|':UIView:0x155dc3410 )>",
NSLayoutConstraint:0x2801c7840 UIView:0x155dc3410.top == UIImageView:0x155dc27d0.top - 20 (active)>",
"<NSLayoutConstraint:0x2801c7890 UIView:0x155dc3410.centerY == UIImageView:0x155dc27d0.centerY (active)>"
ng constraint
<NSLayoutConstraint:0x2801c7890 UIView:0x155dc3410.centerY == UIImageView:0x155dc27d0.centerY (active)>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
2020-07-26 13:13:54.042503+0300 Sport5[10267:1581233] [LayoutConstraints] Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want.
(1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
"<NSLayoutConstraint:0x2801c7a70 V:[UIImageView:0x155dc40c0]-(0)-| (active, names: '|':UIView:0x155dc3b00 )>",
"<NSLayoutConstraint:0x2801c7ac0 UIView:0x155dc3b00.top == UIImageView:0x155dc40c0.top - 20 (active)>",
"<NSLayoutConstraint:0x2801c7b10 UIView:0x155dc3b00.centerY == UIImageView:0x155dc40c0.centerY (active)>"
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x2801c7b10 UIView:0x155dc3b00.centerY == UIImageView:0x155dc40c0.centerY (active)>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
2020-07-26 13:13:58.655384+0300 Sport5[10267:1581233] [LayoutConstraints] Window has a view with an ambiguous layout. See "Auto Layout Guide: Ambiguous Layouts" for help debugging. Displaying synopsis from invoking -[UIView _autolayoutTrace] to provide additional detail.
+ - is laid out manually, but is represented in the layout engine because translatesAutoresizingMaskIntoConstraints = YES
2020-07-26 13:13:58.849727+0300 Sport5[10267:1581233] [LayoutConstraints] View has an ambiguous layout. See "Auto Layout Guide: Ambiguous Layouts" for help debugging. Displaying synopsis from invoking -[UIView _autolayoutTrace] to provide additional detail.
+ - is laid out manually, but is represented in the layout engine because translatesAutoresizingMaskIntoConstraints = YES
2020-07-26 13:13:58.855433+0300 Sport5[10267:1581233] [LayoutConstraints] View has an ambiguous layout. See "Auto Layout Guide: Ambiguous Layouts" for help debugging. Displaying synopsis from invoking -[UIView _autolayoutTrace] to provide additional detail.
+ - is laid out manually, but is represented in the layout engine because translatesAutoresizingMaskIntoConstraints = YES
2020-07-26 13:13:58.865918+0300 Sport5[10267:1581233] [LayoutConstraints] View has an ambiguous layout. See "Auto Layout Guide: Ambiguous Layouts" for help debugging. Displaying synopsis from invoking -[UIView _autolayoutTrace] to provide additional detail.
+ - is laid out manually, but is represented in the layout engine because translatesAutoresizingMaskIntoConstraints = YES ```
【问题讨论】: