#SwiftUIを使って学習がてらタイマーアプリを作ってみよう　FIN

#SwiftUIを使って学習がてらタイマーアプリを作ってみよう　Finish

###前置き　
前回投稿した[Part8](https://qiita.com/scream_episode/items/fb928f114de7a857b480)の続きです。
今回のゴールとしては
1.前回実装したPageViewContorllerに対応したインジゲータの実装
です。

今回の投稿で「SwiftUIを使って学習がてらタイマーアプリを作ってみよう」シリーズはひとまず完結とします。
（もしかしたら追加でなんかしたら続きを書く可能性は無きにしも非ず）
###開発環境
Mac (OS Big Sur version:11.3.1)
Xcode (version:12.5)
Swift (version: 5.4) 
対象IOS（version:14.5以上）

## 今回の作業
### UIを決める
普通のページインジゲータ(PageContorl)は[チュートリアル](https://developer.apple.com/tutorials/swiftui/interfacing-with-uikit)で
やっているが、それじゃつまんないので他に探してたらこんなやつを見つけたんでこれを再現するようにしたいと思いました。

![iOS の画像 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436163/f0585466-33c3-4790-976f-e0910b7e07da.png)


### １.インジゲータ用UI(PageContorol)を作成
現在位置を視覚的に分かりやすくするためのインジゲータ用のパーツViewを作成
*あくまでも今回の学習用に作っているので色々と作りがアレなのは勘弁してください

```PageIndicater.swift
struct PageIndicater: View {
    @State var sliderValue: Float = 0.0
    @Binding var pageIndex: Int
    var body: some View {
        GeometryReader{ reader in
                Capsule()
                    .frame(width: reader.size.width * CGFloat(0.5))
                    .foregroundColor(Color.white)
                    .offset(x: (reader.size.width * CGFloat(self.pageIndex) ) / 2)
                    .animation(.easeIn)
        }.background(Color.red)
    }
}

```

今回はカプセル（長方形で角が丸めてある感じの物）を利用した。
> GemoetryReader{ }

GemoetryReaderで画面サイズを取得し、カプセルのサイズを画面サイズの半分の大きさに（今回はアイテムが二つしか作ってないため直値で指定している）
> .frame(width: reader.size.width * CGFloat(0.5))

offsetを使うことで表示位置をページのインデックスと同期して変更させるようにした。
ページインデックスによって描画位置（start）を左端か中央に設定している

> .offset(x: (reader.size.width * CGFloat(self.pageIndex) ) / 2)

### 2.表示している画面に対応したインジゲータとボタンが表示されるパーツUIを作成
１.ZStackでボタンUIの上に作成したページインデックスを重ねるように表示
2.ButtonとNavitveLinkをページインデックスによって表示させるものを切り替えるようにする。
3.呼び出し先でViewを傾けるのでButtonとNavitveLinkのラベルを角度を反転させて傾けておく

```PageIndicaterAreaView.swift
struct PageIndicaterAreaView: View {
    @Binding var selection: Int
    @Binding var pageCurrent: Int
    var degree:Double
    var basePadding:CGFloat
    
    @EnvironmentObject var timerModel:TimerModel
    @State var isSheet = false
    var body: some View {
        GeometryReader{ geometry in
            ZStack(alignment: .top){
                if(pageCurrent == 0) {
                    // 遷移処理
                    NavigationLink(destination: TimerView(countDwon:Double(self.selection + 1))){
                        Text("Start Timer")
                            .font(.title)
                            .foregroundColor(.white)
                            .frame(minWidth: 0, maxWidth: geometry.size.width,
                                   minHeight: 0, maxHeight: .infinity,
                                   alignment: .topLeading)
                            .padding(.top, basePadding * 0.7)
                            .padding(.leading, basePadding * 2)
                            .rotationEffect(.degrees(degree * -1))
                    }
                    .background(Color.blue)
                }else {
                    Button(action:{ isSheet.toggle()}){
                        Text("Sound Select")
                            .font(.title)
                            .foregroundColor(.yellow)
                            .frame(minWidth: 0, maxWidth: geometry.size.width,
                                   minHeight: 0, maxHeight: .infinity,
                                   alignment: .topLeading)
                            .padding(.top, basePadding * 0.7)
                            .padding(.leading, basePadding * 2)
                            .rotationEffect(.degrees(degree * -1))
                            .background(Color.purple)
                    }
                    .background(Color.red)
                    .sheet(isPresented: $isSheet){
                        MusicPicker(songInfo: $timerModel.songInfo)
                    }

                }
                
                // PageContorl的な物
                PageIndicater(pageIndex: self.$pageCurrent)
                    .frame(minWidth: 0, maxWidth:.infinity,
                           minHeight: 0,  maxHeight: (geometry.size.height / 10) * 1)

            }
        }
    }
}

```

### 3.任意の画面で作成したパーツUIを表示させる
作業２で作成したパーツViewとpart8で作成したPageViewを組みわせるとこんな感じになる

![up2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436163/cc7822bd-2d54-57dc-6e7b-ce658e17d3c2.gif)


---
###参考/引用元
Apple Developer SwiftUI Tutorials 
・[Framework Integration Interfacing with UIKit](https://developer.apple.com/tutorials/swiftui/interfacing-with-uikit)

###シリーズ：「SwiftUIの学習でタイマーアプリを作ってみよう」のリンク
[part1:プロジェクトの作成とGitHubに登録](https://qiita.com/scream_episode/items/f8bfcba4c65c3b758db8)
[part2: Timerを利用したカウント処理の実装](https://qiita.com/scream_episode/items/8d42198698fcf7513b54)
[part3:計測画面でのプログレスバーの実装](https://qiita.com/scream_episode/items/b899fa41728fc4eed590)
[part4:スピナー実装](https://qiita.com/scream_episode/items/7bb249ee55140424829b)
[part5:ライブラリから音楽を選択して再生](https://qiita.com/scream_episode/items/5e60b85fec58ebf50e2f)
[part6:タイマー処理のバックグランド対応](https://qiita.com/scream_episode/items/33586875cf609a884184)
[part7:音楽のバックグランド再生対応](https://qiita.com/scream_episode/items/abb2168fe66b90836443)
[part8:PageViewを作成](https://qiita.com/scream_episode/items/fb928f114de7a857b480)
part9:PageViewのインジゲータを作成　←　今はここ