SwiftUI文档型应用能否跳过文件选择器显示自定义问候视图?
如何在Swift文档型应用启动时跳过默认文件选择器并显示自定义问候窗口
不管是iOS还是macOS平台的文档型应用,都可以通过修改启动逻辑来替换默认的文件选择器,展示自定义问候界面。核心思路是:判断应用启动时是否有打开文档的请求,若无则直接加载自定义界面,并在界面中提供新建/打开文档的入口。
iOS平台实现步骤
1. 修改场景初始化逻辑(SceneDelegate)
在SceneDelegate.swift中,通过启动选项判断是否有打开文档的请求,直接设置对应的根视图控制器:
import UIKit class SceneDelegate: UIResponder, UIWindowSceneDelegate { var window: UIWindow? func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { guard let windowScene = (scene as? UIWindowScene) else { return } let window = UIWindow(windowScene: windowScene) self.window = window // 检查是否有打开文档的URL请求 if connectionOptions.urlContexts.isEmpty { // 加载自定义问候界面 let greetingVC = GreetingViewController() window.rootViewController = greetingVC } else { // 有文档打开请求时,使用默认文档浏览器 let docBrowser = DocumentBrowserViewController() window.rootViewController = docBrowser } window.makeKeyAndVisible() } }
2. 实现自定义问候界面
创建GreetingViewController,添加新建/打开文档的按钮,并绑定对应逻辑:
import UIKit class GreetingViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .white // 新建文档按钮 let newDocBtn = UIButton(type: .system) newDocBtn.setTitle("新建空白文档", for: .normal) newDocBtn.titleLabel?.font = .systemFont(ofSize: 18) newDocBtn.frame = CGRect(x: 80, y: 250, width: view.bounds.width - 160, height: 50) newDocBtn.addTarget(self, action: #selector(showCreateMenu), for: .touchUpInside) view.addSubview(newDocBtn) // 打开文档按钮 let openDocBtn = UIButton(type: .system) openDocBtn.setTitle("打开已有文档", for: .normal) openDocBtn.titleLabel?.font = .systemFont(ofSize: 18) openDocBtn.frame = CGRect(x: 80, y: 320, width: view.bounds.width - 160, height: 50) openDocBtn.addTarget(self, action: #selector(showFilePicker), for: .touchUpInside) view.addSubview(openDocBtn) } @objc private func showCreateMenu() { // 切换到文档浏览器并弹出新建菜单 let docBrowser = DocumentBrowserViewController() docBrowser.modalPresentationStyle = .fullScreen present(docBrowser, animated: true) { docBrowser.presentDocumentCreationMenu(at: nil, animated: true) } } @objc private func showFilePicker() { // 切换到文档浏览器并弹出文件选择器 let docBrowser = DocumentBrowserViewController() docBrowser.modalPresentationStyle = .fullScreen present(docBrowser, animated: true) { docBrowser.presentDocumentPicker(at: nil, animated: true) } } }
macOS平台实现步骤
1. 修改应用启动逻辑(AppDelegate)
在AppDelegate.swift中,阻止默认的打开对话框,并加载自定义问候窗口:
import Cocoa @main class AppDelegate: NSObject, NSApplicationDelegate { func applicationDidFinishLaunching(_ aNotification: Notification) { // 阻止默认打开对话框弹出 NSApp.setActivationPolicy(.regular) // 创建并显示自定义问候窗口 let greetingWindow = NSWindow( contentRect: NSRect(x: 0, y: 0, width: 400, height: 300), styleMask: [.titled, .closable, .miniaturizable], backing: .buffered, defer: false ) greetingWindow.center() greetingWindow.title = "欢迎使用" let greetingVC = GreetingViewController() greetingWindow.contentViewController = greetingVC greetingWindow.makeKeyAndOrderFront(nil) } // 应用重新激活且无可见窗口时,再次显示问候窗口 func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool) -> Bool { if !flag { let greetingWindow = NSWindow( contentRect: NSRect(x: 0, y: 0, width: 400, height: 300), styleMask: [.titled, .closable, .miniaturizable], backing: .buffered, defer: false ) greetingWindow.center() greetingWindow.title = "欢迎使用" let greetingVC = GreetingViewController() greetingWindow.contentViewController = greetingVC greetingWindow.makeKeyAndOrderFront(nil) } return true } }
2. 实现自定义问候界面
创建GreetingViewController,添加功能按钮并绑定文档操作逻辑:
import Cocoa class GreetingViewController: NSViewController { override func viewDidLoad() { super.viewDidLoad() view.wantsLayer = true view.layer?.backgroundColor = NSColor.white.cgColor // 新建文档按钮 let newDocBtn = NSButton(title: "新建空白文档", target: self, action: #selector(createNewDocument)) newDocBtn.frame = NSRect(x: 80, y: 150, width: 240, height: 40) view.addSubview(newDocBtn) // 打开文档按钮 let openDocBtn = NSButton(title: "打开已有文档", target: self, action: #selector(openDocument)) openDocBtn.frame = NSRect(x: 80, y: 90, width: 240, height: 40) view.addSubview(openDocBtn) } @objc private func createNewDocument() { let savePanel = NSSavePanel() // 替换成你自定义的文档类型UTI savePanel.allowedContentTypes = [.init("com.yourapp.yourdoctype")] savePanel.begin { [weak self] result in guard result == .OK, let url = savePanel.url else { return } let doc = YourDocument() // 替换成你的NSDocument子类 doc.save(to: url, ofType: savePanel.allowedContentTypes[0].identifier) { success in if success { doc.makeWindowControllers() doc.showWindows() } } self?.view.window?.close() } } @objc private func openDocument() { let openPanel = NSOpenPanel() openPanel.allowedContentTypes = [.init("com.yourapp.yourdoctype")] openPanel.begin { [weak self] result in guard result == .OK, let url = openPanel.url else { return } let doc = YourDocument() doc.read(from: url, ofType: openPanel.allowedContentTypes[0].identifier) { success in if success { doc.makeWindowControllers() doc.showWindows() } } self?.view.window?.close() } } }
内容的提问来源于stack exchange,提问作者Bowen Cui
相关产品推荐
相关产品推荐

