Ios 如何根据自定义UIView的内容自动设置其宽度?

Ios 如何根据自定义UIView的内容自动设置其宽度?,ios,swift,uiview,autolayout,Ios,Swift,Uiview,Autolayout,我有一个简单的自定义UIView(屏幕截图上有白色背景的视图),它使用xib和从UIView派生的自定义类 在里面,我有一个UILabel和一个按钮在同一条线上,仅此而已 按钮的大小是固定的。 标签的宽度必须根据其内容进行调整 我想要的是: -使标签的大小与其内容相适应 -将按钮的位置设置为始终紧靠标签之后 -使自定义符合其内容 像这样: 我怎样才能继续这样做 添加内容: class Keyword: UIView { @IBOutlet weak var label: UILabel!

我有一个简单的自定义UIView(屏幕截图上有白色背景的视图),它使用xib和从UIView派生的自定义类

在里面,我有一个UILabel和一个按钮在同一条线上,仅此而已

按钮的大小是固定的。 标签的宽度必须根据其内容进行调整

我想要的是: -使标签的大小与其内容相适应 -将按钮的位置设置为始终紧靠标签之后 -使自定义符合其内容

像这样:

我怎样才能继续这样做

添加内容:

class Keyword: UIView {

@IBOutlet weak var label: UILabel!
@IBOutlet var contentView: UIView!

override init(frame: CGRect) {
    super .init(frame: frame)
    commonInit()
}

required init?(coder aDecoder: NSCoder) {
    super .init(coder: aDecoder)
    commonInit()
}

fileprivate func commonInit() {
    Bundle.main.loadNibNamed("Keyword", owner: self, options: nil)
    addSubview(contentView)
    contentView.frame = self.bounds
}

override var intrinsicContentSize: CGSize {
    let height = CGFloat(21)
    return CGSize(width: UIViewNoIntrinsicMetric, height: height)
}

/*
// Only override draw() if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func draw(_ rect: CGRect) {
    // Drawing code
}
*/

}
UILabel违禁品:

勾选按钮约束:


以下扩展可用于计算标签的高度和宽度

extension String {

//Calculate height and width for label with string
func height(withConstrainedWidth width: CGFloat, font: UIFont) -> CGFloat {
    let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude)
    let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [NSAttributedStringKey.font: font], context: nil)

    return ceil(boundingBox.height)
}

func width(withConstrainedHeight height: CGFloat, font: UIFont) -> CGFloat {
    let constraintRect = CGSize(width: .greatestFiniteMagnitude, height: height)
    let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [NSAttributedStringKey.font: font], context: nil)

    return ceil(boundingBox.width)
}

}
在本例中,由于按钮大小是固定的,因此可以使用上述扩展名计算标签的宽度,并可用于设置整个视图的宽度约束。如果标签对按钮的前导约束为8,尾随约束为8,而按钮对容器视图的尾随约束为8,则可以计算视图所需的宽度,如下所示:

viewWidthConstraint.constant = 8+<width of string from the above extension>+8+<width of button>+8
viewWidthConstraint.constant=8++8++8

这里唯一改变的参数是标签的宽度。

多亏了@matt,我找到了解决方案

我的代码中只有两个错误

  • 我的自定义视图中缺少以下行代码
    translatesAutoResizengMaskintoConstraints=false
    ,因此从未调用
    intrinsicContentSize
  • 正如@matt所建议的,在
    intrinsicContentSize
    内部,我需要根据标签的固有宽度和宽度参数按钮提供一个值,而不是
    UIViewNoIntrinsicMetric
  • 现在,正确的代码是:

    class Keyword: UIView {
    
    @IBOutlet weak var label: UILabel!
    @IBOutlet weak var btn: UIButton!
    @IBOutlet var contentView: UIView!
    
    override init(frame: CGRect) {
        super .init(frame: frame)
        commonInit()
    }
    
    required init?(coder aDecoder: NSCoder) {
        super .init(coder: aDecoder)
        commonInit()
    }
    
    fileprivate func commonInit() {
        translatesAutoresizingMaskIntoConstraints = false
        Bundle.main.loadNibNamed("Keyword", owner: self, options: nil)
        addSubview(contentView)
        contentView.frame = self.bounds
    }
    
    override var intrinsicContentSize: CGSize {
        let height = btn.frame.size.height
        let width =  btn.frame.origin.x + btn.frame.size.width
        return CGSize(width: width, height: height)
    }
    
    
    // Only override draw() if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    override func draw(_ rect: CGRect) {
        // Drawing code
    }
    
    }
    

    使用自动布局和内部内容大小。我尝试使用内部内容大小,但不起作用。为什么投反对票是一个真正的问题?我投票支持这一点,好吧,因此宽度需要基于标签和按钮的固有宽度,而不是
    宽度:uiviewnointrisicmetric
    。请注意,当标签文本更改时,可能需要使其无效。