如何从半屏Sheet推送全屏SFSafariViewController?
解决方案
问题出在你用NavigationLink在Sheet的NavigationView栈内推送页面,导致Sheet的导航栏与SFSafariViewController的导航栏叠加,且页面被Sheet的尺寸限制无法全屏。以下是修正方案:
核心修改点
- 移除Sheet页面(
PresentView)中的NavigationView,改用按钮触发全屏展示SFSafariViewController - 使用
.fullScreenCover替代NavigationLink,实现全屏推送效果 - 可为Sheet添加独立的导航栏(用于关闭Sheet),避免与Safari的导航栏冲突
修正后的完整代码
import SwiftUI import SafariServices struct ContentView: View { @State private var showingSheet = false var body: some View { NavigationStack { // iOS16+推荐用NavigationStack,兼容旧版可保留NavigationView VStack { Button("Show sheet") { showingSheet = true } } .frame(maxWidth: .infinity, maxHeight: .infinity) .background(Color.gray.opacity(0.2)) .sheet(isPresented: $showingSheet) { PresentView() } } } } struct PresentView: View { @Environment(\.dismiss) private var dismiss @State private var showFullScreenSafari = false var body: some View { VStack { Button("Link btn") { showFullScreenSafari = true } .foregroundColor(.blue) } .frame(maxWidth: .infinity, maxHeight: .infinity) .background(Color.gray.opacity(0.2)) .toolbar { // 给Sheet添加导航栏关闭按钮 ToolbarItem(placement: .navigationBarTrailing) { Button("Cancel") { dismiss() } } } .navigationTitle("Sheet") // Sheet的导航标题(可选) .fullScreenCover(isPresented: $showFullScreenSafari) { SafariView(url: URL(string: "https://github.com/")!) } } } struct SafariView: UIViewControllerRepresentable { let url: URL func makeUIViewController(context: Context) -> SFSafariViewController { return SFSafariViewController(url: url) } func updateUIViewController(_ uiViewController: SFSafariViewController, context: Context) {} }
效果说明
- 点击主页面的"Show sheet"会弹出半屏Sheet,Sheet带有独立的导航栏(含关闭按钮)
- 点击Sheet内的"Link btn",会全屏弹出
SFSafariViewController,仅显示Safari自身的导航栏 - 关闭Safari后会回到Sheet页面,关闭Sheet则回到主页面
内容的提问来源于stack exchange,提问作者mars
相关产品推荐
相关产品推荐

