Swift - 如何给图片添加动画效果?

23

我想在特定时间段内使图像动画化。在Objective C中它运行良好。然而,在Swift中它没有运作,我的错误在哪里?

Objective-C的代码如下:

-(void)viewDidLoad
{
   [super viewDidLoad];
   NSMutableArray *imgListArray=[NSMutableArray array];
   for (int i=0; i<=11; i++)

   {
       NSString *strImageName=[NSString stringWithFormat:@"c%d.png", i];
       NSLog(@"%@",strImageName);
       UIImage *image=[UIImage imageNamed:strImageName];
       [imgListArray addObject:image];
   }

   self.imgView.animationImages = imgListArray;
   self.imgView.animationDuration =1.0f;    
   [self.imgView startAnimating];
   // Do any additional setup after loading the view, typically from a nib
}

Swift的代码是-

override func viewDidLoad()
{
   super.viewDidLoad()

   var imgListArray :NSMutableArray = []
   for countValue in 1...11
   {
      var strImageName : String = "c\(countValue).png"
      var image = UIImage(named:strImageName) // suggested by Anil
      imgListArray.addObject(image)
   }

   // Swift code HERE for Objective c
}

那行代码 var image = [UIImage imageNamed(strImageName)] 是什么意思?这是一个数组吗?还是 ObjC 和 Swift 的混合语法? - holex
@holex 在 Objective-C 中,它运行良好,但我对 Swift 转换没有什么头绪。 - ChenSmile
var image: UIImage = UIImage(named: strImageName) 变量图像:UIImage = UIImage(named: strImageName) - holex
@holex,我明白你的意思,并在我的问题中进行了修改,现在我想要添加动画效果... - ChenSmile
你需要完成将 ObjC 代码转换为 Swift 的工作... - holex
7个回答

32
[UIImage imageNamed (strImageName)]

这不是swift代码。在swift中应该是:

UIImage(named:strImageName)  

修改后的代码:

var imgListArray :NSMutableArray = []
for countValue in 1...11
    {

        var strImageName : String = "c\(countValue).png"
        var image  = UIImage(named:strImageName)
        imgListArray .addObject(image)
    }

    self.imageView.animationImages = imgListArray;
    self.imageView.animationDuration = 1.0
    self.imageView.startAnimating()

谢谢...我无法做动画。在Objective-C中,我已经使用了上面的代码,在Swift中,我没有任何想法... - ChenSmile
可能有一些情况NSMutableArray不能正常工作。如果您开始收到关于可变数组的奇怪错误,请尝试使用泛型。var imageList Array <AnyObject> = [] - djthoms
如果我使用打包的图像文件,代码会如何更改?这意味着所有动画都在一个文件中! - Famic Tech
@Anil Varghese。我正在获取图像的url列表,那么在这里如何处理它? - Davender Verma

24

对于Swift 2,请使用[UIImage]

var images: [UIImage] = []
for i in 1...2 {
    images.append(UIImage(named: "c\(i)")!)
}
myImageView.animationImages = images
myImageView.animationDuration = 1.0
myImageView.startAnimating()

18

在 Swift 中,你可以更进一步,只需一行简单的代码就能实现这一点:

let loadingImages = (1...11).map { UIImage(named: "c\($0)")! }

然后你可以完成其余部分并将其注入imageView中

self.imageView.animationImages = loadingImages
self.imageView.animationDuration = 1.0
self.imageView.startAnimating()

谢谢您采用这种功能性方法!一个评论:使用flatMap而不是map并明确解包会更安全。 - Włodzimierz Woźniak
这取决于具体情况和你的个人喜好。对于本地图片,我更倾向于崩溃(这样我就知道某些帧丢失了)。如果你从其他地方下载它们,你可以避免显式解包。 - Tiago Almeida

13

在Swift 3中 - 创建图像数组并仅对其进行动画处理。

func animate_images()
{
    let myimgArr = ["1.jpg","2.jpg","3.jpg"]
    var images = [UIImage]()

    for i in 0..<myimgArr.count
    {
        images.append(UIImage(named: myimgArr[i])!)
    }

    imgView_ref.animationImages = images
    imgView_ref.animationDuration = 0.04
    imgView_ref.animationRepeatCount = 2
    imgView_ref.startAnimating()
}

要停止动画,只需编写

 imgView_ref.stopAnimating()

4

Swift 3+

UIImageView可以以两种不同的方式播放动画(其他答案已深入介绍了第一种方法):

    • 创建一个包含要播放的图像的[UIImage]数组
    • 使用此数组设置视图的animationImages属性
    • 设置animationDuration属性
    • 开始动画

以下代码使用#imageLiterals

let images = [img1, img2, img3] // use of #imageLiterals here
let animation = UIImage.animatedImage(with: images, duration: 1)
self.myImageView.image = animation

优点:

如果您经常需要更改 UIImageView 的图像,其中可能有一个图像需要动画效果,那么您不再需要每次都开始/停止动画,也不需要将 animatedImages 属性设置回 nil 才能显示存储在图像视图的 image 属性中的图像。

缺点:

如果封装在单个 UIImage 中而不是数组中,则无法启动/停止动画。


关于 #imageLiterals 的更多信息:

如果要使用图像文字,可以键入 imageLiteral 或只需键入来自资源文件夹的图像名称,Xcode 的代码完成将会提供建议。

进一步阅读:

  • 另一篇关于使用 #imageLiterals 和 #colorLiterals 来实现动画效果的博客文章

2

如果您正在运行多个动画,取决于一个变量,请尝试以下操作。

例如,您可以运行一个动画发送0或1(也许基于您的应用程序是否知道它是白天还是黑夜):

func runAnimation (imgView: UIImageView, arrayPos: Int) {
    let timingArray = [7.0,10.0] //Durations of each
    let frameArray = [43,45]  //Frames for each
    var imgArray: Array<UIImage> = [] //Setup empty array 

    for i in 1 ... frameArray[arrayPos] {
        //Fill empty array with images!!
        let imageToAdd = UIImage(named: "animationNum_\(arrayPos)-frameNum_\(i)")
        imgArray.append(imageToAdd!)
    }
    imgView.animationImages = imgArray
    imgView.animationDuration = timingArray[arrayPos]
    imgView.animationRepeatCount = 2
    imgView.startAnimating()
}

2

如果您想要动画化一组图像,可以采用另一种方法:

var counter = 1
var timer = NSTimer()
@IBOutlet weak var someImg: UIImageView!

override func viewDidLoad() {
    super.viewDidLoad()
    timer = NSTimer.scheduledTimerWithTimeInterval(0.3, target: self, selector: Selector("doSomeAnimation"), userInfo: nil, repeats: true)
}

func doSomeAnimation() {
    //I have four pngs in my project, which are named frame1.png ... and so on


       if counter == 4 {

        counter = 1

        }else {

        counter++
    }

    someImg.image = UIImage(named: "frame\(counter).png")
}

希望能帮到你!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接