程序问答   发布时间:2022-06-01  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了复杂的 UIKit + SwiftUI 界面通过 UIViewControllerRepresentable大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决复杂的 UIKit + SwiftUI 界面通过 UIViewControllerRepresentable?

开发过程中遇到复杂的 UIKit + SwiftUI 界面通过 UIViewControllerRepresentable的问题如何解决?下面主要结合日常开发的经验,给出你关于复杂的 UIKit + SwiftUI 界面通过 UIViewControllerRepresentable的解决方法建议,希望对你解决复杂的 UIKit + SwiftUI 界面通过 UIViewControllerRepresentable有所启发或帮助;

我正在构建一个相机应用程序,其中包含 SwiftUI(父级)中的所有 UI,其中包含一个包含所有录制功能的 UIKit 控制器。 UI 非常复杂,所以如果可能的话,希望在项目中保持这种结构。

UIKit 类有一些函数,例如 startRecord() stopRecord(),我想从 SwiftUI 视图中触发它们。出于这个原因,我想从我的 SwiftUI 视图中“调用”UIKit 函数。

我正在试验 UIVIEwControllerRepresentable,能够对全局变量更改执行更新,但我仍然无法调用我想从 SwiftUI 父级触发的各个函数。

这是 SwiftUI 文件:

init(MetalVIEw: MetalVIEwController?) {
    self.MetalVIEw = MetalVIEwController(appStatus: appStatus)
}

var body: some VIEw {
    
    ZStack {
        
        // - Camera vIEw
        MetalVIEw
            .edgesIgnoringSafeArea(.top)
            .padding(.bottom,54)
        
        vstack {
            
            
            LateralMenuVIEw(appStatus: appStatus,filtertooltipShowing: $_filtertooltipShowing)
            
            button("RECORD",action: {
                print("record button pressed")
                MetalVIEw?.mymetalDelegate.switchRecording(). // <-- Not sure about this
            })

这是 MetalVIEwController:

protocol MetalVIEwControllerDelegate {
    func switchRecording()
}

// MARK: - The secret sauce for loading the MetalVIEw (UIKit -> SwiftUI)
struct MetalVIEwController: UIVIEwControllerRepresentable {

var appStatus: AppStatus
typealias UIVIEwControllerType = MetalController
var mymetalDelegate: MetalVIEwControllerDelegate!

func makeCoordinator() -> Coordinator {
    Coordinator(MetalVIEwController: self)
}

func makeUIVIEwController(context: UIVIEwControllerRepresentableContext<MetalVIEwController>) -> MetalController {
    let controller = MetalController(appStatus: appStatus)
    return controller
}

func updateUIVIEwController(_ controller: MetalController,context: UIVIEwControllerRepresentableContext<MetalVIEwController>) {
    controller.changeFilter()
}

class Coordinator: NSObject,MetalVIEwControllerDelegate {
    var controller: MetalVIEwController

    init(MetalVIEwController: MetalVIEwController) {
        controller = MetalVIEwController
    }
    func switchRecording() {
        print("just tesTing")
    }
}

}

和 UIKit 控制器...

class MetalController: UIVIEwController {

var _mydelegate: MetalVIEwControllerDelegate?
...
overrIDe func vIEwDIDLoad() {
 ...
    self._mydelegate = self
}

extension MetalController: MetalVIEwControllerDelegate {
    func switchRecording() {
        print("THIS SHOulD BE WORKING,BUT ITS NOT")
    }
}

解决方法

我喜欢使用COR_524_11845@bine 通过ObservabLeobject 将消息传递到UIKit 视图。这样,我就可以命令式地调用它们。我没有尝试解析您的代码,而是为这个概念做了一个小例子:

import SwiftUI
import Combine

enum messageBridgemessage {
    case mymessage(parameter: int)
}

class messageBridge : ObservabLeobject {
    @Published var result = 0
    
    var messagePassthrough = PassthroughSubject<messageBridgemessage,Never>()
}

struct ContentView : View {
    @StateObject private var messageBridge = messageBridge()
    
    var body: some View {
        VStack {
            Text("Result: \(messageBridge.result)")
            Button("Add 2") {
                messageBridge.messagePassthrough.send(.mymessage(parameter: messageBridge.result))
            }
            VCRepresented(messageBridge: messageBridgE)
        }
    }
}

struct VCRepresented : UIViewControllerRepresentable {
    var messageBridge : messageBridge
    
    func makeUIViewController(context: Context) -> CustomVC {
        let vc = CustomVC()
        context.coordinator.connect(vc: vc,bridge: messageBridgE)
        return vc
    }
    
    func updateUIViewController(_ uiViewController: CustomVC,context: Context) {
        
    }
    
    func makeCoordinator() -> Coordinator {
        return Coordinator()
    }
    
    class Coordinator {
        private var cancellable : AnyCancellable?
        
        func connect(vc: CustomVC,bridge: messageBridgE) {
            cancellable = bridge.messagePassthrough.sink(receiveValue: { (messagE) in
                switch message {
                case .mymessage(let parameter):
                    bridge.result = vc.addTwo(input: parameter)
                }
            })
        }
    }
}

class CustomVC : UIViewController {
    func addTwo(input: int) -> Int {
        return input + 2
    }
}

在示例中,messageBridge 有一个 PassthroughSubject,可以从 UIKit 视图(或在本例中为 UIViewController)订阅。它归 ContentView 所有,并通过参数传递给 VCRepresented

VCRepresented 中,Coordinator 上有一个方法可以订阅发布者 (messagePassthrough) 并对消息采取行动。您可以通过枚举 (messageBridgemessage) 上的关联属性传递参数。如果需要,返回值可以存储在 messageBridge 上的 @Published 属性中(或者,您可以设置另一个发布者以相反方向)。

它有点冗长,但似乎是与您需要的树的任何级别(SwiftUI 视图、可表示视图、UIKit 视图等)进行通信的非常可靠的模式。

大佬总结

以上是大佬教程为你收集整理的复杂的 UIKit + SwiftUI 界面通过 UIViewControllerRepresentable全部内容,希望文章能够帮你解决复杂的 UIKit + SwiftUI 界面通过 UIViewControllerRepresentable所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签:+复杂的