swift - 添加到 UITableViewController 时,SwiftUI 视图大小被破坏
问题描述
我需要在现有UITableViewController
的tableHeaderView
. 但是,似乎 SwiftUI 视图的大小在添加到UITableViewController
.
UIView
如果我只是使用 a将我的 SwiftUI 视图转换为aUIHostingController
并将其设置为tableHeaderView
,则视图将显示在屏幕外:
func addHeaderView() {
let view = VerticalTextStack()
let hostingController = UIHostingController(rootView: view)
tableView.tableHeaderView = hostingController.view
}
为了解决这个问题,我尝试了几种不同的方法来修复视图的高度。添加一个NSLayoutConstraint
没有做任何事情。手动设置时tableHeaderView.frame.size
,结果更好,因为至少现在视图显示在屏幕上,但多行Text
变为单行并被截断。
正如您在此处看到的,第二个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
或任何大的数字并添加到也不会产生多行。Text
VerticalTextStack
.layoutPriority(.greatestFiniteMagnitude)
Text
Text
解决方案
这是一个可能的解决方案。
使用此更改您的添加标题视图功能。
func addHeaderView() {
let view = VerticalTextStack()
let hostingController = UIHostingController(rootView: view)
let headerViewMain = UIView()
headerViewMain.backgroundColor = .red
headerViewMain.addSubview(hostingController.view)
hostingController.view.translatesAutoresizingMaskIntoConstraints = false
let constraints = [
hostingController.view.topAnchor.constraint(equalTo: headerViewMain.topAnchor),
hostingController.view.leftAnchor.constraint(equalTo: headerViewMain.leftAnchor),
headerViewMain.bottomAnchor.constraint(equalTo: hostingController.view.bottomAnchor),
headerViewMain.rightAnchor.constraint(equalTo: hostingController.view.rightAnchor)
]
NSLayoutConstraint.activate(constraints)
headerViewMain.frame.size.height = headerViewMain.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize).height
headerViewMain.frame.size.width = headerViewMain.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize).width
self.tableHeaderView = headerViewMain
self.layoutIfNeeded()
self.setNeedsLayout()
self.reloadData()
}
推荐阅读
- r - 我试图理解 predict()
- powershell - Powershell - If 语句,在弹出窗口中返回计数结果
- google-api - 添加学生的课堂 API 调用速度很慢
- perl - 在最新的稳定 Perl 5.32.0 上运行 Net::Async::OpenTracing 时出错
- android - SensorManager.registerListener - samplingPeriodUs 被忽略
- .net-core - 设置响应的状态码对 web api 核心没有影响
- json - jupyter上的folium空白等值线图,可能的JSON格式问题
- sql - sqlalchemy Teradata 的“用户 ID、密码或帐户无效”
- nginx - Letsencrypt 和 Nginx 未能通过 acme 挑战
- c# - 如何在 selenium Web 驱动程序 C# 中编写运行时 XPATH 查询