【发布时间】:2024-04-10 21:10:01
【问题描述】:
我需要在现有的UITableViewController 中显示一个 SwiftUI 视图,如tableHeaderView。但是,似乎 SwiftUI 视图的大小在添加到 UITableViewController 时被破坏了。
如果我只是使用 UIHostingController 将我的 SwiftUI 视图转换为 UIView 并将其设置为 tableHeaderView,则视图将显示在屏幕外:
func addHeaderView() {
let view = VerticalTextStack()
let hostingController = UIHostingController(rootView: view)
tableView.tableHeaderView = hostingController.view
}
为了解决这个问题,我尝试了几种不同的方法来修复视图的高度。添加NSLayoutConstraint 没有做任何事情。手动设置tableHeaderView.frame.size 时,结果更好,因为至少现在视图显示在屏幕上,但多行Texts 变成单行并被截断。
正如您在此处看到的,第二个 Text 被截断:
这是一个展示问题的简化示例:
/// `UITableViewController` displaying a `UIView` as its `tableHeaderView`
class TableViewController: UITableViewController {
let cellReuseIdentifier = "cell"
let data = ["A", "B", "C", "D", "E"]
let themeManager = AppThemeManager()
// MARK: - UIViewController lifecycle
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellReuseIdentifier)
addHeaderView()
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
fixTableHeaderViewSize()
}
// MARK: - UITableViewDelegate
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
data.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier, for: indexPath)
cell.textLabel?.text = data[indexPath.row]
return cell
}
// MARK: - SwiftUI view
func fixTableHeaderViewSize() {
guard let tableHeaderView = tableView?.tableHeaderView else { return }
let expectedHeight = tableHeaderView.systemLayoutSizeFitting(UIView.layoutFittingExpandedSize).height
let expectedSize = CGSize(width: tableHeaderView.frame.width, height: expectedHeight)
tableHeaderView.frame.size = expectedSize
}
func addHeaderView() {
let view = VerticalTextStack()
let hostingController = UIHostingController(rootView: view)
tableView.tableHeaderView = hostingController.view
}
}
private struct VerticalTextStack: View {
let data = ["First", "I am a very long text that only fits in multiple lines. I still continue.", "Third"]
let themeManager = AppThemeManager()
var body: some View {
VStack(spacing: 10) {
ForEach(data, id: \.self) { value in
Text(value)
}
}
}
}
我也尝试将 addHeaderView 移动到其他 UIViewController 函数,例如 viewWillLayoutSubviews,但这并没有改变任何东西。
将lineLimit 设置为nil 或VerticalTextStack 内部Text 上的任何大数字并将.layoutPriority(.greatestFiniteMagnitude) 添加到Text 也不会使Text 成为多行。
【问题讨论】:
标签: swift uitableview swiftui uikit