简体   繁体   English

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

[英]How to set custom UIView width automatically based on its content?

I have a simple custom UIView (The view with white background on the screenshot) using xib and custom class derived from UIView.我有一个简单的自定义 UIView(屏幕截图上带有白色背景的视图),使用了从 UIView 派生的 xib 和自定义类。

自定义视图

Inside I have a UILabel and a button on the same line ant that's all.在里面我有一个 UILabel 和一个按钮在同一行蚂蚁就是这样。

The size of the button is fixed.按钮的大小是固定的。 The width of the label must be adjusted on its content.标签的宽度必须根据其内容进行调整。

What I would like is : - fit the size of the label to its content - set the position of the button always just after the label - fit the custom to its content我想要的是: - 使标签的大小适合其内容 - 始终在标签之后设置按钮的位置 - 使自定义适合其内容

Like this :像这样 :

正确的 Cutsom 视图

How can I proceed to do this ?我怎样才能继续这样做?

Add content :添加内容:

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 contraints : UILabel 限制:

UILabel 限制

Tick UIButton constraints :勾选 UIButton 约束:

在此处输入图片说明

The following extension can be used to calculate the height and width of label.以下扩展名可用于计算标签的高度和宽度。

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)
}

}

In your case, since the button size is fixed, you can calculate the width of label using the above extension and can be used to set the width constraint of the entire view.在您的情况下,由于按钮大小是固定的,您可以使用上述扩展名计算标签的宽度,并可用于设置整个视图的宽度约束。 If your label has a leading constraint of 8 and a trailing constraint of 8 to the button and the button has a trailing constraint of 8 to the container view, then you can calculate the required width for your view as:如果您的标签对按钮的前导约束为 8,尾随约束为 8,并且按钮对容器视图的尾随约束为 8,那么您可以计算视图所需的宽度:

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

Here the only changing parameter will be the width of the label.这里唯一改变的参数是标签的宽度。

Thanks to @matt, I found the solution.感谢@matt,我找到了解决方案。

There were just 2 errors in my code.我的代码中只有 2 个错误。

  1. The following line code translatesAutoresizingMaskIntoConstraints = false in my custom view was missing, so intrinsicContentSize was never called.我的自定义视图中缺少以下行代码translatesAutoresizingMaskIntoConstraints = false ,因此从未调用过intrinsicContentSize
  2. As suggested by @matt, inside intrinsicContentSize , I need to provide a value based on the intrinsic widths of the label and the button for the width parameters instead of UIViewNoIntrinsicMetric正如@matt 所建议的,在intrinsicContentSize ,我需要根据标签的固有宽度和按钮的宽度参数而不是UIViewNoIntrinsicMetric提供一个值

Now, the right code is :现在,正确的代码是:

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
}

}

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

相关问题 根据内容自动设置自定义UIView的高度? - Automatically set height of custom UIView based on its contents? 如何调整UITextView的大小,当达到一定值时,它会根据内容和固定宽度自动调整其宽度和高度? - How to resize a UITextView that automatically resize its width and height based on the content and fixed width when reaches certain value? 如何根据内容设置collectionview单元格宽度? - How to set collectionview cell width based on content? 如何将自定义子视图的宽度设置为没有宽度约束的父UIView的1/3? - How do I set width of custom subview to be 1/3rd of parent UIView which does not have width constraint? 自动将 UIView 的角半径设置为视图宽度的一半 - Set UIView's corner radius to half of the view's width automatically 如何根据内容更改 UIView 大小? - How to change an UIView size according to its content? 如何设置自定义UIView的大小/位置以放置在自定义UITableViewCell中? - how do I set the size/position of a custom UIView for its placing within a custom UITableViewCell? 如何设置自定义UIView属性 - How to Set Custom UIView Properties 如何将addtarget设置为自定义UIView - How to set addtarget to custom UIView 如何以像素为单位设置 UIVIew 的宽度和高度? - how to set width and height of a UIVIew in pixels?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM