UIKit跳转到SwiftUI
swift
public struct DemoSwiftUIController: View {
public var body: some View {
Text("this is a swiftui controller!")
}
public init() {}
}
// UIKit页面
@IBAction func pushSwiftUIController(_ sender: Any) {
let swiftUIViewController = UIHostingController(rootView: DemoSwiftUIController())
self.navigationController?.pushViewController(swiftUIViewController, animated: true)
}
public struct DemoSwiftUIController: View {
public var body: some View {
Text("this is a swiftui controller!")
}
public init() {}
}
// UIKit页面
@IBAction func pushSwiftUIController(_ sender: Any) {
let swiftUIViewController = UIHostingController(rootView: DemoSwiftUIController())
self.navigationController?.pushViewController(swiftUIViewController, animated: true)
}
加载SwiftUI
通过添加UIHostingController.view来实现
swift
@IBAction func addSwiftUIView(_ sender: Any) {
let hostingController = UIHostingController(rootView: SwiftUIViewComponent())
addChildViewController(hostingController)
self.view.addSubview(hostingController.view)
// 用于在将`子视图控制器`添加到 `父视图控制器(self)` 或从 `父视图控制器中移除(nil)` 时进行状态更新的方法
// 如果不调用子视图控制器就无法检测到它是否移动到了父视图控制器(无法知道生命周期)
hostingController.didMove(toParent: self)
hostingController.view.backgroundColor = UIColor.red
hostingController.view.frame = CGRect(x: 100, y: 200, width: 300, height: 80)
}
@IBAction func addSwiftUIView(_ sender: Any) {
let hostingController = UIHostingController(rootView: SwiftUIViewComponent())
addChildViewController(hostingController)
self.view.addSubview(hostingController.view)
// 用于在将`子视图控制器`添加到 `父视图控制器(self)` 或从 `父视图控制器中移除(nil)` 时进行状态更新的方法
// 如果不调用子视图控制器就无法检测到它是否移动到了父视图控制器(无法知道生命周期)
hostingController.didMove(toParent: self)
hostingController.view.backgroundColor = UIColor.red
hostingController.view.frame = CGRect(x: 100, y: 200, width: 300, height: 80)
}
可进行简单封装:
swift
import SwiftUI
public protocol SwiftSupportController {}
public extension SwiftSupportController where Self: UIViewController {
/// 增加swiftUIView
/// - Parameter content: swiftUI view
/// - Returns: View
func addSwiftUIView<Content>(content: Content) -> UIView where Content: View {
let hostingController = self.swiftUIController(content: content)
self.view.addSubview(hostingController.view)
addChildViewController(hostingController)
hostingController.didMove(toParentViewController: self)
return hostingController.view
}
/// 获取swiftui的 UIHostingController
/// - Parameter content: swiftUI view
/// - Returns: View
func swiftUIController<Content>(content: Content) -> UIViewController where Content: View {
return UIHostingController(rootView: content)
}
}
import SwiftUI
public protocol SwiftSupportController {}
public extension SwiftSupportController where Self: UIViewController {
/// 增加swiftUIView
/// - Parameter content: swiftUI view
/// - Returns: View
func addSwiftUIView<Content>(content: Content) -> UIView where Content: View {
let hostingController = self.swiftUIController(content: content)
self.view.addSubview(hostingController.view)
addChildViewController(hostingController)
hostingController.didMove(toParentViewController: self)
return hostingController.view
}
/// 获取swiftui的 UIHostingController
/// - Parameter content: swiftUI view
/// - Returns: View
func swiftUIController<Content>(content: Content) -> UIViewController where Content: View {
return UIHostingController(rootView: content)
}
}
SwiftUI中使用UIKit
可以参考: [通过抽离SwiftUI代码的方式提高预览速度]
UIKit 和SwiftUI传值交互示例
SwiftUI:
swift
import SwiftUI
public class DemoTitleModel: ObservableObject {
@Published public var text: String
public init(text: String) {
self.text = text
}
}
public struct DemoChangeTitle: View {
@ObservedObject var model: DemoTitleModel
public var body: some View {
Text(model.text)
}
public init(model: DemoTitleModel) {
self.model = model
}
}
#Preview {
let model = DemoTitleModel(text: "default text")
return DemoChangeTitle(model: model)
}
import SwiftUI
public class DemoTitleModel: ObservableObject {
@Published public var text: String
public init(text: String) {
self.text = text
}
}
public struct DemoChangeTitle: View {
@ObservedObject var model: DemoTitleModel
public var body: some View {
Text(model.text)
}
public init(model: DemoTitleModel) {
self.model = model
}
}
#Preview {
let model = DemoTitleModel(text: "default text")
return DemoChangeTitle(model: model)
}
UIKit:
swift
import SwiftUI
import UIKit
/// swiftui和uikit交互
class InteractSwiftUIViewController: UIViewController, SwiftSupportController {
@ObservedObject var viewModel = DemoTitleModel(text: "my default text")
override func viewDidLoad() {
super.viewDidLoad()
let view = addSwiftUIView(content: DemoChangeTitle(model: viewModel))
view.frame = CGRect(x: 100, y: 100, width: 200, height: 100)
view.backgroundColor = UIColor.lightGray
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
viewModel.text = "\(viewModel.text) + 1"
}
}
import SwiftUI
import UIKit
/// swiftui和uikit交互
class InteractSwiftUIViewController: UIViewController, SwiftSupportController {
@ObservedObject var viewModel = DemoTitleModel(text: "my default text")
override func viewDidLoad() {
super.viewDidLoad()
let view = addSwiftUIView(content: DemoChangeTitle(model: viewModel))
view.frame = CGRect(x: 100, y: 100, width: 200, height: 100)
view.backgroundColor = UIColor.lightGray
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
viewModel.text = "\(viewModel.text) + 1"
}
}