我想从半模型表推送到全屏 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 视图?
需要的不是链接,而是
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 进行测试
澄清你的问题后,这里有一个方法: 第二个按钮必须激活主视图中的链接并关闭工作表。
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))
}
}
}
日复一日,我找到了解决方案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 并从左向右滑动....
该死的苹果王!