【问题标题】:Auto resize the UIView based on UILabel's content through Auto Layout通过 Auto Layout 根据 UILabel 的内容自动调整 UIView 的大小
【发布时间】:2019-06-05 04:02:45
【问题描述】:

我需要显示横幅视图以显示消息,

现在消息的内容可能会有所不同,并且视图也应该根据UILabels 的内容调整大小。

UILabel 设置为Word WrapnumberOfLines 设置为0

xib 中的设计是,

而相应的类文件是,

import UIKit

class ORABannerView: UIView {

    @IBOutlet weak var bannerText: UILabel!

    static func instantiate(message: String) -> ORABannerView {
        let view: ORABannerView = initFromNib() ?? ORABannerView()
        view.bannerText.text = message
        return view
    }

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

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

    override func draw(_ rect: CGRect) {
        super.draw(rect)
    }
}

initFromNib 是作为 UIView 的扩展实现的,

extension UIView {
    class func initFromNib<T: UIView>() -> T? {
        guard let view = Bundle.main.loadNibNamed(String(describing: self), owner: nil, options: nil)?[0] as? T else {
            return nil
        }
        return view
    }
}

尝试在视图上使用 layoutIfNeeded(),但它对我不起作用。

任何建议将不胜感激。

【问题讨论】:

    标签: ios swift uiview autolayout constraints


    【解决方案1】:

    你可能想试试下面的代码,

    创建一个方法sizeHeaderToFit 并根据其内容的高度返回UIView 的高度。

    private func sizeHeaderToFit(headerView: UIView?) -> CGFloat {
           guard let headerView = headerView else {
               return 0.0
           }
    
           headerView.setNeedsLayout()
           headerView.layoutIfNeeded()
    
           let height = headerView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize).height
    
           return height
       }
    

    那么就可以从各自的代码中调用上面的方法了,

    sizeHeaderToFit(headerView: yourView)
    

    ORABannerView类中,添加覆盖layoutSubviews

    override func layoutSubviews() {
           super.layoutSubviews()
           bannerText.preferredMaxLayoutWidth = bannerText.bounds.width
       }
    

    xib 文件中,将约束保持在superview 而不是safe area 以进行代码优化。 [可选]

    希望对你有帮助。

    【讨论】:

    • 让我试试这个方法。
    【解决方案2】:
    1. 删除尾随或前导约束
    2. 以编程方式设置大小以适应属性

    【讨论】:

    • 我正在寻找 xib 文件本身的解决方案,主要是约束。
    【解决方案3】:

    我希望这个类看起来像

    class ORABannerView: UIView {
    
        @IBOutlet weak var bannerText: UILabel!
    
        static func instantiate(message: String) -> ORABannerView {
            let view: ORABannerView = initFromNib()
            view.bannerText.text = message
            return view
        }
    
        override init(frame: CGRect) {
            super.init(frame: frame)
        }
    
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
        }
    
        override func draw(_ rect: CGRect) {
            super.draw(rect)
        }
    }
    

    let v = ORABannerView.instantiate(message: "djhhejjhsdjhdjhjhdshdsjhdshjdhjdhjdhjddhjhjdshjdhdjshjshjdshjdshjdshjdshjdsjhdshjds")
    
    self.view.addSubview(v)
    
    v.translatesAutoresizingMaskIntoConstraints = false
    
    NSLayoutConstraint.activate([
    
        v.topAnchor.constraint(equalTo: self.view.topAnchor,constant:50),
    
        v.leadingAnchor.constraint(equalTo: self.view.leadingAnchor,constant:0),
    
        v.trailingAnchor.constraint(equalTo: self.view.trailingAnchor,constant:0)
    
    ])
    

    【讨论】:

    • 我添加了我的initWithNib 方法
    • 不需要设置底部锚点?
    • 你想从顶部还是底部显示横幅?如果顶部设置顶部约束,如果底部设置底部,则重新设置您需要设置前导、尾随、顶部和底部的标签
    • 在xib中设置没问题
    • 难道不能在xib文件本身而不是在代码中设置锚点吗?
    【解决方案4】:

    新用户自动布局,总是忘记两个有用的约束:

    func setContentCompressionResistancePriority(UILayoutPriority, for: NSLayoutConstraint.Axis)
    func setContentHuggingPriority(UILayoutPriority, for: NSLayoutConstraint.Axis)
    

    它也存在于 IB 中:

    尝试使用优先级参数

    【讨论】:

    • 让我试一试,顺便说一句,您是否尝试过同样的方法并且对您有效?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-09
    • 2018-09-30
    • 2019-09-18
    • 2019-12-17
    • 2012-05-26
    • 2014-05-04
    • 1970-01-01
    相关资源
    最近更新 更多