SwiftUI 如何根据修饰符替换菜单项

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

在 SwiftUI 中,按住选项键时如何在 2 个菜单项之间切换

就像当您打开 Finder 文件菜单并按下选项键时,某些项目会交替出现

遗憾的是我的方法仍然显示这两种选择

        Button("Alternative option") {
            
        }
        .keyboardShortcut(KeyEquivalent("i"), modifiers: [.command, .option])

        Button("Regular option") {
            
        }
        .keyboardShortcut(KeyEquivalent("i"), modifiers: [.command])

enter image description here

macos swiftui menu menuitem
1个回答
0
投票

这是因为您提供了两种观点。您需要使用 if 语句来决定要显示哪一个。

这是我的一个应用程序中的一个示例,我在其中更改了登录用户更改时的菜单按钮

import SwiftUI

结构LoginCommandsView:查看{

@Environment(\.openWindow) private var openWindow
@Environment(\.dismiss) private var dismiss

@State private var loginText: String = "Login as User"
@State private var userIsAdmin: Bool = false
@State private var userIsLoggedIn: Bool = false


var body: some View {
    //FIXME: - see bug notes
    loginButton
        .onAppear {
            setParameters(Company.shared.currentUser)
        }
        //bug fix on change not always called
        .onReceive(NotificationCenter.default.publisher(for: .authenticationState), perform: { _ in
            setParameters(Company.shared.currentUser)
        })
        //bug fix on receive not always called
        .onChange(of: Company.shared.currentUser) { _, newValue in
            setParameters(newValue)
        }
    
    if userIsLoggedIn {
        changePassword
    }
    
    if userIsAdmin {
        createUser
    }
    
    if userIsLoggedIn {
        logoutButton
    }
}

@ViewBuilder
private var loginButton: some View {
    
    Button(loginText) {
        Company.shared.currentUser = nil
        CompanyData.shared.save()
        openWindow(id: WindowConstants.loginView)
    }
}

private var changePassword: some View {
    Button("Change Password") {
        openWindow(id: WindowConstants.changePassword)
    }
}

private var createUser: some View {
    Button("Create New User") {
        openWindow(id: WindowConstants.userCreate)
    }
}

private var logoutButton: some View {
    Button("Logout") {
        logout()
    }
}

private func logout() {
    Company.shared.currentUser = nil
    CompanyData.shared.save()
    openWindow(id: WindowConstants.loginView)
    dismiss()
}

private func setParameters(_ user: User?) {
    if user == nil {
        loginText = "Login"
        userIsAdmin = false
        userIsLoggedIn = false
    } else {
        userIsLoggedIn = true
        loginText = "Switch User"
        userIsAdmin = user?.userIsAdmin ?? false
    }
}
}

在你的情况下你可以这样做

if someCondition {
            Button("Alternative option") {
        
    }
    .keyboardShortcut(KeyEquivalent("i"), modifiers: [.command, .option])
} else {
    Button("Regular option") {
        
    }
    .keyboardShortcut(KeyEquivalent("i"), modifiers: [.command])
}

请注意,此视图在它所应用的窗口组的

.commands
中使用,“在我的情况下是所有窗口”

.commands {
            //MARK: - commands
        Group {
                //MARK: New Item Commands
            CommandGroup(replacing: .newItem) {
                LoginCommandsView()
                    .onReceive(NotificationCenter.default.publisher(for: .authenticationState)) { _ in
                        showFullMenu = Company.shared.currentUser != nil
                    }
            }
}

如果用户通过身份验证,显示完整菜单只会添加其他可用的菜单项。从 .commands 闭包内部。

© www.soinside.com 2019 - 2024. All rights reserved.