コイントスを実装する
まずはSwiftUIでコインの裏表の状態を監視するための@State変数を用意します。
struct YesNoCoinTossView: View { // ここを追加↓ @State private var isReversed = false var body: some View { VStack(spacing: 60) { Text("迷ったら時は\nコインで決めよう") .multilineTextAlignment(.center) .font(.largeTitle)
次に、Text(“やる”)
を次のように書き換えます。
VStack(spacing: 32) { // ここを変更↓ Text(isReversed == true ? "やらない" : "やる") .font(.largeTitle) .frame(width: 160, height: 160) .background { Circle() .fill(.yellow) }
Text(isReversed == true ? "やらない" : "やる")
という見慣れない書き方が出てきましたが、これは三項演算子を使用した条件式になります。
三項演算子
三項演算子は、簡単に条件分岐を表現する方法です。具体的には以下のように使います。
条件式 ? 条件が真の場合の値 : 条件が偽の場合の値
今回の例では、isReversed
がtrue
の時はやらない
という文字になり、そうでない場合はやる
という文字になっています。
また、Swiftでは、Bool
型の条件式を記述する場合にisReversed == true
のようにtrue
を明示的に記述する必要はなく、次のように省略して記述することもできます。
Text(isReversed ? "やらない" : "やる")
Boolをランダムに変更する
コインの裏表の状態を表す変数を準備しました。次に、コインを投げる
ボタンが押されたときに、isReversed
にtrue
またはfalse
をランダムに代入します。ランダムなBool
値を取得するにはBool.random()
を使用します。
VStack(spacing: 32) { Text(isReversed == true ? "やらない" : "やる") .font(.largeTitle) .frame(width: 160, height: 160) .background { Circle() .fill(.yellow) } Button { // ここを追加↓ isReversed = Bool.random() } label: { Text("コインを投げる") .font(.title) } }
コード変更後、コインを投げる
ボタンを押すと、プレビュー上のやる
のテキストがやらない
に変わったり、変わらなかったりを確認できます。
コインが回転するアニメーションを付ける
コインが回るアニメーションをつけて、コイントス感を出していきます。
まずは、回転する角度をView
に反映するために回転角度用の@State
変数を追加します。そして、コインを投げる
ボタンを押した時に回転角度が以前の結果と変わるようにします。
struct YesNoCoinTossView: View { @State private var isReversed = false // ここを追加↓ @State private var rotationDegrees = 0.0 var body: some View { VStack(spacing: 60) { Text("迷ったら時は\nコインで決めよう") .multilineTextAlignment(.center) .font(.largeTitle) VStack(spacing: 32) { Text(isReversed == true ? "やらない" : "やる") .font(.largeTitle) .frame(width: 160, height: 160) .background { Circle() .fill(.yellow) } Button { // ここを追加↓ rotationDegrees = rotationDegrees == 0 ? 360 : 0 isReversed = Bool.random() } label: { Text("コインを投げる") .font(.title) } } } } }
rotationDegrees = rotationDegrees == 0 ? 360 : 0
では、値が0
の時は360
が代入されて、そうでない時は0
が代入されるようにしています。
しかし、まだコインを投げる
ボタンを押してもアニメーションは発生しません。アニメーションをつけるために次のようにコードを変更します。
VStack(spacing: 60) { Text("迷ったら時は\nコインで決めよう") .multilineTextAlignment(.center) .font(.largeTitle) VStack(spacing: 32) { Text(isReversed == true ? "やらない" : "やる") .font(.largeTitle) .frame(width: 160, height: 160) .background { Circle() .fill(.yellow) } // ここを追加↓ .rotation3DEffect(.degrees(rotationDegrees), axis: (x: 0, y: 1, z: 0)) Button { // ここを追加↓ withAnimation { rotationDegrees = rotationDegrees == 0 ? 360 : 0 isReversed = Bool.random() } } label: { Text("コインを投げる") .font(.title) } } }
.rotation3DEffect
モディファイアは指定した軸を中心に3DでView
を回転したように見せることができます。今回はy軸
を指定しており、画面の上下方向を中心に対象物が回転します。
また、同様に withAnimation {
を追加しています。このwithAnimation
の{}
の中に含まれる値に対してアニメーションを付与することができます。今回は回転角度rotationDegrees
とコインの裏表状態isReversed
に対してアニメーションを付与しています。
これでコインを投げる
ボタンを押すと、コインが回転するようなアニメーションが発生するようになりました。これでアプリ「やるのかやらないのかコイントス」は完成です。
もし、iOSシミュレーターでも動作確認したい場合は、前回学んだ方法でMyAppCollectionApp
のView
を書き換えて実行してみて下さい。
@main struct MyAppCollectionApp: App { var body: some Scene { WindowGroup { // ここを変更↓ YesNoCoinTossView() } } }
まとめと次回
今回はアプリを作る過程で、SwiftUIでのView
のレイアウトの調整方法や三項演算子、アニメーションの付け方などを学びました。
rotation3DEffect
の回転軸については実際にx
やz
軸に値を入れて、どうアニメーションするのか確認しても面白いかもしれません。
連載で説明している内容は、ごく一部にすぎません。気になった部分は積極的に調べるとSwiftUIでできることを色々知ることができて、さらに楽しさが増えると思います。
次回はアプリ「愚っ痴る - ここが私の愚痴を吐き出す場所」を作ります。お楽しみに!