如何在堆栈视图中动态调整文本视图的大小
Posted
技术标签:
【中文标题】如何在堆栈视图中动态调整文本视图的大小【英文标题】:How to dynamically resize text view inside a stack view 【发布时间】:2021-07-06 01:32:12 【问题描述】:我正在尝试在堆栈视图中显示动态大小的UITextView
,但文本视图未调整到内容的大小。
首先我有安排好的子视图:
class InfoView: UIView
private var title: String!
private var detail: String!
private var titleLabel: UILabel!
private var detailTextView: UITextView!
init(infoModel: InfoModel)
self.title = infoModel.title
self.detail = infoModel.detail
super.init(frame: .zero)
configure()
setConstraint()
required init?(coder: NSCoder)
fatalError("init(coder:) has not been implemented")
private func configure()
titleLabel = UILabel()
titleLabel.text = title
titleLabel.font = .rounded(ofSize: titleLabel.font.pointSize, weight: .bold)
titleLabel.textColor = .lightGray
titleLabel.sizeToFit()
titleLabel.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(titleLabel)
detailTextView = UITextView()
detailTextView.sizeToFit()
detailTextView.text = detail
detailTextView.font = UIFont.systemFont(ofSize: 19)
detailTextView.isEditable = false
detailTextView.textColor = .lightGray
detailTextView.isUserInteractionEnabled = false
detailTextView.isScrollEnabled = false
detailTextView.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(detailTextView)
private func setConstraint()
NSLayoutConstraint.activate([
titleLabel.topAnchor.constraint(equalTo: self.topAnchor),
titleLabel.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 5),
titleLabel.heightAnchor.constraint(equalToConstant: 40),
detailTextView.topAnchor.constraint(equalTo: titleLabel.bottomAnchor),
detailTextView.leadingAnchor.constraint(equalTo: self.leadingAnchor),
detailTextView.trailingAnchor.constraint(equalTo: self.trailingAnchor),
detailTextView.bottomAnchor.constraint(equalTo: self.bottomAnchor)
])
然后我在视图控制器中实现堆栈视图:
class MyViewController: UIViewController
var infoModelArr: [InfoModel]!
var stackView: UIStackView!
var scrollView: UIScrollView!
init(infoModelArr: [InfoModel])
self.infoModelArr = infoModelArr
super.init(nibName: nil, bundle: nil)
required init?(coder: NSCoder)
fatalError("init(coder:) has not been implemented")
override func viewDidLoad()
super.viewDidLoad()
var infoViewArr = [InfoView]()
for infoModel in infoModelArr
let infoView = InfoView(infoModel: infoModel)
infoViewArr.append(infoView)
stackView = UIStackView(arrangedSubviews: infoViewArr)
stackView.axis = .vertical
stackView.spacing = 10
stackView.distribution = .fillProportionally
stackView.translatesAutoresizingMaskIntoConstraints = false
scrollView.addSubview(stackView)
NSLayoutConstraint.activate([
stackView.topAnchor.constraint(equalTo: scrollView.topAnchor),
stackView.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor),
stackView.trailingAnchor.constraint(equalTo: view.layoutMarginsGuide.trailingAnchor),
])
override func viewDidLayoutSubviews()
super.viewDidLayoutSubviews()
scrollView.contentSize = stackView.bounds.size
最后,我将视图控制器称为:
let myVC = MyViewController(infoModelArr: [InfoModel(title: "title", detail: "detail"), InfoModel(title: "title", detail: "detail")])
self.present(myVC, animated: true, completion: nil)
值得注意的是,如果我用单个排列的子视图实例化堆栈视图,堆栈视图的高度似乎是动态调整的,但是一旦引入 2 个或更多子视图,高度就不会反映内容.
当我尝试设置 InfoView
的内在大小时,
override func layoutSubviews()
super.layoutSubviews()
height = titleLabel.bounds.height + detailTextView.bounds.height
var height: CGFloat! = 200
didSet
self.invalidateIntrinsicContentSize()
override var intrinsicContentSize: CGSize
let originalSize = super.intrinsicContentSize
return CGSize(width: originalSize.width, height: height)
detailTextView.bounds.height
返回 0。
【问题讨论】:
你想重塑UITableView
吗?您似乎没有正确使用UIScrollView
(您甚至从未初始化它?)。 fillProportionally
在这里似乎也不合适。应该有一些约束被打破,对吧?您应该在问题中包含冲突的约束。我认为fill
更合适,但你为什么不首先使用UITableView
?
@Sweeper 哎呀,缺少UIScrollView
是我在复制问题时的一个错误。 fill
似乎在起作用,所以如果你想发布答案,我会标记它。我使用UIStackView
,因为我将只使用 1 - 3 个项目,但我肯定会考虑该选项。
【参考方案1】:
fillProportionally
分布尝试根据排列的子视图的固有内容大小缩放其高度,作为堆栈视图高度的比例。例如如果堆栈视图的高度为 120,排列的子视图 A 的固有高度为 10,排列的子视图 B 的固有高度为 20,则 A 和 B 在堆栈视图中的高度分别为 40 和 80。
您的堆栈视图没有定义的高度,因此fillProportionally
在这里没有多大意义。
相反,fill
的分布应该可以完成这项工作:
stackView.distribution = .fill
(作为实验,您可以尝试在堆栈视图中添加高度约束,您将看到fillProportionally
的工作原理)
【讨论】:
以上是关于如何在堆栈视图中动态调整文本视图的大小的主要内容,如果未能解决你的问题,请参考以下文章
如何在动态类型的 UIContentSizeCategoryDidChangeNotification 之后调整视图大小