【问题标题】:SwiftUI: Change “About View” in macOS appSwiftUI:在 macOS 应用程序中更改“关于视图”
【发布时间】:2020-10-31 16:55:37
【问题描述】:

我正在使用 SwiftUI 和新的 App 生命周期构建一个 macOS 应用程序。

我很想更改“关于窗口”的内容(当您在应用程序菜单中点击“关于 DemoApp”时出现)但不知道如何:

如何将 About 视图替换为自定义视图?

【问题讨论】:

  • 其他人已经回答了这个问题,但我想留下一个指向 this 博客帖子的链接,我发现这对于将属性字符串输入现有的“关于”窗口很有用。当您只需要添加少量信息时,这非常有用。

标签: swift swiftui menuitem nsmenu about-box


【解决方案1】:

您可以这样做,但它确实需要创建一个 AppDelegate。这是您的 AppFile 的外观:

struct MyApp: App {
    @NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

    var body: some Scene {
        WindowGroup {
            MainView()
        }
        .commands {
            CommandGroup(replacing: CommandGroupPlacement.appInfo) {
                Button(action: {
                    appDelegate.showAboutPanel()
                }) {
                    Text("About My App")
                }
            }
        }
    }
}

您的 AppDelegate 应该如下所示:

class AppDelegate: NSObject, NSApplicationDelegate {
    private var aboutBoxWindowController: NSWindowController?

    func showAboutPanel() {
        if aboutBoxWindowController == nil {
            let styleMask: NSWindow.StyleMask = [.closable, .miniaturizable,/* .resizable,*/ .titled]
            let window = NSWindow()
            window.styleMask = styleMask
            window.title = "About My App"
            window.contentView = NSHostingView(rootView: AboutView())
            aboutBoxWindowController = NSWindowController(window: window)
        }

        aboutBoxWindowController?.showWindow(aboutBoxWindowController?.window)
    }
}

然后,只需创建一个名为 AboutView 的 SwiftUI 视图,它就会在您的 About 框中显示该视图。例如:

struct AboutView: View {
    var body: some View {
        VStack {
            Spacer()
            HStack {
                Spacer()
                Text("Hello, World!")
                Spacer()
            }
            Spacer()
        }
        .frame(minWidth: 300, minHeight: 300)
    }
}

【讨论】:

    【解决方案2】:

    您需要将 Credits.rtf 文件添加到您的 Bundle。这将被自动检测并插入到关于对话框中。

    你可以找到更多here

    【讨论】:

    • 非常感谢您的帮助,@davidev!如果您想将信用添加到现有的关于面板,这将非常有用。但是我问的是如何用我自己的视图完全替换那个面板,我不想只自定义默认的。
    【解决方案3】:
    import Foundation
    import SwiftUI
    
    struct AboutView: View {
        var body: some View {
            VStack(spacing: 10) {
                Image(nsImage: NSImage(named: "AppIcon")!)
                
                Text("\(Bundle.main.appName)")
                    .font(.system(size: 20, weight: .bold))
                    // Xcode 13.0 beta 2
                    //.textSelection(.enabled)
                
                Link("\(AboutView.offSiteAdr.replace(of: "http://", to: ""))", destination: AboutView.offCiteUrl )
                
                Text("Ver: \(Bundle.main.appVersionLong) (\(Bundle.main.appBuild)) ")
                    // Xcode 13.0 beta 2
                    //.textSelection(.enabled)
                
                Text(Bundle.main.copyright)
                    .font(.system(size: 10, weight: .thin))
                    .multilineTextAlignment(.center)
            }
            .padding(20)
            .frame(minWidth: 350, minHeight: 300)
        }
    }
    
    ///////////////////////////////////
    /// HELPERS
    //////////////////////////////////
    class AppDelegate: NSObject, NSApplicationDelegate {
        private var aboutBoxWindowController: NSWindowController?
        
        func showAboutWnd() {
            if aboutBoxWindowController == nil {
                let styleMask: NSWindow.StyleMask = [.closable, .miniaturizable,/* .resizable,*/ .titled]
                let window = NSWindow()
                window.styleMask = styleMask
                window.title = "About \(Bundle.main.appName)"
                window.contentView = NSHostingView(rootView: AboutView())
                window.center()
                aboutBoxWindowController = NSWindowController(window: window)
            }
            
            aboutBoxWindowController?.showWindow(aboutBoxWindowController?.window)
        }
    }
    
    extension AboutView {
        private static var offSiteAdr: String { "http://www.taogit.com" }
        private static var offEmail: String { "someUser@gmail.com" }
        
        public static var offCiteUrl: URL { URL(string: AboutView.offSiteAdr )! }
        public static var offEmailUrl: URL { URL(string: "mailto:\(AboutView.offEmail)")! }
    }
    extension Bundle {
        public var appName: String { getInfo("CFBundleName")  }
        //public var displayName: String {getInfo("CFBundleDisplayName")}
        //public var language: String {getInfo("CFBundleDevelopmentRegion")}
        //public var identifier: String {getInfo("CFBundleIdentifier")}
        public var copyright: String {getInfo("NSHumanReadableCopyright").replace(of: "\\\\n", to: "\n") }
        
        public var appBuild: String { getInfo("CFBundleVersion") }
        public var appVersionLong: String { getInfo("CFBundleShortVersionString") }
        //public var appVersionShort: String { getInfo("CFBundleShortVersion") }
        
        fileprivate func getInfo(_ str: String) -> String { infoDictionary?[str] as? String ?? "⚠️" }
    }
    
    

    并分配给菜单行:

    struct MyApp: App {
        @NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    
        var body: some Scene {
            WindowGroup {
                MainView()
            }
            // Replacement of standard About window
            .commands {
                CommandGroup(replacing: CommandGroupPlacement.appInfo) {
                    Button("About \(Bundle.main.appName)") { appDelegate.showAboutWnd() }
                }
            }
        }
    }
    

    结果:

    奖励:版权中支持“\n”

    【讨论】:

      猜你喜欢
      • 2020-04-10
      • 2020-04-09
      • 1970-01-01
      • 1970-01-01
      • 2020-10-25
      • 2020-08-08
      • 2021-11-23
      • 2022-01-26
      • 1970-01-01
      相关资源
      最近更新 更多