👻
Custom Viewを利用して特定のForEach itemに独自な事件を加える
まずは、ForEach
でいくつのボタンを作る
struct ContentView: View {
let items = ["Forest", "Sun", "Moon", "Sea"]
var body: some View {
VStack {
ForEach(items, id: \.self) { item in
Button(item) { }
.buttonStyle(.borderedProminent)
}
}
}
}
画面はこんな感じです
次に、クリックモーションを加える
struct ContentView: View {
let items = ["Forest", "Sun", "Moon", "Sea"]
+ @State private var animationAmount = 0.0
var body: some View {
VStack() {
ForEach(items, id: \.self) { item in
Button(item) {
+ withAnimation {
+ animationAmount += 360
+ }
}
.buttonStyle(.borderedProminent)
+ .rotation3DEffect(.degrees(animationAmount), axis: (x: 0, y: 1, z: 0))
}
}
}
}
しかしみんなが一斉に動き出してしまった、、、
クリックされたボタンだけにモーションをつけるために、Custom Viewを利用してViewを分離させる
+struct MyButton: View {
+ var text: String
+ @State private var animationAmount = 0.0
+
+ var body: some View {
+ Button(text) {
+ withAnimation {
+ animationAmount += 360
+ }
+ }
+ .buttonStyle(.borderedProminent)
+ .rotation3DEffect(.degrees(animationAmount), axis: (x: 0, y: 1, z: + 0))
+ }
+}
struct ContentView: View {
let items = ["Forest", "Sun", "Moon", "Sea"]
- @State private var animationAmount = 0.0
var body: some View {
VStack() {
ForEach(items, id: \.self) { item in
+ MyButton(text: item)
}
}
}
}
これで成功しました
ちなみに、functionをCustom Viewに入れる方法もあります
struct MyButton: View {
var text: String
+ var clickEvent: () -> Void
@State private var animationAmount = 0.0
var body: some View {
Button(text) {
withAnimation {
animationAmount += 360
}
+ clickEvent()
}
.buttonStyle(.borderedProminent)
.rotation3DEffect(.degrees(animationAmount), axis: (x: 0, y: 1, z: 0))
}
}
struct ContentView: View {
let items = ["Forest", "Sun", "Moon", "Sea"]
@State private var clickedItem = "No one"
var body: some View {
VStack() {
ForEach(items, id: \.self) { item in
+ MyButton(text: item, clickEvent: {
+ clickedItem = item
+ })
}
+ Text("\(clickedItem) is clicked")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Discussion