检查可动画数据的状态
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// AnimatableTrigger.swift | |
// ScrollViewDemo | |
// | |
// Created by Yang Xu on 2022/9/2. | |
// | |
import Foundation | |
import SwiftUI | |
// 考虑到动画数据插值的不确定性,除了起始点数据外,其他位置数据的判断条件应该设置的宽松些 | |
struct AnimationTrigger<Value: VectorArithmetic>: Animatable, ViewModifier { | |
var animatableData: Value { | |
get { value } | |
set { | |
value = newValue | |
} | |
} | |
var value: Value | |
let condition: (Value) -> Bool | |
var trigger: (Value, Int) -> Void | |
let triggerOnce: Bool | |
@State var count = 0 | |
func body(content: Content) -> some View { | |
let _ = [condition].forEach { | |
if $0(value) { | |
DispatchQueue.main.async { | |
if (triggerOnce && count == 0) || !triggerOnce { | |
count += 1 | |
trigger(value, count) | |
} | |
} | |
} | |
} | |
content | |
.background(Color.clear.id(value.magnitudeSquared)) | |
} | |
} | |
extension View { | |
func animationTrigger<Value: VectorArithmetic>( | |
value: Value, | |
condition: @escaping (Value) -> Bool, | |
trigger: @escaping (Value, Int) -> Void, | |
triggerOnce: Bool = true | |
) -> some View { | |
modifier(AnimationTrigger(value: value, condition: condition, trigger: trigger, triggerOnce: triggerOnce)) | |
} | |
} | |
struct TiggerDemo: View { | |
@State var degree: CGFloat = 0 | |
@State var y: CGFloat = 0 | |
@State var text = "" | |
var body: some View { | |
VStack { | |
Rectangle() | |
.fill(.orange) | |
.frame(width: 200, height: 200) | |
.overlay(Text(text).rotationEffect(.degrees(180))) | |
.animationTrigger(value: degree, condition: { $0 == 180 }, trigger: { _, count in | |
text = "旋转结束" | |
withAnimation(.easeOut.delay(0.3)) { | |
y = 200 | |
} | |
}) | |
.offset(x: 0, y: y) | |
.rotationEffect(Angle.degrees(degree)) | |
Button("Rotation") { | |
withAnimation(.easeInOut(duration: 1)) { | |
degree = 180 | |
} | |
}.buttonStyle(.bordered) | |
} | |
} | |
} | |
struct TiggerPreview:PreviewProvider{ | |
static var previews: some View{ | |
TiggerDemo() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment