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.
我尝试使用 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.