容器视图中以编程方式创建的标签不会针对文本展开

Programatically Created Label Within Container View Won't Expand For Text

我有一个可重复使用的视图 class,当添加到另一个视图时带有函数 .addDisapearingView() 会在函数参数中显示文本。标签及其容器视图都是以编程方式创建的。当标签中有长文本时,我希望标签和视图的高度都增加。当文本对于标签来说太长时,标签不会增长——随后文本不会 clip/go 到下一行。我试图让容器视图根据文本以编程方式扩展。

我尝试了一个扩展程序来检测标签何时被截断。使用该扩展,我在标签和视图上使用了 += 运算符来扩展它们,但没有成功。

while label.isTruncated {
       print("printing while truncating in the while loop")
        regView.frame.size.height += 5
        label.frame.size.height += 5
    }

有趣的是,我以前使用过该代码,在情节提要中添加 5 到视图的高度约束以扩展文本标签的大小,并且它有效。这让我相信我的问题可能出在编辑 regView 的高度限制的某个地方。

我试过无数种

    label.adjustsFontSizeToFitWidth = true
    label.numberOfLines = 3
    label.lineBreakMode = .byWordWrapping
    label.translatesAutoresizingMaskIntoConstraints = false
    label.frame.size.height = regView.frame.size.height
    label.sizeToFit()
    regView.layoutSubviews()

我试过更改视图和标签的框架,更改代码顶部的约束,以及其他问题的答案。

代码:

截断标签扩展:

extension UILabel {

var isTruncated: Bool {

    guard let labelText = text else {
        return false
    }

    let labelTextSize = (labelText as NSString).boundingRect(
        with: CGSize(width: frame.size.width, height: .greatestFiniteMagnitude),
        options: .usesLineFragmentOrigin,
        attributes: [.font: font],
        context: nil).size

    return labelTextSize.height > bounds.size.height
}
}

查看约束更改器:

extension UIView {

func updateConstraint(attribute: NSLayoutAttribute, constant: CGFloat) -> Void {
    if let constraint = (self.constraints.filter{[=13=].firstAttribute == attribute}.first) {
        constraint.constant = constant
        self.layoutIfNeeded()
    }
}
}

整个函数:

func addDisapearingView(toview: UIView, text: String, textColor: UIColor, colorView: UIColor, alpha: CGFloat, height: CGFloat){

    regView.backgroundColor = colorView
    regView.alpha = alpha
    regView.frame = CGRect(x: toview.bounds.minX, y: toview.bounds.minY, width: toview.frame.size.width, height: height)

    toview.addSubview(regView)

    regView.translatesAutoresizingMaskIntoConstraints = false
    if #available(iOS 11.0, *) {
        let guide = toview.safeAreaLayoutGuide
        regView.trailingAnchor.constraint(equalTo: guide.trailingAnchor).isActive = true
        regView.leadingAnchor.constraint(equalTo: guide.leadingAnchor).isActive = true
        regView.topAnchor.constraint(equalTo: guide.topAnchor).isActive = true
        regView.heightAnchor.constraint(equalToConstant: height).isActive = true

    } else {
        NSLayoutConstraint(item: regView,
                           attribute: .top,
                           relatedBy: .equal,
                           toItem: toview, attribute: .top,
                           multiplier: 1.0, constant: 0).isActive = true
        NSLayoutConstraint(item: regView,
                           attribute: .leading,
                           relatedBy: .equal, toItem: toview,
                           attribute: .leading,
                           multiplier: 1.0,
                           constant: 0).isActive = true
        NSLayoutConstraint(item: regView, attribute: .trailing,
                           relatedBy: .equal,
                           toItem: toview,
                           attribute: .trailing,
                           multiplier: 1.0,
                           constant: 0).isActive = true
        NSLayoutConstraint(item: regView, attribute: NSLayoutAttribute.height, relatedBy: .equal, toItem: toview, attribute: .height, multiplier: 1.0, constant: height).isActive = true
        //regView.heightAnchor.constraint(equalToConstant: height).isActive = true
    }

    let label = UILabel(frame: CGRect(x: regView.frame.origin.x, y: regView.frame.origin.y, width: regView.frame.width, height: height))
    label.text = text
    label.font = UIFont(name: "Arial", size: 12)
    label.textColor = textColor
    label.adjustsFontSizeToFitWidth = true
    label.numberOfLines = 3
    label.lineBreakMode = .byWordWrapping
    label.translatesAutoresizingMaskIntoConstraints = false
    label.frame.size.height = regView.frame.size.height
    label.sizeToFit()
    regView.layoutSubviews()
    regView.addSubview(label)
    print("Label Height: \(label.frame.height)")
    print("Reg view height: \(regView.frame.height)")

    while label.isTruncated {
        print("label is truncated")
        regView.frame.size.height += 5
        label.frame.size.height += 5
        label.updateConstraint(attribute: NSLayoutAttribute.height, constant: regView.frame.height)
        label.updateConstraint(attribute: NSLayoutAttribute.width, constant: regView.frame.width)

        regView.layoutSubviews()
        label.sizeToFit()
        print("Label Height: \(label.frame.height)")
        print("Reg view height: \(regView.frame.height)")
    }

    //remove
    Timer.scheduledTimer(withTimeInterval: 2.8, repeats: false) { (action) in
        UIView.animate(withDuration: 2.8, animations: {
            self.regView.removeFromSuperview()
            label.removeFromSuperview()

        })
    }

}

调用者:ReusableView().addDisapearingView(toview: self.view, text: "Anonymous posts will still show up in your profile page!, more text text to test in teh view that doen't work!", textColor: UIColor.white, colorView: UIColor.darkGray, alpha: 0.9, height: 20)

有趣的事情(我 尝试 修复)是即使高度设置为 40,或者两行文本可以容纳的值, 标签仍然没有 expand/truncate, 如果高度参数是 20.

就更不用说了

如有任何帮助,我们将不胜感激!

我猜你完全需要自动布局并使 regView 根据标签的文本扩展而没有任何高度限制

let regView = UIView()

func addDisapearingView(toview: UIView, text: String, textColor: UIColor, colorView: UIColor, alpha: CGFloat, height: CGFloat){

regView.backgroundColor = colorView
regView.alpha = alpha
toview.addSubview(regView)

regView.translatesAutoresizingMaskIntoConstraints = false
if #available(iOS 11.0, *) {
    let guide = toview.safeAreaLayoutGuide
    NSLayoutConstraint.activate([
            regView.trailingAnchor.constraint(equalTo: guide.trailingAnchor),
            regView.leadingAnchor.constraint(equalTo: guide.leadingAnchor),
            regView.topAnchor.constraint(equalTo: guide.topAnchor),
           // regView.bottomAnchor.constraint(equalTo: guide.bottomAnchor).isActive = true
           // regView.heightAnchor.constraint(equalToConstant: height).isActive = true
    ])
} else {
    NSLayoutConstraint(item: regView,
                       attribute: .top,
                       relatedBy: .equal,
                       toItem: toview, attribute: .top,
                       multiplier: 1.0, constant: 0).isActive = true
    NSLayoutConstraint(item: regView,
                       attribute: .leading,
                       relatedBy: .equal, toItem: toview,
                       attribute: .leading,
                       multiplier: 1.0,
                       constant: 0).isActive = true
    NSLayoutConstraint(item: regView, attribute: .trailing,
                       relatedBy: .equal,
                       toItem: toview,
                       attribute: .trailing,
                       multiplier: 1.0,
                       constant: 0).isActive = true
   // NSLayoutConstraint(item: regView, attribute: NSLayoutConstraint.Attribute.height, relatedBy: .equal, toItem: toview, attribute: .height, multiplier: 1.0, constant: height).isActive = true
    //regView.heightAnchor.constraint(equalToConstant: height).isActive = true
}

let label = UILabel()
label.text = text
label.font = UIFont(name: "Arial", size: 12)
label.textColor = textColor
label.numberOfLines = 3
label.lineBreakMode = .byWordWrapping
label.translatesAutoresizingMaskIntoConstraints = false
regView.addSubview(label)

    NSLayoutConstraint.activate([
        label.trailingAnchor.constraint(equalTo: regView.trailingAnchor),
        label.leadingAnchor.constraint(equalTo: regView.leadingAnchor),
        label.topAnchor.constraint(equalTo: regView.topAnchor),
        label.bottomAnchor.constraint(equalTo: regView.bottomAnchor) // this is the key behind expanding 

    ])

 Timer.scheduledTimer(withTimeInterval:3, repeats: false) { (action) in
    UIView.animate(withDuration: 2.8, animations: {
        self.regView.removeFromSuperview()
    })
 }

}

编辑:

let regView = UIView()

func addDisapearingView(toview: UIView, text: String, textColor: UIColor, colorView: UIColor, alpha: CGFloat, height: CGFloat){

    regView.backgroundColor = colorView
    regView.alpha = alpha
    toview.addSubview(regView)

    regView.translatesAutoresizingMaskIntoConstraints = false
    var topCon:NSLayoutConstraint!

    if #available(iOS 11.0, *) {
        let guide = toview.safeAreaLayoutGuide
        topCon = regView.bottomAnchor.constraint(equalTo: guide.topAnchor)
        topCon.isActive = true
        NSLayoutConstraint.activate([
            regView.trailingAnchor.constraint(equalTo: guide.trailingAnchor),
            regView.leadingAnchor.constraint(equalTo: guide.leadingAnchor),
            // regView.bottomAnchor.constraint(equalTo: guide.bottomAnchor).isActive = true
            // regView.heightAnchor.constraint(equalToConstant: height).isActive = true
            ])
    } else {
        topCon =  NSLayoutConstraint(item: regView,
                           attribute: .bottom,
                           relatedBy: .equal,
                           toItem: toview, attribute: .top,
                           multiplier: 1.0, constant: 0)
            topCon.isActive = true
        NSLayoutConstraint(item: regView,
                           attribute: .leading,
                           relatedBy: .equal, toItem: toview,
                           attribute: .leading,
                           multiplier: 1.0,
                           constant: 0).isActive = true
        NSLayoutConstraint(item: regView, attribute: .trailing,
                           relatedBy: .equal,
                           toItem: toview,
                           attribute: .trailing,
                           multiplier: 1.0,
                           constant: 0).isActive = true
        // NSLayoutConstraint(item: regView, attribute: NSLayoutConstraint.Attribute.height, relatedBy: .equal, toItem: toview, attribute: .height, multiplier: 1.0, constant: height).isActive = true
        //regView.heightAnchor.constraint(equalToConstant: height).isActive = true
    }

    let label = UILabel()
    label.text = text
    label.font = UIFont(name: "Arial", size: 12)
    label.textColor = textColor
    label.numberOfLines = 3
    label.lineBreakMode = .byWordWrapping
    label.translatesAutoresizingMaskIntoConstraints = false
    regView.addSubview(label)

    NSLayoutConstraint.activate([
        label.trailingAnchor.constraint(equalTo: regView.trailingAnchor),
        label.leadingAnchor.constraint(equalTo: regView.leadingAnchor),
        label.topAnchor.constraint(equalTo: regView.topAnchor),
        label.bottomAnchor.constraint(equalTo: regView.bottomAnchor) // this is the key behind expanding

        ])


     regView.layoutIfNeeded()

    topCon.constant += self.regView.frame.height

    UIView.animate(withDuration: 2) {
        toview.layoutIfNeeded()
    }


    Timer.scheduledTimer(withTimeInterval:3, repeats: false) { (action) in
        UIView.animate(withDuration: 2.8, animations: {
            self.regView.removeFromSuperview()
        })
    }

}