SwiftUI:更改 macOS 应用程序中的“关于视图”

问题描述 投票:0回答:4

我正在使用

SwiftUI
和新的
App
生命周期构建 macOS 应用程序。

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

enter image description here

如何将“关于”视图替换为自定义视图?

swift swiftui menuitem nsmenu about-box
4个回答
11
投票

你可以这样做,但它确实需要创建一个 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 视图,它就会在您的“关于”框中显示该视图。例如:

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

11
投票

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

您可以在这里找到更多


5
投票
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 { "[email protected]" }
    
    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() }
            }
        }
    }
}

结果:

enter image description here

奖励:支持“ “版权所有

enter image description here


0
投票

所以我使用了

hayesk
描述的方法一段时间,但我意识到这可以完全通过SwiftUI UI来完成(不需要应用程序委托)。

struct RoamApp: App {
    @Environment(\.openWindow) private var openWindow

    var body: some Scene {
        Window("Roam", id: "main") {
            RemoteView()
        }
        .commands {
            CommandGroup(replacing: CommandGroupPlacement.appInfo) {
                Button(action: {
                    // Open the "about" window
                    openWindow(id: "about")
                }, label: {
                    Text("About Roam", comment: "Button to open the about page of the Roam app")
                })
            }
        }
        // Note the id "about" here
        Window("About Roam", id: "about") {
            ExternalAboutView()
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.