Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SwiftUI:无法设置图像动画_Swift_Xcode_Swiftui - Fatal编程技术网

SwiftUI:无法设置图像动画

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

我正在尝试在SwiftUI中制作类似于苹果控制中心扬声器或亮度HUD的扬声器动画。我正在使用苹果提供的SFSymbols中的4幅图像:

  • “speaker.slash.fill”
    //speakerEmpty
  • “扬声器1.填充”
    //扬声器1
  • “扬声器2.填充”
    //扬声器2
  • “扬声器3.填充”
    //扬声器3
  • 因此,我有一个开关(在SwiftUI中切换)来切换我的声音选项和四幅图像的动画。这是我希望图像设置动画的方式: 启用切换时:

  • speakerEmpty
    应将动画设置为->
    speaker1
    然后
  • speaker1
    应将动画设置为->
    speaker2
    然后
  • speaker2
    应设置为->
    speaker3
  • 当切换开关关闭时反转

    以下是我尝试的代码:

    SpeakerSymbol枚举

    说话人选择可观察对象

    纵断面图


    我想我的代码逻辑很好。图像正在以应有的方式被替换。但动画效果不起作用。令人沮丧的是,我尝试了很多可能的方法,但都没有奏效。

    这里是可能的方法。我简化它是为了演示和减少发布代码,但这个想法应该是清晰的,并且易于转换到您的真实代码中

    结果演示(确实比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)
                    }
                }
            }
        }
    }