0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【SwiftUI】試して学ぶAnimationとTransition

0
Posted at

はじめに

先日、SwiftUIのAnimationとTransitionについて学習しました。

AnimationとTransitionの組み合わせによって挙動が変わったり、
Transition自身もcombineして組み合わせることができるといったように
柔軟な設定が可能なのですがその分わかりにくいです。

今回はAnimationとTransitionの組み合わせを実機で試すことができるアプリを作りました。

作ったもの

TransitionとcombineするTransition、及び付与するAnimationを
インサート時とリムーバル時それぞれ設定して挙動を確認することが可能です。

001.gif

コード

下記を丸っとコピーして実行します。

かなり殴り書きなコードですが、springのdurationなども指定できるように今後改良していきたいと思います。

Contentview.swift
import SwiftUI

struct ContentView: View {
    @State private var viewFlg: Bool = false
    @State private var isResume: Bool = false
    private let transitionList: [AnyTransition] = [.slide, .opacity, .scale, .move(edge: .top), .move(edge: .leading), .move(edge: .bottom), .move(edge: .trailing)]
    private let transitionStringList: [String] = ["slide", "opacity",
                                                  "scale", "move(edge: .top)", "move(edge: .leading)", "move(edge: .bottom)", "move(edge: .trailing)"]
    private let animationList: [Animation] = [.default, .linear, .easeIn, .easeOut, .easeInOut, .spring(response: 0.5, dampingFraction: 0.5, blendDuration: 1), .interactiveSpring(response: 0.5, dampingFraction: 0.5, blendDuration: 0.5)]
    private let animationStringList: [String] = [".default", ".linear", ".easeIn", ".easeOut", ".easeInOut", ".spring()", ".interactiveSpring()"]
    
    @State private var insertAnimationSelection: Int = 0
    @State private var removalAnimationSelection: Int = 0
    
    @State private var insertSelection: Int = 0
    @State private var removalSelection: Int = 0
    
    @State private var insertCmbSelection: Int = 0
    @State private var removalCmbSelection: Int = 0
    @State private var insertCombineFlg: Int = 0
    @State private var removalCombineFlg: Int = 0
    
    var body: some View {
        VStack {
            ZStack {
                Color.white
                // こいつにtransitionを反映する
                if viewFlg || !isResume {
                    Rectangle()
                        .fill(Color.blue)
                        .frame(width: 100, height: 40)
                        .transition(.asymmetric(
                                        insertion: insertCombineFlg == 0 ? transitionList[self.insertSelection] : transitionList[self.insertSelection].combined(with: transitionList[self.insertCmbSelection])
                                        ,removal: removalCombineFlg == 0 ? transitionList[self.removalSelection] : transitionList[self.removalSelection].combined(with: transitionList[self.removalCmbSelection])))
                        .zIndex(2)
                }
                
                VStack {
                    Spacer()
                    HStack {
                        Spacer()
                        if !isResume {
                            Button(action: {
                                self.isResume.toggle()
                                Timer.scheduledTimer(withTimeInterval: 0.5, repeats: false) {timer in
                                    withAnimation(animationList[self.insertAnimationSelection]) {
                                        self.viewFlg.toggle()
                                        Timer.scheduledTimer(withTimeInterval: 2.0, repeats: false) {timer in
                                            withAnimation(animationList[self.removalAnimationSelection]) {
                                                self.viewFlg.toggle()
                                            }
                                            Timer.scheduledTimer(withTimeInterval: 2.0, repeats: false) {timer in
                                                self.isResume.toggle()
                                            }
                                        }
                                    }
                                }
                            }, label: {
                                Image(systemName: "play.circle")
                                    .resizable()
                                    .frame(height: 40)
                                    .frame(width: 40)
                            })
                        }
                    }
                }
                .padding()
                .zIndex(1)
            }
            .frame(height: 200)
            
            
            
            NavigationView {
                VStack {
                    
                    Form {
                        Picker("", selection: self.$insertCombineFlg) {
                            Text("single").tag(0)
                            Text("combine").tag(1)
                        }
                        .pickerStyle(SegmentedPickerStyle())
                        
                        Picker(selection: $insertSelection, label: Text("InsertTransition"), content: {
                            ForEach(0 ..< transitionStringList.count) { num in
                                Text(self.transitionStringList[num])
                            }
                        })
                        
                        if self.insertCombineFlg == 1 {
                            Picker(selection: $insertCmbSelection, label: Text("withTransition"), content: {
                                ForEach(0 ..< transitionStringList.count) { num in
                                    Text(self.transitionStringList[num])
                                }
                            })
                        }
                        
                        Picker(selection: $insertAnimationSelection, label: Text("Animation"), content: {
                            ForEach(0 ..< animationStringList.count) { num in
                                Text(self.animationStringList[num])
                            }
                        })
                    }
                    
                    Form {
                        Picker("", selection: self.$removalCombineFlg) {
                            Text("single").tag(0)
                            Text("combine").tag(1)
                        }
                        .pickerStyle(SegmentedPickerStyle())
                        
                        Picker(selection: $removalSelection, label: Text("removalAnimation"), content: {
                            ForEach(0 ..< transitionStringList.count) { num in
                                Text(self.transitionStringList[num])
                            }
                        })
                        
                        if self.removalCombineFlg == 1 {
                            Picker(selection: $removalCmbSelection, label: Text("withTransition"), content: {
                                ForEach(0 ..< transitionStringList.count) { num in
                                    Text(self.transitionStringList[num])
                                }
                            })
                        }
                        
                        Picker(selection: $removalAnimationSelection, label: Text("Animation"), content: {
                            ForEach(0 ..< animationStringList.count) { num in
                                Text(self.animationStringList[num])
                            }
                        })
                    }
                    
                }            .navigationBarHidden(true)
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?