UILabel sizeToFit 不算长的自动换行符

UILabel sizeToFit not count long word-wrap line break

我尝试使用 sizeToFit 让 UILabel 高度随着文本动态变化。但是,它确实计算“\n”,但似乎不计算换行的长字换行。文字终会溢出

在代码中,我首先添加了一个scrollview和一个stackview,并创建了两个函数来设置它们的约束和背景颜色。当一切都完成后,我尝试编写一个 for 循环,使用 UILabel 创建 UIView,并使用

label.numberOfLines = 0

label.lineBreakMode = NSLineBreakMode.byWordWrapping

让长字换行。然后我创建了一个 for 循环来获得更长的字符串。

label.text = "This is first line and it is very very long long long."
            for _ in 0...i{
                label.text! += "\n"+"This is new added line and is also very very long long long"
            }

原代码如下,如有需要

我不知道是哪一步出错了。

谢谢你的帮助。

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = UIColor(red: 213/255, green: 165/255, blue: 68/255, alpha: 1)
        //scroll and stack view adjust
        let scrollView = UIScrollView()
        scrollViewAdjust(scrollView: scrollView)
        let stackView = UIStackView()
        stackViewAdjust(stackView: stackView, scrollView: scrollView)
        
        for i in 0..<5{
            let newView = UIView()
            stackView.addArrangedSubview(newView)
            newView.translatesAutoresizingMaskIntoConstraints = false
            newView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1)
            newView.layer.cornerRadius = 5
            let label = UILabel()
            newView.addSubview(label)
            label.translatesAutoresizingMaskIntoConstraints = false
            label.numberOfLines = 0
            label.lineBreakMode = NSLineBreakMode.byWordWrapping
            label.text = "This is first line and it is very very long long long."
            for _ in 0...i{
                label.text! += "\n"+"This is new added line and is also very very long long long"
            }
            label.topAnchor.constraint(equalTo: newView.topAnchor).isActive = true
            label.leadingAnchor.constraint(equalTo: newView.leadingAnchor, constant: 3).isActive = true
            label.trailingAnchor.constraint(equalTo: newView.trailingAnchor, constant: 3).isActive = true
            label.sizeToFit()
            print(label.frame.size.height)
            newView.heightAnchor.constraint(equalToConstant: label.frame.size.height).isActive = true
        }
        
        
    }
    
    //functions
    func scrollViewAdjust(scrollView: UIScrollView){
        view.addSubview(scrollView)
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
        scrollView.topAnchor.constraint(equalTo: view.topAnchor, constant: 6).isActive = true
        scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
    }
    
    func stackViewAdjust(stackView:UIStackView, scrollView:UIScrollView){
        stackView.axis = .vertical
        stackView.spacing = 20
        scrollView.addSubview(stackView)
        stackView.translatesAutoresizingMaskIntoConstraints = false
        stackView.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor).isActive = true
        stackView.widthAnchor.constraint(equalTo: scrollView.widthAnchor, multiplier: 0.8).isActive = true
        stackView.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 15).isActive = true
        stackView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
    }
}

您的尾随约束不是。正确

label.trailingAnchor.constraint(equalTo: newView.trailingAnchor, constant: 3).isActive = true

它会从 newView 中消失...像这样设置它以提供 3 点填充

label.trailingAnchor.constraint(equalTo: newView.trailingAnchor, constant: -3).isActive = true

创建标签时必须设置标签宽度。我已经更新了您此处示例中的 for 循环以匹配您的 stackView 的宽度:

    for i in 0..<5{
        let newView = UIView()
        stackView.addArrangedSubview(newView)
        newView.translatesAutoresizingMaskIntoConstraints = false
        newView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1)
        newView.layer.cornerRadius = 5
        stackView.layoutIfNeeded() // needed to force update the layout before getting the width
        let width = stackView.frame.width
        print(width)
        let label = UILabel(frame: CGRect(x: 0, y: 0, width: width, height: CGFloat.greatestFiniteMagnitude))
        newView.addSubview(label)
        label.translatesAutoresizingMaskIntoConstraints = false
        label.numberOfLines = 0
        label.textColor = UIColor.black
        label.lineBreakMode = NSLineBreakMode.byWordWrapping
        label.text = "This is \(i) line and it is very very long long long."
        for ii in 0...i{
            label.text! += "\n"+"This is new added \(ii) line and is also very very long long long"
        }
        label.sizeToFit()
        label.topAnchor.constraint(equalTo: newView.topAnchor).isActive = true
        label.leadingAnchor.constraint(equalTo: newView.leadingAnchor, constant: 3).isActive = true
        label.trailingAnchor.constraint(equalTo: newView.trailingAnchor, constant: 3).isActive = true
        label.bottomAnchor.constraint(equalTo: newView.bottomAnchor).isActive = true
        print(label.frame.size.height)
        newView.heightAnchor.constraint(equalToConstant: label.frame.size.height).isActive = true
    }

While this works and does scroll, you should really be using a UICollectionView to custom UICollectionViewCell's to handle a scroll like this.