我在我的一个视图中添加了一个滚动视图子视图,但是无法使其高度准确适合滚动视图显示的内容,即UILabel中的文本。 高度需要是动态的(即文本长度的一个因素(,因为我正在为许多不同的文本长度实例化此视图。 每当我登录label.frame.bounds
我都会得到 (0,0( 回来。 我也在几个地方尝试过sizeToFits()
,但没有太多运气。
我的目标是让滚动视图在到达文本的最后一行时结束。 此外,我只使用编程约束。
我的代码的精简版本如下:
import UIKit
class ViewController: UIViewController, UIScrollViewDelegate {
let scrollView = UIScrollView()
let containerView = UIView()
let label = UILabel()
override func viewDidLoad() {
super.viewDidLoad()
scrollView.delegate = self
// This needs to change
scrollView.contentSize = CGSize(width: 375, height: 1000)
scrollView.addSubview(containerView)
view.addSubview(scrollView)
label.text = unknownAmountOfText()
label.backgroundColor = .gray
containerView.isUserInteractionEnabled = true
containerView.addSubview(label)
label.translatesAutoresizingMaskIntoConstraints = false
label.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true
label.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
scrollView.frame = view.bounds
containerView.frame = CGRect(x: 0, y: 0, width: scrollView.contentSize.width, height: scrollView.contentSize.height)
}
}
任何帮助,不胜感激。
找到的解决方案:
func heightForLabel(text: String, font: UIFont, lineHeight: CGFloat, width: CGFloat) -> CGFloat {
let label:UILabel = UILabel(frame: CGRect(x: 0, y: 0, width: width, height: CGFloat.greatestFiniteMagnitude))
label.numberOfLines = 0
label.lineBreakMode = NSLineBreakMode.byWordWrapping
label.font = font
label.text = text
label.setLineHeight(lineHeight: lineHeight)
label.sizeToFit()
return label.frame.height
}
我在网上找到了这个解决方案,它为我提供了根据标签的高度为 scrollView 高度设置适当内容大小所需的内容。 理想情况下,我可以在没有此功能的情况下确定这一点,但现在我很满意。
UIScrollView 及其内容大小的关键是设置约束,以便实际内容定义 contentSize。
举一个简单的例子:假设你有一个 UIScrollView,宽度:200,高度:200。现在你把一个UIView放进去,它的宽度:100,高度:400。视图应上下滚动,但不能左右滚动。您可以将视图限制为 100x400,然后将顶部、底部、左侧和右侧"固定"到滚动视图的两侧,AutoLayout 将"自动神奇地"设置滚动视图的内容大小。
当您添加可以显式(代码、用户交互(或隐式更改大小的子视图时,如果约束设置正确,这些更改也将"自动神奇地"调整滚动视图的内容大小。
所以...下面是你正在尝试做的事情的一个示例:
import UIKit
class ViewController: UIViewController, UIScrollViewDelegate {
let scrollView = UIScrollView()
let label = UILabel()
let s1 = "1. This is the first line of text in the label. It has words and punctuation, but no embedded line-breaks, so what you see here is normal UILabel word-wrapping."
var counter = 1
override func viewDidLoad() {
super.viewDidLoad()
// turn off translatesAutoresizingMaskIntoConstraints, because we're going to set them
scrollView.translatesAutoresizingMaskIntoConstraints = false
label.translatesAutoresizingMaskIntoConstraints = false
// set background colors, just so we can see the bounding boxes
self.view.backgroundColor = UIColor(red: 1.0, green: 0.7, blue: 0.3, alpha: 1.0)
scrollView.backgroundColor = UIColor(red: 0.8, green: 0.8, blue: 1.0, alpha: 1.0)
label.backgroundColor = UIColor(white: 0.9, alpha: 1.0)
// add the label to the scrollView, and the scrollView to the "main" view
scrollView.addSubview(label)
self.view.addSubview(scrollView)
// set top, left, right constraints on scrollView to
// "main" view + 8.0 padding on each side
scrollView.topAnchor.constraint(equalTo: self.topLayoutGuide.bottomAnchor, constant: 8.0).isActive = true
scrollView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 8.0).isActive = true
scrollView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -8.0).isActive = true
// set the height constraint on the scrollView to 0.5 * the main view height
scrollView.heightAnchor.constraint(equalTo: self.view.heightAnchor, multiplier: 0.5).isActive = true
// set top, left, right AND bottom constraints on label to
// scrollView + 8.0 padding on each side
label.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 8.0).isActive = true
label.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor, constant: 8.0).isActive = true
label.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor, constant: -8.0).isActive = true
label.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: -8.0).isActive = true
// set the width of the label to the width of the scrollView (-16 for 8.0 padding on each side)
label.widthAnchor.constraint(equalTo: scrollView.widthAnchor, constant: -16.0).isActive = true
// configure label: Zero lines + Word Wrapping
label.numberOfLines = 0
label.lineBreakMode = NSLineBreakMode.byWordWrapping
label.font = UIFont.systemFont(ofSize: 17.0)
// set the text of the label
label.text = s1
// ok, we're done... but let's add a button to change the label text, so we
// can "see the magic" happening
let b = UIButton(type: UIButtonType.system)
b.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(b)
b.setTitle("Add a Line", for: .normal)
b.topAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: 24.0).isActive = true
b.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
b.addTarget(self, action: #selector(self.btnTap(_:)), for: .touchUpInside)
}
func btnTap(_ sender: Any) {
if let t = label.text {
counter += 1
label.text = t + "nn(counter). Another line"
}
}
}
使用 containerView 给出顶部、左侧、右侧和底部约束以标记。和设置标签.行数 = 0还要确保已将顶部、左侧、右侧和底部约束提供给 containerView。这将解决您的问题
从界面构建器设置自动布局约束,如图所示。在此处输入图像描述
我将UIScrollView的高度设置为UIView的0.2
然后将 UIlabel 从主情节提要拖到视图控制器。
在视图加载方法中添加这两行。
拖动标签.行数 = 0
draggedlabel.lineBreakMode = NSLineBreakMode.byWordWrapping