如何在SwiftUI中使用SFSafariViewController?

Nat*_*cks 1 safari ios swift swiftui

我正在尝试SFSafariViewController从a 呈现一个,NavigationButton但是我不确定如何使用SwiftUI。

在UIKit中,我只会做:

let vc = SFSafariViewController(url: URL(string: "https://google.com"), entersReaderIfAvailable: true)
    vc.delegate = self

    present(vc, animated: true)
Run Code Online (Sandbox Code Playgroud)

bhe*_*inz 50

Matteo Pacini 帖子的补充,.presentation(Modal()) 已被 iOS 13 的版本删除。此代码应该可以工作(在 Xcode 11.3、iOS 13.0 - 13.3 中测试):

import SwiftUI
import SafariServices

struct ContentView: View {
    // whether or not to show the Safari ViewController
    @State var showSafari = false
    // initial URL string
    @State var urlString = "https://duckduckgo.com"

    var body: some View {
        Button(action: {
            // update the URL if you'd like to
            self.urlString = "https://duckduckgo.com"
            // tell the app that we want to show the Safari VC
            self.showSafari = true
        }) {
            Text("Present Safari")
        }
        // summon the Safari sheet
        .sheet(isPresented: $showSafari) {
            SafariView(url:URL(string: self.urlString)!)
        }
    }
}

struct SafariView: UIViewControllerRepresentable {

    let url: URL

    func makeUIViewController(context: UIViewControllerRepresentableContext<SafariView>) -> SFSafariViewController {
        return SFSafariViewController(url: url)
    }

    func updateUIViewController(_ uiViewController: SFSafariViewController, context: UIViewControllerRepresentableContext<SafariView>) {

    }

}
Run Code Online (Sandbox Code Playgroud)

  • @gsamerica 请参阅 [BetterSafariView](https://github.com/stleamist/BetterSafariView)。它以全屏“SFSafariViewController”作为其原始风格。 (3认同)

Mat*_*ini 5

SFSafariViewControllerUIKit组件,因此您需要制作它UIViewControllerRepresentable

有关如何将组件桥接到的更多详细信息,请参阅集成SwiftUI WWDC 19视频。UIKitSwiftUI

struct SafariView: UIViewControllerRepresentable {

    let url: URL

    func makeUIViewController(context: UIViewControllerRepresentableContext<SafariView>) -> SFSafariViewController {
        return SFSafariViewController(url: url)
    }

    func updateUIViewController(_ uiViewController: SFSafariViewController,
                                context: UIViewControllerRepresentableContext<SafariView>) {

    }

}
Run Code Online (Sandbox Code Playgroud)

警告说明:SFSafariViewController是要显示在另一个视图控制器之上,而不是推入导航堆栈中。

它还具有一个导航栏,这意味着如果按下视图控制器,将看到两个导航栏。

在此处输入图片说明

如果以模态呈现,它似乎可以工作-尽管有故障。

struct ContentView : View {

    let url = URL(string: "https://www.google.com")!

    var body: some View {
        EmptyView()
        .presentation(Modal(SafariView(url:url)))
    }
}
Run Code Online (Sandbox Code Playgroud)

看起来像这样:

在此处输入图片说明

我建议通过协议移植WKWebView到,并代替它使用。SwiftUIUIViewRepresentable


Stl*_*ist 5

使用BetterSafariView,您可以SFSafariViewController在 SwiftUI 中轻松呈现。它按照 Apple 的预期运行良好,而不会失去其原始的推送过渡和滑动关闭手势。

用法

.safariView(isPresented: $presentingSafariView) {
    SafariView(url: URL("https://github.com/")!)
}
Run Code Online (Sandbox Code Playgroud)

例子

import SwiftUI
import BetterSafariView

struct ContentView: View {
    
    @State private var presentingSafariView = false
    
    var body: some View {
        Button("Present SafariView") {
            self.presentingSafariView = true
        }
        .safariView(isPresented: $presentingSafariView) {
            SafariView(
                url: URL(string: "https://github.com/stleamist/BetterSafariView")!,
                configuration: SafariView.Configuration(
                    entersReaderIfAvailable: false,
                    barCollapsingEnabled: true
                )
            )
        }
    }
}
Run Code Online (Sandbox Code Playgroud)