在显示视图之前根据特定宽度获取 UIView 的高度

Posted

技术标签:

【中文标题】在显示视图之前根据特定宽度获取 UIView 的高度【英文标题】:Get height of UIView based on specific width before showing view 【发布时间】:2016-12-21 12:53:41 【问题描述】:

我有一个在 Interface Builder 中设计的UIView。它基本上由标题图像和下面的一些文本(UILabel)组成。视图以模态方式显示,带有自定义转换,并没有填满整个屏幕。

左右两边有 20 像素的边距,顶部有 40 像素的边距。 UILabel 充满了来自网络的一些文本。我想要做的是找到(或者我应该说预测)特定宽度的整个视图的高度。我怎样才能做到这一点?

【问题讨论】:

您对该视图有什么限制? 顶部图片高度固定,上下左右固定,UILabel也固定上下左右 你能展示一些图片吗?你检查过这个答案吗? ***.com/a/36862795/4910767 【参考方案1】:

我遇到了类似的问题,但您可以使用UIView 扩展名来自动调整最大宽度的视图,而不是计算字体大小和图像高度:

extension UIView 

    func autosize(maxWidth: CGFloat) 

        translatesAutoresizingMaskIntoConstraints = false

        let dummyContainerView = UIView(frame: CGRect(x: 0, y: 0, width: maxWidth, height: 10000000))
        dummyContainerView.addSubview(self)
        dummyContainerView.topAnchor.constraint(equalTo: topAnchor, constant: 0).isActive = true
        dummyContainerView.leftAnchor.constraint(equalTo: leftAnchor, constant: 0).isActive = true
        dummyContainerView.rightAnchor.constraint(equalTo: rightAnchor, constant: 0).isActive = true

        setNeedsLayout()
        layoutIfNeeded()

        removeFromSuperview()

        frame = CGRect(x: 0, y: 0, width: frame.width, height: frame.height)

        translatesAutoresizingMaskIntoConstraints = true
    
 

使用此方法,您不必担心视图内的内容。

要使用它:

let customView: CustomView = ... //create your view
... // configure all data on your view, e.g. labels with correct text
customView.autosize(maxWidth: 150) // resize your view 
view.addSubview(customView) // add your view to any view

【讨论】:

【参考方案2】:

在计算纵横比之前,您需要同时拥有图片和标签。 我想你应该使用这样的东西(也许将 imageView 和 Label 之间的垂直间距添加到总和中,并且可能从宽度中删除横向边距):

目标 C

- (CGFloat)preferredHeightFromWidth:(CGFloat)width text:(NSString *)text font:(UIFont *)font image:(UIImage *)image

    // Calculate label height
    CGFloat labelHeight = [text
                           boundingRectWithSize:CGSizeMake(width, 10000)
                           options:NSStringDrawingUsesLineFragmentOrigin
                           attributes:@NSFontAttributeName:font
                           context:[[NSStringDrawingContext alloc] init]
                           ].size.height;

    // Calculate image height
    CGFloat ratio = image.size.height/ image.size.width;
    CGFloat imageHeight = (ratio * width);

    // Do the sum
    return labelHeight + imageHeight;

斯威夫特

func preferredHeight(width: CGFloat, text: NSString, font: UIFont, image: UIImage) -> CGFloat 
    // Calculate Label Height
    let labelRect = text.boundingRect(
        with: CGSize.init(width: width, height: 10000),
        options: .usesLineFragmentOrigin,
        attributes: [NSFontAttributeName : font],
        context: NSStringDrawingContext())
    let labelHeight = labelRect.height

    // Calculate Image Height
    let ratio = image.size.height / image.size.width
    let imageHeight = ratio / width

    // Calculate Total Height
    let height = labelHeight + imageHeight

    // Return Height Value
    return height

(感谢 Christopher Hannah 的快速版本)

【讨论】:

【参考方案3】:

这里的答案和 Alberto 一样,但是我已经把它改成了 Swift 3。

func preferredHeight(width: CGFloat, text: NSString, font: UIFont, image: UIImage) -> CGFloat 
    // Calculate Label Height
    let labelRect = text.boundingRect(
        with: CGSize.init(width: width, height: 10000),
        options: .usesLineFragmentOrigin,
        attributes: [NSFontAttributeName : font],
        context: NSStringDrawingContext())
    let labelHeight = labelRect.height

    // Calculate Image Height
    let ratio = image.size.height / image.size.width
    let imageHeight = ratio / width

    // Calculate Total Height
    let height = labelHeight + imageHeight

    // Return Height Value
    return height

【讨论】:

以上是关于在显示视图之前根据特定宽度获取 UIView 的高度的主要内容,如果未能解决你的问题,请参考以下文章

UIView 不根据子视图调整宽度?

UIView 事件应用约束并设置子视图宽度

iOS自动布局:在ViewController中获取视图内的视图宽度

根据 `UITableViewCell` 中的 `UILabel` 文本更改 `UIView` 宽度

如何用另一个 UIView 的矩形切割 UIView 的顶角

从自定义 UIView 类设置视图宽度约束不更新帧