SwiftUI 与 UIKit 混用

UIKit 到 SwiftUI

  1. 用实现了 UIViewRepresentable 协议的 “final class” 或是 “struct”,都可以直接作为 SwiftUI里的 View 来使用。样例代码如下: UIKit 里:
final class ButtonForSwiftUI : UIViewRepresentable {
    
    var btn : UIButton = UIButton(type: .system)
    
    //当SwiftUI第一次初始化 ButtonForSwiftUI时 会调用
    func makeUIView(context: Context) -> UIButton {
        btn.setTitle("Button1", for: .normal)
        btn.setTitleColor(.green, for: .normal)
        btn.backgroundColor = .black
        btn.addTarget(self, action: #selector(onClick), for: .touchUpInside)
        return btn
    }
    
   //当SwiftUI 初始化或刷新view时,如果用到了ButtonForSwiftUI,就会调用
    func updateUIView(_ uiView: UIButton, context: Context) {
        //从 context.coordinator 来访问创建的 DoWithAction 实例
    }
    
    //创建一个专门处理数据的实例
    func makeCoordinator() -> DoWithAction {
        DoWithAction(self)
    }
    
    @objc private func onClick() {
        print("\(self)")
    }
   //声明 数据处理类
    class DoWithAction {
        var control : ButtonForSwiftUI
        init(_ c : ButtonForSwiftUI) {
            control = c
        }
    }
    
}

SwiftUI里:

ButtonForSwiftUI().frame(width: 100, height: 50, alignment: .leading)

SwiftUI 到 UIKit

使用 SwiftUI 的View来创建 UIHostingController,然后使用 UIHostingController的view属性即可。 样例代码:

let swiftUIVC = UIHostingController(rootView: SwiftUIView())
swiftUIVC.view.frame = CGRect(x: 50, y: 200, width: 200, height: 200)

Objective-C 使用SwiftUI

由于 SwiftUI 对OC是不能直接使用的,那么需要用Swift 在中间搭桥,由Swift 创建 UIHostingController,作为UIViewController 返回给OC来使用。 样例代码:

Objective-C

UIViewController * vc = [SwiftUIFactory vc_swiftUI];
[self presentViewController:vc animated:YES completion:NULL];

Swift

@objc class SwiftUIFactory : NSObject {
    @objc class func vc_swiftUI() -> UIViewController {
        return UIHostingController(rootView: SwiftUIView())
    }
}

SwiftUI和OC之间可以通过传入的closure 来通讯。