首页 > 解决方案 > SwiftUI onTapGesture interact with caller only

问题描述

I've just started looking into SwiftUI and since it's so different I'm trying to wrap my head around basic concepts.

In this scenario, how would I go about changing the color only for the circle tapped?

ForEach(1...count, id: \.self) { _ in
    Circle()
        .foregroundColor(colors.randomElement()).opacity(0.2)
        .frame(width: .random(in: 10...100), height: .random(in: 10...100))
        .position(x: .random(in: self.stepperValue...400),
                  y: .random(in: self.stepperValue...400))
        .saturation(2.0)
        .onTapGesture(count: 1, perform: {
            // Change color of circle that was tapped
            print("Tapped")
        })
        .animation(.default) // Animate the change in position

}

标签: swiftswiftui

解决方案


Well there are two main options I see here

  1. Make a custom view like
struct MyCircle: View {

    @State var color: Color?

    var body: some View {
        Circle()
            .foregroundColor(color)
            .onTapGesture {
                self.color = colors.randomElement()
            }
    }
}

and then integrate that or

  1. Use a model for your color
struct MyView: View {
    
    @State var colors = allColors.indices.compactMap { _ in allColors.randomElement() }
    
    var body: some View {
        ForEach(colors.indices) { index in
            Circle()
                .foregroundColor(colors[index])
                .onTapGesture {
                    colors[index] = allColors.randomElement()
                }
        }
    }
}

A state like this should preferably be in its own class which should be inserted as ObservedObject.


推荐阅读