繁体   English   中英

如何在 SwiftUI 中为 ForEach 中的特定按钮设置动画?

[英]How to animate particular button from ForEach in SwiftUI?

我有一个动画按钮的问题。 我使用 ForEach 方法创建了它们。 我的应用程序的布局由 3 个标志组成。 我们有文字说我们必须选择特定国家的国旗,如果我们选择正确的国旗,我们就会获得积分。

我想在按下特定按钮时为其设置动画。 答案是否正确并不重要。

我创建这些按钮的代码如下所示:

ForEach(0 ..< 3) { number in
    Button(action: {
        withAnimation {
            if number == self.correctAnswer {
                self.animationAmount += 360
            }
        }
        
        self.flagTapped(number)
    }) {
        ImageView(myImage: self.countries[number])
    }
    .rotation3DEffect(.degrees(number == self.correctAnswer ? self.animationAmount : 0), axis: (x: 0, y: 1, z: 0))
    .opacity(self.showAnimation && number != self.correctAnswer ? 0.25 : 1)
    .background(self.showAnimation && number != self.correctAnswer ? Color.red: nil)
}

self.flagTapped(number)showAnimation切换为true

这是可能的替代方法 - 更合适的外观将按钮移动到单独的视图中,并在需要时让它自行设置动画。

演示是在一些复制的简化代码上准备的(由于提供的快照中缺少部分)。 使用 Xcode 12 / iOS 14 测试。

演示

struct DemoView: View {
    let countries = ["flag-1", "flag-2", "flag-3", "flag-4"]

    @State private var number: Int = -1
    let correctAnswer = 1
    var body: some View {
        VStack {
            ForEach(0 ..< 3) { number in
                FlagButton(number: number, image: self.countries[number], answer: correctAnswer){
                    self.flagTapped(number)
                }
            }
        }
    }

    private func flagTapped(_ number: Int) {
        self.number = number
    }
}


struct FlagButton: View {
    let number: Int
    let image: String
    let answer: Int
    var showAnimation = false
    let action: () -> ()

    @State private var animationAmount = Double.zero
    var body: some View {
        Button(action: {
            if self.number == self.answer {
                self.animationAmount += 360
            }
            action()
        }) {
            Image(image)
        }
        .rotation3DEffect(.degrees(number == answer ? self.animationAmount : 0), axis: (x: 0, y: 1, z: 0))
        .opacity(self.showAnimation && number != answer ? 0.25 : 1)
        .background(self.showAnimation && number != answer ? Color.red: nil)
        .animation(.default)
    }
}

备份

@State private var selectedFlag = -1 //Add this in your ContentView struct
ForEach(0..<3) { number in
                    Button {
                        flagTapped(number)
                        noOfQuestions += 1
                        if noOfQuestions == 8 {
                            showingEnd = true
                        }
                        if scoreTitle == "Correct Answer" {
                            score += 1
                        }
                    } label: {
                        Image(countries[number])
                            .renderingMode(.original)
                            .clipShape(Capsule())
                            .shadow(radius: 5)
                            .rotation3DEffect(.degrees(selectedFlag == number ? 360 : 0),
                                              axis: (x: 0, y:1, z:0))
                            .opacity((selectedFlag == number || selectedFlag == -1) ? 1 : 0.25)
                            .animation(.default, value: selectedFlag )
                            .scaleEffect((selectedFlag == number || selectedFlag == -1) ? 1 : 0.75)
                    }
                }

selectedFlag 变量将帮助确定当前选择了哪些标志,并将动画应用于特定图像而不是按钮效果最好。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM