SwiftUIでネストされたUIViewを制御する慣用的な方法は何ですか

SwiftUIでネストされたUIViewを制御する慣用的な方法は何ですか

タグ:



質問

SwiftUIビュー階層にWKWebViewを表示したいのですが、SwiftUIに実装されているボタンを使用してWKWebViewを制御したいと思います。

これを行うには、 UIViewRepresentable を実装して WKWebView をラップするSwiftUI WebView クラスを作成します。

struct WebView: UIViewRepresentable {

func makeUIView(context: UIViewRepresentableContext<WebView>) -> WKWebView {
return WKWebView(frame: .zero)
}

func updateUIView(_ uiView: WKWebView, context: UIViewRepresentableContext<WebView>) {
// Update WKWebView here if necessary
}
}

…そしてそれを次のように使用します…

struct BrowserView: View {
var body: some View {
VStack {
WebView()

// Footer
HStack {
Button(action: {
// When this is called, I want to somehow call .goBack()
// on the WKWebView.
}) {
Image(systemName: “chevron.left”)
}


} // HStack
} // VStack
}
}

ユーザーがボタンをタップしたときに、どういうわけか WKWebView で goBack を呼び出したいと思います。 SwiftUIでこれを慣用的に行うにはどうすればよいですか?

私が考えたアプローチは、もろいか、慣用的なSwiftUIではないと思います…

  • ユーザーがバインディングで「戻る」をクリックした回数を表します。 WebViewにそのバインディングをリッスンさせ、それが増加したら元に戻ります。

  • BrowserView に MutableWebViewAPI のようなオブジェクトを作成させ、構築時に WebView に渡します。 WebView はこのオブジェクトをリッスンするため、 BrowserView が MutableWebViewAPI.goBack() のようなものを呼び出すと、 WebView も同じように動作します。

ベストアンサー

親ビューに PassthroughSubject を作成し、子 WebView のイベントをサブスクライブすることで、Combineの機能を活用するのが最善の方法だと思います。

まず、 UIViewReprsentable に、 WebView に送信する利用可能なイベントをキャプチャする構造体を作成します。

struct WebView: UIViewReprsentable {

enum WebEvent {
case back
case forward
}

let eventPublisher: AnyPublisher<WebEvent, Never>

init(eventPublisher: AnyPublisher<WebEvent, Never>) {
self.eventPublisher = eventPublisher

eventPublisher.sink { event in
// forward the appropriate event to your underlying WKWebView
}
}
}

次に、親で PassthroughSubject を作成して、これらのイベントを作成します。

struct ParentView: View {
private let eventSender = PassthroughSubject<WebView.WebEvent, Never>()

var body: some View {
VStack {
Button(“Back”) {
self.eventSender.send(.back)
}
Button(“Forward”) {
self.eventSender.send(.forward)
}

WebView(eventPublisher: eventSender.eraseToAnyPublisher())
}
}
}






source
Clojureでマップをネストする慣用的な方法は何ですか?
HaskellでネストされたIOを処理する慣用的な方法
Clojureのネストされたマップで複数のキー/値を関連付ける慣用的な方法は何ですか?
ネストされたルートであるがネストされていないテンプレートの慣用的なEmberjs
ネストされた状態ブランチをテストする慣用的な方法はありますか?
ネストされたマッチは慣用的なRustで悪い習慣ですか?
swiftUIでは、UIView内またはUIViewとしてUIHostingControllerを使用する方法は?
rootsagaを起動する慣用的な方法は何ですか?
これを書くより慣用的なRubyの方法は何ですか?
refでPersistentQueueをポップする慣用的な方法は何ですか?
Rating