Swiftui 从半模型表推送到全屏 SFSafariViewController

问题描述 投票:0回答:3

我想从半模型表推送到全屏 SFSafariViewController。

我想要的是首先呈现一个带有“Link Btn”的工作表,单击“Link Btn”以推送到全屏网页视图以显示网页,如下所示:

我的代码如下:

import SwiftUI
import SafariServices

struct ContentView: View {
    @State private var showingVC = false
    var body: some View {
        NavigationView() {
            VStack() {
                Button(action: {
                    self.showingVC = true
                }, label: {
                    Text("Show sheet")
                })
            }
            .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
            .background(Color.gray.opacity(0.2))
            .sheet(isPresented: $showingVC) {
                PresentView()
            }
        }
        
    }
}

struct PresentView: View {
    var body: some View {
        NavigationView() {
            VStack() {
                NavigationLink(destination: SafariView(url: URL(string: "https://github.com/")!)) {
                    Text("Link btn")
                        .foregroundColor(.blue)
                }
            }
            .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
            .background(Color.gray.opacity(0.2))
        }
    }
}

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

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

    }
}

但是最终的网页不是全屏的,并且有两个导航栏,如下所示:

如何从呈现的工作表视图中推送到只有一个导航栏的全屏 Web 视图?

swift swiftui wkwebview swiftui-navigationlink swiftui-navigationview
3个回答
3
投票

需要的不是链接,而是

fullScreenCover
,比如

struct PresentView: View {
    @State private var showSafari = false
    var body: some View {
        NavigationView() {
            VStack() {
                Button {
                    showSafari.toggle()    // << here !!
                } label: {
                    Text("Link btn")
                }
            }
            .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
            .background(Color.gray.opacity(0.2))
            .fullScreenCover(isPresented: $showSafari) {  
                SafariView(url: URL(string: "https://github.com/")!)  // << here !!
            }
        }
    }
}

使用 Xcode 13.4 / iOS 15.5 进行测试


1
投票

澄清你的问题后,这里有一个方法: 第二个按钮必须激活主视图中的链接并关闭工作表。

struct ContentView: View {
    
    @State private var showingVC = false
    @State private var showingBrowser = false

    var body: some View {
        NavigationView() {
            VStack() {
                Button("Show sheet") { self.showingVC = true }
                
                NavigationLink("",
                               destination: SafariView(url: URL(string: "https://github.com/")!),
                               isActive: $showingBrowser)
            }
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .background(Color.gray.opacity(0.2))
            .sheet(isPresented: $showingVC) {
                PresentView(showingBrowser: $showingBrowser) // pass binding
            }
        }
    }
}


struct PresentView: View {

    @Environment(\.dismiss) private var dismiss
    @Binding var showingBrowser: Bool

    var body: some View {
        NavigationView() {
            VStack() {
                Button("Link btn") {
                    showingBrowser = true // activate browser link back in main view
                    dismiss() // dismiss sheet
                }
            }
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .background(Color.gray.opacity(0.2))
        }
    }
}

0
投票

日复一日,我找到了解决方案B,如下所示:

import SwiftUI
import SafariServices

struct ContentView: View {
    @State private var showingVC = false
    var body: some View {
        //SafariView(url: URL(string: "https://github.com/")!)
        NavigationView() {
            ZStack() {
                VStack() {
                    Button(action: {
                        self.showingVC = true
                    }, label: {
                        Text("Show sheet")
                    })
                }
                .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
                .background(Color.gray.opacity(0.2))
                .sheet(isPresented: $showingVC) {
                    PresentView()
                }
            }
            .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
        }
    }
}

struct PresentView: View {
    @State private var showSafari = false
    var body: some View {
        NavigationView() {

            VStack() {
                Button {
                    let url: URL = URL(string: "https://github.com/")!
                    let currentVC = UIViewController.currentViewController()
                    let vc = SFSafariViewController(url: url)
                    currentVC?.present(vc, animated: true)  // << here !!
                } label: {
                    Text("Link btn")
                }
            }
            .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
            .background(Color.gray.opacity(0.2))
        }
    }
}

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

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

    }
}


extension UIViewController {
     /// MARK : - 当前顶层控制器
     class func currentViewController() -> UIViewController? {
        let window = UIApplication.shared.windows.filter {$0.isKeyWindow}.first
        var currentVC = window?.rootViewController
        while ((currentVC?.presentedViewController) != nil) {
            currentVC = currentVC?.presentedViewController
        }
        if (currentVC is UITabBarController) {
            currentVC = (currentVC as? UITabBarController)?.selectedViewController
        }
        if (currentVC is UINavigationController) {
            currentVC = (currentVC as? UINavigationController)?.topViewController
        }
        return currentVC
    }
}

如果您在工作表模型中呈现 SFSafariViewController,您将获得全屏 SFSafariViewController 并从左向右滑动....

该死的苹果王!

© www.soinside.com 2019 - 2024. All rights reserved.