Программно созданная метка в представлении контейнера не будет расширяться для текста - PullRequest
0 голосов
/ 02 января 2019

У меня есть класс многократного использования, функция .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 голосов
/ 02 января 2019

Полагаю, вам полностью необходим автоматический макет, и 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()
    })
 }

}

Edit:

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

}
...