コイントスを実装する
まずは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でできることを色々知ることができて、さらに楽しさが増えると思います。
次回はアプリ「愚っ痴る - ここが私の愚痴を吐き出す場所」を作ります。お楽しみに!

