首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >UIStackView中的NSLayout约束无法同时满足约束

UIStackView中的NSLayout约束无法同时满足约束
EN

Stack Overflow用户
提问于 2020-07-26 18:31:38
回答 2查看 90关注 0票数 0

我正在以编程的方式在UITableViewCell中创建一个UIStackView。StackView包含3个消息气球,分别由容器UIView、UIImageView和UILabel组成。我试图使容器视图的高度大于图像视图,因为它应该在UIImageView顶部包含更多元素,但高度被缩减为UIImageView的高度,并且控制台显示为Unable to simultaneously satisfy constraints。根据this answer的建议,我将UIImageView的translateAutoResizingMAskIntoConstraints设置为false,因此现在容器视图确实比图像视图高,但图像视图的宽度不适合UILabel。

代码:

代码语言:javascript
运行
复制
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
}
}

控制台日志:

代码语言:javascript
运行
复制
   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 ```
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-07-26 20:39:14

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

票数 0
EN

Stack Overflow用户

发布于 2020-07-26 18:43:13

布局管理器的第一个抱怨是非常明显的。您有一个约束x.top = y.top,另一个约束x.top = y.top - 20。您生成了这些约束,应该能够修复它们。我没有再往前看了。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63098952

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档