簡體   English   中英

SwiftUI onTapGesture 僅與調用者交互

[英]SwiftUI onTapGesture interact with caller only

我剛剛開始研究 SwiftUI,因為它是如此不同,我正試圖圍繞基本概念展開思考。

在這種情況下,我將如何只為點擊的圓圈更改顏色?

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

}

好吧,我在這里看到兩個主要選項

  1. 制作一個自定義視圖,例如
struct MyCircle: View {

    @State var color: Color?

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

然后整合它或

  1. 使用 model 作為您的顏色
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()
                }
        }
    }
}

像這樣的 state 最好位於它自己的 class 中,它應該作為ObservedObject插入。

您創建一個具有“行”單個屬性的View

import SwiftUI
struct SampleColorChangeView: View {
    //If the options are fixed no need to keep an eye on them
    //You can move this down to the Row if you don't need to have them available here
    let colors: [Color] = [.red,.blue,.gray, .yellow,.orange]
    @State var count: Int = 10
    var body: some View {
        VStack{
            ForEach(1...count, id: \.self) { _ in
                RowView(colors: colors)
                
            }
        }
    }
}
//Create a row View to observe individual objects
//You will do this with anything that you want to Observe independently
struct RowView: View {
    let colors: [Color]
    //@State observes changes so the View is updated
    @State var color: Color = .blue
    //This kind of works like the colors do you want one for each or a shared for all. Does the parent need access? You can move it up or keep it here
    @State var stepperValue: CGFloat = 0
    //The only change here is the reference to the individual Color
    var body: some View {
        Circle()
            //You set the individual color here
            .foregroundColor(color).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
                color = colors.randomElement()!
                print("Tapped")
            })
            .animation(.default) // Animate the change in position
            //If you want to set a random color to start vs just having them all be the same Color you can do something like this
            .onAppear(){
                color = colors.randomElement()!
            }
    }
}
struct SampleColorChangeView_Previews: PreviewProvider {
    static var previews: some View {
        SampleColorChangeView()
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM