執行效果
重寫可動畫類數據
//VectorArithmetic 可動畫類型的數據 extension View { //定義Data為VectorArithmetic //ModifiedContent是指,將此Self示圖 //經由AnimationDataChangeModifier,修改後產生新的示圖 //modifier主要是回傳ModifiedContent func onAnimationDataChange( for data: Data, onComplete: @escaping () -> Void ) -> ModifiedContent<Self, AnimationDataChangeModifier> { return modifier(AnimationDataChangeModifier( changeData: data, onComplete: onComplete)) } } //指處where Data: VectorArithmetic //確保資料類型是VectorArithmetic //AnimatableModifier繼承於 //Animatable, ViewModifier,可動畫的修改器 struct AnimationDataChangeModifier : AnimatableModifier where Data: VectorArithmetic { //animatableData是繼承Animatable的資料,監聽變化 var animatableData: Data { didSet { dataChangeCallback() } } private var previousData: Data private var onComplete: () -> Void //此處要注意,順序很重要 init( changeData: Data, onComplete: @escaping () -> Void ) { //先註冊callback,完成時回調 self.onComplete = onComplete //此處是關鍵 //animatableData改變會先呼叫didSet //此時呼叫dataChangeCallback //animatableData已改變資料,previousData尚未改變 self.animatableData = changeData //執行這行後previousData才改變資料 previousData = changeData } private func dataChangeCallback() { guard animatableData == previousData else { return } DispatchQueue.main.async { self.onComplete() } } func body(content: Content) -> some View { return content } }
使用方法
//onAnimationDataChange //必須要使用withAnimation的變數變化,才會觸發 //因為VectorArithmetic 可動畫類型的數據 struct MainView: View { @State var opacity: Double = 1 @State var animation = false var body: some View { Text("1234567890abcdefg") .opacity(animation ? opacity : 1) .animation(animation ? Animation.linear : nil ) .onAnimationDataChange(for: opacity) { if opacity == 0.1 { withAnimation( Animation.linear(duration: 1)) { opacity = 1 } } else { withAnimation( Animation.linear(duration: 1)) { opacity = 0.1 } } } .onAppear { animation = true withAnimation( Animation.linear(duration: 1)) { opacity = 0.1 } } } }
訂閱Codeilin的旅程,若有最新消息會通知。
廣告
發表迴響