SwiftUI展示QLPreviewController时无法滑动关闭的问题求助
SwiftUI中QLPreviewController滑动关闭失效及导航栏缺失问题
在SwiftUI应用中使用QLPreviewController展示图片时,发现两个与UIKit模态展示不一致的问题:
- UIKit中模态展示QLPreviewController时,会自动将其包裹在UINavigationController中,且支持下滑图片直接关闭控制器;
- SwiftUI中通过
.fullScreenCover展示时,既没有自动添加的UINavigationController,下滑关闭的交互也完全失效。
UIKit示例代码
import UIKit import QuickLook class ViewController: UIViewController { let button = UIButton(type: .system) let url = Bundle.main.url(forResource: "foo", withExtension: "jpg")! override func viewDidLoad() { super.viewDidLoad() button.setTitle("Preview", for: .normal) self.view.addSubview(button) button.addTarget(self, action: #selector(buttonTapped(_:)), for: .touchUpInside) } override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() button.frame = CGRect(x: (view.frame.size.width - 150)/2, y: (view.frame.size.height - 44)/2, width: 150, height: 44) } @IBAction func buttonTapped(_ button: UIButton) { let previewController = QLPreviewController() previewController.dataSource = self present(previewController, animated: true) } } extension ViewController : QLPreviewControllerDataSource { @objc func numberOfPreviewItems(in controller: QLPreviewController) -> Int { return 1 } func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem { return url as QLPreviewItem } }
SwiftUI示例代码
import Foundation import SwiftUI import QuickLook struct ContentViewSimple: View { @StateObject private var previewURL = URLContainer() var body: some View { VStack { Button("Preview", action: { previewURL.url = Bundle.main.url(forResource: "foo", withExtension: "jpg") }) } .fullScreenCover(item: $previewURL.url, content: { url in QuickLookPreviewSimple(url: url) }) } } class URLContainer : ObservableObject { @Published var url : URL? } struct QuickLookPreviewSimple: UIViewControllerRepresentable { let url: URL func makeUIViewController(context: Context) -> QLPreviewController { let controller = QLPreviewController() controller.dataSource = context.coordinator return controller } func updateUIViewController(_ uiViewController: QLPreviewController, context: Context) { } func makeCoordinator() -> Coordinator { return Coordinator(parent: self) } class Coordinator : NSObject, QLPreviewControllerDataSource { let parent: QuickLookPreviewSimple init(parent: QuickLookPreviewSimple) { self.parent = parent } @objc func numberOfPreviewItems(in controller: QLPreviewController) -> Int { return 1 } func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem { return parent.url as QLPreviewItem } } }
已尝试的解决方法
- 手动将QLPreviewController包裹在UINavigationController中:可添加工具栏和Done按钮关闭,但滑动关闭仍无效;
- 使用
.sheet替代.fullScreenCover:仅能通过滑动导航栏/工具栏关闭,下滑图片的交互仍无作用; - 使用
.quickLookPreview替代.fullScreenCover:自动添加UINavigationBar,但滑动关闭功能依然不生效。
请问这是SwiftUI的遗留问题需要Apple修复,还是存在可行的解决办法?
内容的提问来源于stack exchange,提问作者Greg G
相关产品推荐
相关产品推荐

