SwiftUI:无法设置图像动画
我正在尝试在SwiftUI中制作类似于苹果控制中心扬声器或亮度HUD的扬声器动画。我正在使用苹果提供的SFSymbols中的4幅图像:SwiftUI:无法设置图像动画,swift,xcode,swiftui,Swift,Xcode,Swiftui,我正在尝试在SwiftUI中制作类似于苹果控制中心扬声器或亮度HUD的扬声器动画。我正在使用苹果提供的SFSymbols中的4幅图像: “speaker.slash.fill”//speakerEmpty “扬声器1.填充”//扬声器1 “扬声器2.填充”//扬声器2 “扬声器3.填充”//扬声器3 因此,我有一个开关(在SwiftUI中切换)来切换我的声音选项和四幅图像的动画。这是我希望图像设置动画的方式: 启用切换时: speakerEmpty应将动画设置为->speaker1然后 spea
//speakerEmpty
//扬声器1
//扬声器2
//扬声器3
speakerEmpty
应将动画设置为->speaker1
然后speaker1
应将动画设置为->speaker2
然后speaker2
应设置为->speaker3
我想我的代码逻辑很好。图像正在以应有的方式被替换。但动画效果不起作用。令人沮丧的是,我尝试了很多可能的方法,但都没有奏效。这里是可能的方法。我简化它是为了演示和减少发布代码,但这个想法应该是清晰的,并且易于转换到您的真实代码中 结果演示(确实比gif更流畅): 修正模型
enum SpeakerSymbol: Int, CaseIterable { // Inherited from Int for convenient below
case speakerEmpty, speaker1, speaker2, speaker3
var image: some View {
var name: String
switch self {
case .speakerEmpty: name = "speaker.slash.fill"
case .speaker1: name = "speaker.1.fill"
case .speaker2: name = "speaker.2.fill"
case .speaker3: name = "speaker.3.fill"
}
return Image(systemName: name).font(.largeTitle)
}
}
SpeakerSymbol的可设置动画修改器,用于让SwiftUI动画知道更改的SpeakerSymbol值可以设置动画
struct SpeakerModifier: AnimatableModifier {
var symbol: SpeakerSymbol
init(symbol: SpeakerSymbol) {
self.symbol = symbol
self.animating = Double(symbol.rawValue) // enum to Double
}
private var animating: Double // Double supports Animatable
var animatableData: Double { // required part of Animatable protocol
get { animating }
set { animating = newValue }
}
func body(content: Content) -> some View {
return SpeakerSymbol(rawValue: Int(animating))!.image // Double -> enum
}
}
用法演示
struct TestSpeakerModifier: View {
@State private var speaker: SpeakerSymbol = .speakerEmpty
var body: some View {
VStack {
Color.clear // << just holder area
.modifier(SpeakerModifier(symbol: speaker))
.frame(width: 80, height: 80)
Divider()
Button("Toggle") {
withAnimation { // animates between enum states
self.speaker =
(self.speaker == .speakerEmpty ? .speaker3 : .speakerEmpty)
}
}
}
}
}
struct TestSpeakerModifier:View{
@国家专用变量演讲者:SpeakerSymbol=.Speakermpty
var body:一些观点{
VStack{
Color.clear//谢谢。它很好地工作了。我在使用切换开关时对它进行了相应的修改。@Asperi,Cloud您喜欢这样做只是波浪被设置为动画,而不会像原始扬声器波浪那样将图像移回原处。
enum SpeakerSymbol: Int, CaseIterable { // Inherited from Int for convenient below
case speakerEmpty, speaker1, speaker2, speaker3
var image: some View {
var name: String
switch self {
case .speakerEmpty: name = "speaker.slash.fill"
case .speaker1: name = "speaker.1.fill"
case .speaker2: name = "speaker.2.fill"
case .speaker3: name = "speaker.3.fill"
}
return Image(systemName: name).font(.largeTitle)
}
}
struct SpeakerModifier: AnimatableModifier {
var symbol: SpeakerSymbol
init(symbol: SpeakerSymbol) {
self.symbol = symbol
self.animating = Double(symbol.rawValue) // enum to Double
}
private var animating: Double // Double supports Animatable
var animatableData: Double { // required part of Animatable protocol
get { animating }
set { animating = newValue }
}
func body(content: Content) -> some View {
return SpeakerSymbol(rawValue: Int(animating))!.image // Double -> enum
}
}
struct TestSpeakerModifier: View {
@State private var speaker: SpeakerSymbol = .speakerEmpty
var body: some View {
VStack {
Color.clear // << just holder area
.modifier(SpeakerModifier(symbol: speaker))
.frame(width: 80, height: 80)
Divider()
Button("Toggle") {
withAnimation { // animates between enum states
self.speaker =
(self.speaker == .speakerEmpty ? .speaker3 : .speakerEmpty)
}
}
}
}
}