繁体   English   中英

UIStackView内的NSLayout约束无法同时满足约束

[英]NSLayout Constraint inside UIStackView Unable to simultaneously satisfy constraints

我正在以编程方式在 UITableViewCell 内创建 UIStackView。 StackView 包含 3 个消息气球,由容器 UIView、UIImageView 和 UILabel 组成。 我正在尝试使容器视图的高度大于图像视图,因为它应该在 UIImageView 的顶部包含更多元素,但高度降低到 UIImageView 的高度,并且控制台显示Unable to simultaneously satisfy constraints . 这个答案中获得建议我将 UIImageView 的 translateAutoResizingMAskIntoConstraints 设置为 false,所以现在容器视图确实比图像视图高,但图像视图的宽度不适合 UILabel。

messageView.translatesAutoresizingMaskIntoConstraints = true(默认)

messageView.translatesAutoresizingMaskIntoConstraints = false

编码:

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 ```

布局经理的第一个抱怨非常明显。 你有一个 x.top = y.top 和另一个 x.top = y.top - 20 的约束。你产生了约束,你应该能够修复它们。 我没有再看下去。

事实证明,问题在于 UIStackView 是基于其子视图的内在内容大小,所以我不得不为大小添加约束而不是使用框架。 之后,我将 UILabel 添加为 UIImageView 的子视图,并设置了前导尾随和中心约束,从而解决了问题。 我没有接受@gnasher729,因为这不是正确的答案,但它确实给了我解决它的提示,为此我感谢他的帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM