swift - 如何从 SwiftUI 中的 UIViewRepresentable 外部调用 UIView 上的方法?

标签 swift mkmapview swiftui

我希望能够将对 UIViewRespresentable(或者可能是 Coordinator)方法的引用传递给父 View。我能想到的唯一方法是在父级 View 结构上创建一个字段,其中包含一个类,然后我将该类传递给子级,该子级充当此行为的委托(delegate)。但这似乎很冗长。

这里的用例是能够从标准的 SwiftUI Button 调用一个方法,该方法将缩放 MKMapView 中的当前位置,MKMapView 隐藏在 UIViewRepresentable 在树的其他地方。我不希望当前位置成为 Binding,因为我希望此操作是一次性的,而不是经常反射(reflect)在 UI 中。

TL;DR 至少对于 UIViewRepresentable 而言,是否有一种标准方法可以让父级在 SwiftUI 中获取对子级的引用? (我知道这在大多数情况下可能是不可取的,并且在很大程度上不符合 SwiftUI 模式)。

最佳答案

我自己也在努力解决这个问题,下面是使用 CombinePassthroughSubject 的方法:

struct OuterView: View {
  private var didChange = PassthroughSubject<String, Never>()

  var body: some View {
    VStack {
      // send the PassthroughSubject over
      Wrapper(didChange: didChange)
      Button(action: {
        self.didChange.send("customString")
      })
    }
  }
}

// This is representable struct that acts as the bridge between UIKit <> SwiftUI
struct Wrapper: UIViewRepresentable {
  var didChange: PassthroughSubject<String, Never>
  @State var cancellable: AnyCancellable? = nil

  func makeUIView(context: Context) → SomeView {
    let someView = SomeView()
    // ... perform some initializations here

    // doing it in `main` thread is required to avoid the state being modified during
    // a view update
    DispatchQueue.main.async {
      // very important to capture it as a variable, otherwise it'll be short lived.
      self.cancellable = didChange.sink { (value) in
        print("Received: \(value)")
        
        // here you can do a switch case to know which method to call
        // on your UIKit class, example:
        if (value == "customString") {
          // call your function!
          someView.customFunction()
        }
      }
    }

    return someView
  }
}

// This is your usual UIKit View
class SomeView: UIView {
  func customFunction() {
    // ...
  }
}

关于swift - 如何从 SwiftUI 中的 UIViewRepresentable 外部调用 UIView 上的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58039286/

相关文章:

ios - Swift JSON 崩溃与零

xcode - 如何让应用程序购买工作

swift - 永远不会调用 TextField onCommit

ios - Realm 移动平台适合管理小公司的服务吗?

swift - 按下按钮时将 UIViewController .xib 添加到 UIViewController

objective-c - 在没有 Internet 访问的情况下显示 MKMapView

ios - MKMapView 与零高度约束斗争 - map View 的 edgeInsets?

ios - 如何将MKMapView缩放到用户的当前位置

ios - 使用全屏图像和导航查看链接

ios - 无法推断复杂的闭包返回类型 SwiftUI ForEach