我希望从 Swift UI 管理的按钮调用 UIKit UIViewController 内的函数
在我的 Swift UI 视图中,我有:
struct CameraView: View {
var body: some View {
cameraViewController = CameraViewController()
...
Run Code Online (Sandbox Code Playgroud)
我看到它创建了两个实例,一个像调用任何类一样直接创建,另一个由makeUIViewController
Swift UI 管理 UIKit UIViewControllers 所需的方法创建。
然而,当我将一个函数附加到 Swift UI 中的按钮时,会说,cameraViewController.takePhoto()
引用的实例不是显示的实例。
如何获取显示的具体实例?
此问题可能有多种解决方案,但无论如何,您需要找到一种方法来保留对UIViewController
. 因为 SwiftUI 视图本身非常短暂,所以您不能只在视图本身中存储引用,因为它可以随时重新创建。
使用工具:
ObservableObject——这将允许您将数据存储在类而不是结构中,并且使存储引用、连接数据等变得更容易
协调器 - 在 a 中UIViewRepresentable
,您可以使用协调器模式,该模式允许您存储对 的引用UIViewController
并与其进行通信
组合发布者——这些是完全可选的,但我选择在这里使用它们,因为它们是一种无需太多样板代码即可移动数据的简单方法。
import SwiftUI
import Combine
struct ContentView: View {
@StateObject var vcLink = VCLink()
var body: some View {
VStack {
VCRepresented(vcLink: vcLink)
Button("Take photo") {
vcLink.takePhoto()
}
}
}
}
enum LinkAction {
case takePhoto
}
class VCLink : ObservableObject {
@Published var action : LinkAction?
func takePhoto() {
action = .takePhoto
}
}
class CustomVC : UIViewController {
func action(_ action : LinkAction) {
print("\(action)")
}
}
struct VCRepresented : UIViewControllerRepresentable {
var vcLink : VCLink
class Coordinator {
var vcLink : VCLink? {
didSet {
cancelable = vcLink?.$action.sink(receiveValue: { (action) in
guard let action = action else {
return
}
self.viewController?.action(action)
})
}
}
var viewController : CustomVC?
private var cancelable : AnyCancellable?
}
func makeCoordinator() -> Coordinator {
return Coordinator()
}
func makeUIViewController(context: Context) -> CustomVC {
return CustomVC()
}
func updateUIViewController(_ uiViewController: CustomVC, context: Context) {
context.coordinator.viewController = uiViewController
context.coordinator.vcLink = vcLink
}
}
Run Code Online (Sandbox Code Playgroud)
这里发生了什么:
VCLink
是ObservableObject
我用来作为观点之间沟通的中间人ContentView
引用了VCLink
-- 当按下按钮时,Publisher
onVCLink
会将其传达给任何订阅者VCRepresented
,我存储对 ViewController 的引用并在VCLink
其中Coordinator
Coordinator
并Publisher
在其sink
方法中对存储的 执行操作ViewController
。在这个演示中,我只是打印动作。在您的示例中,您想要触发照片本身。 归档时间: |
|
查看次数: |
3416 次 |
最近记录: |