点击按钮时图标动画错误

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

我在选择按钮时遇到问题。我使用枚举来跟踪应用程序中的页面及其值,例如页面标题和页面图标。我使用这些值在 VStack 内创建一个带有按钮的菜单。我使用 ForEach 检索所有枚举值 (AppScreen) 并将它们填充到按钮的标签中。到目前为止,一切都很好,但是当我选择一个按钮时,图标动画也会影响之前选择的按钮。让我举个例子:

我的按钮的标题是“按钮 1”和“按钮 2”及其相关图标。当我选择“按钮 1”时,图标动画工作正常,但当我选择“按钮 2”时,它无法正常工作,因为它为“按钮 1”和“按钮 2”的图标设置动画,而不仅仅是“按钮” 2.”

我哪里出错了?

这是我的代码:

import Foundation

enum AppScreen: CaseIterable, Identifiable {
    case btn1, btn2
    
    var id: AppScreen { self }
    
    var screenName: String {
        switch self {
        case .btn1: "btn1"
        case .btn2: "btn2"
        }
    }
    
    var screenIcon: String {
        switch self {
        case .btn1: "exclamationmark.arrow.triangle.2.circlepath"
        case .btn2: "person.2"
        }
    }
}

struct AppSideBar: View {
@Binding var appScreen: AppScreen?
@State private var selection: String = ""

var body: some View {
        HStack {
            VStack {
                ForEach(AppScreen.allCases) { screen in
                    Button {
                        selection = screen.screenName
                    } label: {
                        VStack {
                            Image(systemName: screen.screenIcon)
                                
                            Text(screen.screenName)
                                .foregroundStyle(selection == screen.screenName ? .red : .white)
                        }
                    }
                    .symbolEffect(.bounce, value: selection == screen.screenName)
                    .buttonStyle(.borderless)
                }
            }
        }
#if os(macOS)
.frame(width: NSScreen.main!.visibleFrame.width / 1.6, 
       height: NSScreen.main!.visibleFrame.height - 100)
#endif
    }
}
ios xcode macos button swiftui
1个回答
0
投票

.symbolEffect

文档
指出“每次值更改时都会触发动画”。所以当条件从 false 变为 true 时会触发,但从 true 变为 false 时也会触发。

要解决此问题,我认为您需要为每个按钮设置单独的标志,并且标志仅应在应用选择时更改,而不是在选择移开时更改。像这样:

@State private var selectionApplied = [AppScreen: Bool]()
ForEach(AppScreen.allCases) { screen in
    Button {
        let wasApplied = selectionApplied[screen] ?? false
        selectionApplied[screen] = !wasApplied
        selection = screen.screenName
    } label: {
        // as before
    }
    .symbolEffect(.bounce, value: selectionApplied[screen] ?? false)
    .buttonStyle(.borderless)
}
© www.soinside.com 2019 - 2024. All rights reserved.