如何在SwiftUI中对图像进行动画处理,以播放帧动画

时间:2019-07-22 17:52:34

标签: ios swift uiimageview swiftui

我想在SwiftUI的“图像”视图中对图像进行动画处理

首先,我尝试创建一些变量和一个函数来切换Image(“ imageVariable”)。它发生了变化,但是甚至没有动画尝试过withAnimation { }方法

第二,我尝试使用UIKit视图。在这里,动画有效,但是我不能应用resizable()修饰符或设置固定帧

var images: [UIImage]! = [UIImage(named: "pushup001")!, UIImage(named: "pushup002")!]

let animatedImage = UIImage.animatedImage(with: images, duration: 0.5)

struct workoutAnimation: UIViewRepresentable {

    func makeUIView(context: Self.Context) -> UIImageView {
        return UIImageView(image: animatedImage)
    }

    func updateUIView(_ uiView: UIImageView, context: UIViewRepresentableContext<workoutAnimation>) {

    }
}


struct WorkoutView: View {
    var body: some View {
        VStack {
            workoutAnimation().aspectRatio(contentMode: .fit)
        }
    }
}

在方法1中,我可以更改图像但不能设置动画,而在方法2中,我可以设置动画但不能控制其大小

4 个答案:

答案 0 :(得分:1)

如果您想为动画图像(例如GIF / APNG / WebP)提供健壮且简洁的SwiftUI实现,建议使用SDWebImageSwiftUI。该框架基于现有的成功图像加载框架SDWebImage,并提供SwiftUI绑定。

要播放动画,请使用AnimatedImage视图。

var body: some View {
    Group {
        // Network
        AnimatedImage(url: URL(string: "https://raw.githubusercontent.com/liyong03/YLGIFImage/master/YLGIFImageDemo/YLGIFImageDemo/joy.gif"))
        .onFailure(perform: { (error) in
            // Error
        })
    }
}

答案 1 :(得分:1)

感谢 ImageAnimated 类!它派上用场了!一件事,如果您打算传入值,持续时间应该是一个变量而不是一个常量。否则您必须将持续时间排除在 ImageAnimated(imageSize:imageNames:) 调用之外。 :)

var duration: Double = 0.5

答案 2 :(得分:0)

我使用UIViewRepresentable协议解决了这个问题。在这里,我返回了一个带有ImageView的UIView作为其子视图。这使我可以更好地控制孩子的大小,等等。

import SwiftUI


var images : [UIImage]! = [UIImage(named: "pushup001")!
, UIImage(named: "pushup002")!]

let animatedImage = UIImage.animatedImage(with: images, duration: 0.5)


struct workoutAnimation: UIViewRepresentable {

func makeUIView(context: Self.Context) -> UIView {
   let someView = UIView(frame: CGRect(x: 0, y: 0
    , width: 400, height: 400))

    let someImage = UIImageView(frame: CGRect(x: 20, y: 100, width: 360, height: 180))

    someImage.clipsToBounds = true
    someImage.layer.cornerRadius = 20
    someImage.autoresizesSubviews = true
  someImage.contentMode = UIView.ContentMode.scaleAspectFill

    someImage.image = animatedImage

    someView.addSubview(someImage)

    return someView
  }

func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext<workoutAnimation>) {

}
}


struct WorkoutView: View {


var body: some View {
    VStack (alignment: HorizontalAlignment.center, spacing: 10) {

        workoutAnimation()

        Text("zzzz")
           }
}

}

答案 3 :(得分:0)

我创建了一个图像动画类,可以轻松地重用

import SwiftUI

struct ImageAnimated: UIViewRepresentable {
    let imageSize: CGSize
    let imageNames: [String]
    let duration: Double = 0.5

    func makeUIView(context: Self.Context) -> UIView {
        let containerView = UIView(frame: CGRect(x: 0, y: 0
            , width: imageSize.width, height: imageSize.height))

        let animationImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: imageSize.width, height: imageSize.height))

        animationImageView.clipsToBounds = true
        animationImageView.layer.cornerRadius = 5
        animationImageView.autoresizesSubviews = true
        animationImageView.contentMode = UIView.ContentMode.scaleAspectFill

        var images = [UIImage]()
        imageNames.forEach { imageName in
            if let img = UIImage(named: imageName) {
                images.append(img)
            }
        }

        animationImageView.image = UIImage.animatedImage(with: images, duration: duration)

        containerView.addSubview(animationImageView)

        return containerView
    }

    func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext<ImageAnimated>) {

    }
}

使用方式:

ImageAnimated(imageSize: CGSize(width: size, height: size), imageNames: ["loading1","loading2","loading3","loading4"], duration: 0.3)
                        .frame(width: size, height: size, alignment: .center)