如何在UIKit项目中调用SwiftUI自定义组件框架?
在UIKit项目中集成SwiftUI组件框架并在TableView中展示
最初使用UIKit进行开发,后因需求转向SwiftUI。目前拥有一个包含按钮、文本框等自定义组件的SwiftUI框架,已将其添加到UIKit项目并创建了工作区,希望在TableView中逐个展示这些组件,框架中包含ComponentFactory类可根据标识符返回对应组件:
public class ComponentFactory { var identifier: String public static let shared = ComponentFactory(identifier: "") public init (identifier: String) { self.identifier = identifier } @ViewBuilder public func createView(identifier: String) -> some View { switch identifier { case "txt": TextComponent() case "btn": ButtonComponent(action: {}) case "img": ImageComponent() default: Text("Hey, check identifier") } } }
核心思路:用UIHostingController桥接SwiftUI与UIKit
UIKit通过UIHostingController可以直接承载SwiftUI视图,这是两者交互的核心工具。我们需要把SwiftUI组件包裹成UIHostingController,再嵌入到UIKit的TableViewCell中。
步骤1:优化ComponentFactory(可选但更合理)
原代码中ComponentFactory的identifier成员变量无实际作用,因为createView方法已接收标识符参数,可简化为:
public class ComponentFactory { public static let shared = ComponentFactory() private init() {} // 私有化初始化,确保单例唯一 @ViewBuilder public func createView(identifier: String) -> some View { switch identifier { case "txt": TextComponent() case "btn": ButtonComponent(action: { print("Button tapped!") }) case "img": ImageComponent() default: Text("Hey, check identifier") } } }
步骤2:自定义UITableViewCell承载SwiftUI组件
创建自定义Cell,内部嵌入UIHostingController的视图,通过自动布局让其填充整个cell的contentView:
import UIKit import SwiftUI class SwiftUIComponentCell: UITableViewCell { private var hostingController: UIHostingController<AnyView>? func configure(with identifier: String) { // 移除旧的hosting controller视图 hostingController?.view.removeFromSuperview() hostingController = nil // 通过工厂创建SwiftUI视图并包裹为AnyView(类型擦除) let swiftUIView = ComponentFactory.shared.createView(identifier: identifier) hostingController = UIHostingController(rootView: AnyView(swiftUIView)) guard let hostView = hostingController?.view else { return } // 添加到contentView并设置约束 contentView.addSubview(hostView) hostView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ hostView.topAnchor.constraint(equalTo: contentView.topAnchor), hostView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor), hostView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor), hostView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor) ]) } }
步骤3:配置TableView的数据源与自适应高度
在ViewController中设置TableView,注册自定义Cell,并处理数据源。开启自动高度计算以适配SwiftUI组件的动态高度:
import UIKit class ViewController: UIViewController { private let tableView = UITableView() // 模拟组件标识符列表 private let componentIdentifiers = ["txt", "btn", "img", "unknown"] override func viewDidLoad() { super.viewDidLoad() setupTableView() } private func setupTableView() { view.addSubview(tableView) tableView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ tableView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor), tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor), tableView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor) ]) // 注册自定义Cell tableView.register(SwiftUIComponentCell.self, forCellReuseIdentifier: "SwiftUIComponentCell") // 设置自动高度 tableView.rowHeight = UITableView.automaticDimension tableView.estimatedRowHeight = 100 // 预估高度提升性能 tableView.dataSource = self } } extension ViewController: UITableViewDataSource { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return componentIdentifiers.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "SwiftUIComponentCell", for: indexPath) as! SwiftUIComponentCell let identifier = componentIdentifiers[indexPath.row] cell.configure(with: identifier) return cell } }
注意事项
- 确保SwiftUI组件框架已正确添加到UIKit项目的工作区,且在target依赖中包含该框架。
- 若SwiftUI组件有动态高度变化(如可变文本),UIHostingController会自动处理,TableView的
automaticDimension会根据实际内容计算高度。 - 如需在SwiftUI组件中回调UIKit代码,可通过闭包传递(比如ButtonComponent的action参数,在configure时传入UIKit侧逻辑)。
内容的提问来源于stack exchange,提问作者swifter_472
相关产品推荐
相关产品推荐

