【初心者】Swift UIを勉強する その⑫ ーーー zIndexで位置関係を調整

# はじめに

前回はLazyGridを使って、Cardの並びを自由に調整できるようにしました。
けれども、アニメーションはかなり不自然なので、位置関係をうまく調整すればなおせます。

完成品↓
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1065841/d52c7f69-c58f-6363-f3a8-5f9658354936.gif" width=40%>　　



# 目次
<!-- タイトルとアンカー名を編集 -->
1. [zIndex](#zIndex)
2. [まとめ](#まとめ)
3. [参考文献](#reference)

<!-- 各チャプター -->
<a id="#zIndex"></a>
# zIndex
・ListのアニメーションはCardと比べれば、若干硬くて、
　タップジェスチャーが終わるタイミングで別の[`matchedGeometryEffect`](https://qiita.com/anchor_/items/83303e0b323720df0f1c)を呼び出します。
・また、`matchedGeometryEffect`を区別するために、idの識別を変えます。
　

```swift:CoursesView.swift
//Card
VStack {
    CourseItem(course: item)
        .matchedGeometryEffect(
            id: item.id, in: namespace, isSource: !show
        )
        .frame(width: 200, height: 200)
        .onTapGesture {
             withAnimation(.spring()) {
                   show.toggle()
                   selectedItem = item
                   isDisabled = true
             }
         }
         .disabled(isDisabled)
}
.matchedGeometryEffect(
    id: "container\(item.id)", in: namespace, isSource: !show
)
```




・ListにもCardと同じ作業します。アニメーションを遅らせる必要がなくなったので、消します。


```swift:CoursesView.swift
//List
VStack {
    ForEach(0 ..< 20) { item in
        CourseRow()
    }
}
.padding()
.background(Color("Background 1"))
.matchedGeometryEffect(
       id: "container\(selectedItem!.id)", in: namespace
)
<!-- 
.transition(
    .asymmetric(
        insertion: AnyTransition.opacity.animation(
             Animation.spring().delay(0.3)
        ),
        removal: AnyTransition.opacity.animation(.spring())
     )
)
-->
.edgesIgnoringSafeArea(.all)
}
```
<br>
　　　　　　　　　　　　　　　前後
　　　　　　　　　　　　　　　 ↓
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1065841/bd73a42f-e3dd-18a7-cd8b-c66871dfc265.gif" width=40%>　    　 <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1065841/de2f5346-b952-0976-035b-819b086766cb.gif" width=40%>　








・アニメーションをある程度整えたけど、ListはまだCardの裏側にあるので、`zIndex`を使えば簡単にできます。
・裏にあるViewを`zIndex(1)`で、表にあるViewを`zIndex(2)`。

```swift:CoursesView.swift
//Card
{
//省略
.........
}
.zIndex(1)

//List
{
//省略
.........
}
.zIndex(2)
```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1065841/642ec39f-fd69-fa5b-e301-f1ec61257621.gif" width=40%>　　


<br>
・今まではCardをタップして閉じるけど、わかりやすくするために閉じるボタンを入れるもありです。
・新たに`CloseButton.swift`クラスを作ります。

```swift:CloseButton.swift
struct CloseButton: View {
    var body: some View {
        Image(systemName: "xmark")
            .font(.system(size: 17, weight: .bold))
            .foregroundColor(.white)
            .padding(.all, 10)
            .background(Color.black.opacity(0.6))
    }
}

```

・CloseButtonをCardに置きます。`onTapGesture`をCloseButtonに移動します。

```swift:CoursesView.swift
//List
CloseButton()
    .padding(.trailing, 16)
    .onTapGesture {
        withAnimation(
            .spring()) {
                show.toggle()
                selectedItem = nil
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.5){
                     isDisabled = false
                }
             }
     }
}
.zIndex(2)
```

<a id="#まとめ"></a>
# まとめ

**ソースコード[Github](https://github.com/wsimple1028/swiftUI_ios14)**

<a id="#reference"></a>
# 参考文献
- [Design Code --- SwiftUI for iOS 14](https://designcode.io/swiftui-ios14)