在容器视图中以编程方式创建的标签不会扩展为文本

时间:2019-01-02 16:09:50

标签: swift dynamic view resize label

我有一个可重用的视图类,将函数.addDisapearingView()添加到另一个视图后,将在函数参数中显示文本。标签及其容器视图都是以编程方式创建的。当标签中有长文本时,我希望标签和视图的高度都增加。当标签的文本太长时,标签不会增长-随后文本也不会剪切/转到下一行。我正在尝试使容器视图基于文本以编程方式扩展。

我尝试了一种扩展功能,该功能可以检测标签何时被截断。使用该扩展名,我在标签和视图上使用了+=运算符,但没有运气就扩展了它们两者。

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{$0.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或可以容纳两行文本的值,标签仍然不会不会展开/截断,如果高度参数为20,则不会。

任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:1)

我想您完全需要自动布局,并使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()
        })
    }

}