SwiftUIでいこう! - Animation Timer! 1
ちょっと変わったアニメーションを使ったタイマーです。参考サイトをみながら組み上げていきます。
Xcode、プロジェクトを作って、最初からContentViewはありますが、別viewとしてHomeView.swiftという名前でSwiftUIファイルを作ってまず表示画面を作っていきます。
骨組みは以下のようになります。
var body: some View {
VStack{
Spacer()
ScrollView(.horizontal,showsIndicators:false,content:{
HStack(spacing:20){
ForEach(1...6,id:\.self){index in
let time = index * 5
Text("\(time)")
}
}
.padding()
})
Spacer()
}
}
Spacer()を使って表示部分を中央へ持っていきます。
HStack、ForEachで横並びに数字を並べます。その時円形に形を整え色をつけます。
Text("\(time)")
.font(.system(size: 30,weight:.heavy))
.frame(width:80,height: 80)
.background(Color.blue)
.foregroundColor(.white)
.clipShape(Circle())
こんな感になります
次にデータを入れるモデルを作ります。TimerViewModelという名前でswiftファイルを作ります。
import SwiftUI
class TimerData:ObservableObject{
@Published var time:Int = 0
@Published var selectedTime:Int = 0
@Published var buttonAnimation = false
@Published var timeViewOffset:CGFloat = UIScreen.main.bounds.height
}
ObservableObjectに適合したクラスを作ります。
@Published var time:Int = 0
@Published var selectedTime:Int = 0
これはボタンを選択した時に使う変数。
@Published var buttonAnimation = false
これはアニメーションを動かす時に使う変数。
@Published var timeViewOffset:CGFloat = UIScreen.main.bounds.height
これはアニメーションする時の画面変化に使う変数となっています。
HomeViewを編集していきます。別ファイルで作ったクラスを使えるように変数に代入します。
@StateObject var data = TimerData()
青丸の数字をタップした時の動きを書いていきます。
Text("\(time)")
......................
.background(data.time == time ? Color.pink : Color.blue)
......................
.onTapGesture {
data.time = time
data.selectedTime = time
}
タップした時に
data.time = time
data.selectedTime = time
とするので、タップすると、 data.time = timeとなるので、
.background(data.time == time ? Color.pink : Color.blue)
の動きで丸文字はピンクとなります。
次にアニメーション、タイマーを動かすボタンを作っていきます。まずはアニメーションをつけていきます。
Button(action: {
withAnimation(Animation.easeInOut(duration:0.65)){
data.buttonAnimation.toggle()
}
withAnimation(Animation.easeIn.delay(0.6)){
data.timeViewOffset = 0
}
}
, label: {
Circle()
.fill(Color.pink)
.frame(width:90,height:90)
})
.padding(.bottom,35)
.disabled(data.time == 0)
.opacity(data.time == 0 ? 0.6: 1)
.offset(y:data.buttonAnimation ? 300:0)
}
表示部分は
label: {
Circle()
.fill(Color.pink)
.frame(width:90,height:90)
}
ピンクのまるです。
.padding(.bottom,35)
.disabled(data.time == 0)
.opacity(data.time == 0 ? 0.6: 1)
.offset(y:data.buttonAnimation ? 300:0)
の部分で初期状態変数の値が変化した場合の制御を行います。
これを押すと、変数の値を変化させてアニメーションをスタートします。
withAnimation(Animation.easeInOut(duration:0.65)){
data.buttonAnimation.toggle()
}
withAnimation(Animation.easeIn.delay(0.6)){
data.timeViewOffset = 0
}
あとはVStackと並列にColorを設置。
Color.pink
.ignoresSafeArea(.all,edges: .all)
.overlay(
Text("\(data.selectedTime)")
.font(.system(size: 55,weight:.heavy))
.foregroundColor(.white)
)
.offset(y:data.timeViewOffset)
VStackとColorの上位にZStackをつけます。画面上を色を被せる形をとります。
.offset(y:data.timeViewOffset)
で制御します。あとはZStackを以下で前面黒くしています。
.frame(maxWidth: .infinity,maxHeight: .infinity)
.background(Color(.black).ignoresSafeArea(.all,edges: .all))
この記事が気に入ったらサポートをしてみませんか?