马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
标题形貌
在 SwiftUI 中嵌套利用 UIKit 的 UITableView 时,你大概会遇到一个常见的 Bug:UITableView 的高度没有准确设置,导致内容无法正常滚动,尤其是滚动到页面底部时。
核心标题在于 SwiftUI 和 UIKit 的布局机制差异。SwiftUI 利用声明式布局体系,而 UIKit 利用传统的视图条理布局。假如没有明白告诉 UITableView 应该占用多少高度,UIKit 中的 UITableView 大概会默认按照父视图的尺寸盘算,忽略 SwiftUI 布局中的其他组件。因此,UITableView 的高度和滚动活动就会出现标题。
办理思绪
为了让 UITableView 在 SwiftUI 布局中可以大概准确滚动到底,我们须要:
- 动态获取 SwiftUI 中的可用高度,通过 SwiftUI 的 GeometryReader 盘算当前布局的高度。
- 将高度通报给 UIKit 中的 UITableView,确保它根据父视图的高度动态调解。
以下是一个办理该标题的demo示例
1. 利用 UIViewControllerRepresentable 桥接 SwiftUI 和 UIKit
我们起首须要创建一个桥接类,让 SwiftUI 可以大概嵌套 UIKit 组件。在这个桥接类中,我们吸取从 SwiftUI 获取的高度,然后在 UIKit 组件中利用这个高度动态调解 UITableView 的巨细。- import SwiftUI
- struct MyTableViewWrapper: UIViewControllerRepresentable {
- var height: CGFloat // 接收传递过来的高度
- func makeUIViewController(context: Context) -> MyTableViewController {
- let controller = MyTableViewController()
- controller.height = height // 设置高度
- return controller
- }
- func updateUIViewController(_ uiViewController: MyTableViewController, context: Context) {
- uiViewController.height = height // 动态更新高度
- }
- }
复制代码 MyTableViewWrapper 作为 SwiftUI 和 UIKit 的桥接类,它允许我们将 SwiftUI 的布局数据(比如高度)通报给 UIKit 中的 UITableView。
2. 在 UIViewController 中调解 UITableView 的高度
在自界说的 UIViewController 中,我们利用传入的高度来设置 UITableView 的 frame,如许可以确保 UITableView 的巨细根据 SwiftUI 的布局进办法态调解。- import UIKit
- class MyTableViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
- var height: CGFloat = 0 // 用于接收传进来的高度
-
- override func viewDidLoad() {
- super.viewDidLoad()
- // 创建 UITableView,并根据传入的高度调整它的大小
- let tableView = UITableView(frame: CGRect(x: 0, y: 0, width: view.bounds.width, height: height), style: .plain)
- tableView.dataSource = self
- tableView.delegate = self
- view.addSubview(tableView)
- }
- // UITableViewDataSource 协议实现
- func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
- return 20
- }
- func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
- let cell = UITableViewCell(style: .default, reuseIdentifier: "cell")
- cell.textLabel?.text = "Row \(indexPath.row)"
- return cell
- }
- }
复制代码 在这个自界说的 UIViewController 中,UITableView 的高度由外部传入并动态调解,如许就克制了 UITableView 默认假设本身占据全屏的标题。
3. 利用 GeometryReader 获取 SwiftUI 中的高度
接下来,我们须要在 SwiftUI 布局中利用 GeometryReader 来动态获取可用的高度,并将其通报给 UIKit 的 UITableView。- struct ContentView: View {
- var body: some View {
- GeometryReader { geometry in
- VStack {
- Text("这里是一些顶部内容")
- .padding()
- // 将当前视图的高度传递给 UIKit 中的 TableView
- MyTableViewWrapper(height: geometry.size.height * 0.6) // 比如占屏幕60%高度
- Spacer()
- }
- .padding()
- }
- }
- }
复制代码 在这个布局中,GeometryReader 会动态盘算当前视图的高度,并将这个高度通报给 MyTableViewWrapper,从而确保 UITableView 根据父视图的高度准确调解。
|