UIImageView动画在UICollectionViewCell

时间:2015-09-02 14:47:41

标签: ios swift animation uiimageview uicollectionviewcell

我想在UIImageView内添加UICollectionViewCell动画,所以我想出了这段代码:

    import UIKit

class MainViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {

    var items:[String] = ["one", "two", "three", "four"]

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = UIColor(red: 220/255, green: 220/255, blue: 220/255, alpha: 1.0)
        self.view.addSubview(self.collectionView)
    }

    lazy var collectionView:UICollectionView = {
        var cv = UICollectionView(frame: self.view.bounds, collectionViewLayout: self.flowLayout)
        cv.delegate = self
        cv.dataSource = self
        cv.bounces = true
        cv.alwaysBounceVertical = true
        cv.autoresizingMask = UIViewAutoresizing.FlexibleHeight | UIViewAutoresizing.FlexibleWidth
        cv.registerClass(CustomCell.self, forCellWithReuseIdentifier: "cell")
        cv.backgroundColor = UIColor(red: 220/255, green: 220/255, blue: 220/255, alpha: 1.0)
        return cv
    }()

    lazy var flowLayout:UICollectionViewFlowLayout = {
        var flow = UICollectionViewFlowLayout()
        flow.sectionInset = UIEdgeInsetsMake(2.0, 2.0, 2.0, 2.0)
        return flow
    }()


    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize{

        let width:CGFloat = self.view.bounds.size.width*0.98;
        let height:CGFloat = 150.0;
        return CGSizeMake(width, height)
    }

    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int{
        return self.items.count
    }

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as! CustomCell
        cell.layer.cornerRadius = 4
        cell.backgroundColor = UIColor.whiteColor()
        cell.imgView.animationImages = ["1","2","3","4","5", "6","7","8"].map{UIImage(named: $0)!}
        cell.imgView.animationDuration = NSTimeInterval(0.8)
        cell.imgView.startAnimating()
        return cell
    }

    func collectionView(collectionView: UICollectionView, shouldHighlightItemAtIndexPath indexPath: NSIndexPath) -> Bool {
         return true
    }

    func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
        var alert = UIAlertController(title: "Alert!", message: "Cell tapped", preferredStyle: UIAlertControllerStyle.Alert)
        var action = UIAlertAction(title: "ok", style: UIAlertActionStyle.Cancel) { (dd) -> Void in }
        alert.addAction(action)
        self.presentViewController(alert, animated: true, completion: nil)
    }

}

这是我的MainViewController,以编程方式添加了CollectionView

    import UIKit

class CustomCell: UICollectionViewCell {

    override init(frame: CGRect) {
        super.init(frame: frame)
        self.addSubview(self.imgView)
    }

    lazy var imgView:UIImageView = {
        var iv = UIImageView()
        iv.contentMode = UIViewContentMode.ScaleAspectFill
        return iv
    }()

    required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        self.imgView.frame = CGRectMake(6,15,self.frame.width*0.2, self.frame.height*0.8)
    }
}

这是我的自定义UICollectionViewCell UIImageView

我的问题是当你点击一个单元格UIImageView消失时。试图解决问题,我开始寻找另一个UICoolectionView 委托方法。然后我尝试使用shouldHighlightItemAtIndexPath,但是如果我使用此方法返回 false ,则动画正常,但集合视图停止响应didSelectItemAtIndexPath

这是一个github存储库,其中包含显示问题的代码:https://github.com/gazolla/ImageAnimation使用解决方案更新

SOLUTION:

在matt的帮助下,我在代码中进行了以下更改:

1)将图像数组添加到highlightedAnimationImages属性

let animationArray = ["1","2","3","4","5", "6","7","8"].map{UIImage(named: $0)!}
cell.imgView.highlightedAnimationImages = animationArray

2)取消选择单元格时重新启动动画

 func collectionView(collectionView: UICollectionView, didDeselectItemAtIndexPath indexPath: NSIndexPath) {
    if let cell = collectionView.cellForItemAtIndexPath(indexPath) as? CustomCell{
        cell.imgView.startAnimating()
    }
 }

3)选择单元格后重新启动动画

func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {

    let cell = collectionView.cellForItemAtIndexPath(indexPath) as! CustomCell
    cell.imgView.startAnimating()

    //...

}

解决方案2:

经过一些测试,我发现当你点击并按住时,一个单元格UIImageView会再次消失,所以我们必须用另外两种方法重新启动动画:

1)didHighlightItemAtIndexPath

func collectionView(collectionView: UICollectionView, didHighlightItemAtIndexPath indexPath: NSIndexPath) {
        if let cell = collectionView.cellForItemAtIndexPath(indexPath) as? CustomCell{
            cell.imgView.startAnimating()
        }

  }

2)didUnhighlightItemAtIndexPath

func collectionView(collectionView: UICollectionView, didUnhighlightItemAtIndexPath indexPath: NSIndexPath) {
    if let cell = collectionView.cellForItemAtIndexPath(indexPath) as? CustomCell{
        cell.imgView.startAnimating()
    }
}

6 个答案:

答案 0 :(得分:2)

当您选择单元格时,图片视图会查看其highlightedAnimationImages,而不是其animationImages。您没有设置highlightedAnimationImages,因此您什么也看不见。

这是一个截屏视频,显示这可行。当背景为灰色(即selectedBackgroundView)时,将选择单元格但动画仍在继续:

enter image description here

答案 1 :(得分:1)

如果其他人遇到这个讨厌的错误并且上述解决方案无效 - 请尝试在您的单元格的imageView.stopAnimating()函数中调用prepareForReuse()

答案 2 :(得分:0)

来自@Sebastian的Swift 4版解决方案2。

func collectionView(_ collectionView: UICollectionView, didHighlightItemAt indexPath: IndexPath) {
    if let cell = collectionView.cellForItem(at: indexPath) as? CustomCell {
        cell.imgView.startAnimating()
    }
}

func collectionView(_ collectionView: UICollectionView, didUnhighlightItemAt indexPath: IndexPath) {
    if let cell = collectionView.cellForItem(at: indexPath) as? CustomCell {
        cell.imgView.startAnimating()
    }
}

答案 3 :(得分:0)

我遇到了同样的问题,但是我没有使“ didDeselectItemAtIndexPath”正常工作,所以我的解决方案是在图片上添加一个没有任何功能的按钮。

因此,当您触摸图片时,您将改为触摸按钮。

答案 4 :(得分:0)

The solution 1 and 2 based on Sebastian 给了我灵感。当 UITableViewCell isSelectedisHighlighted 状态改变时,它会调用 setSelected:animated:setHighlighted:animated 方法。所以,我重写了自定义 UITableViewCell 的方法。

class DCFWFailReasonCell: UITableViewCell {

    // Local flag for UIImageView animation.
    fileprivate var isAnimation: Bool = false

    // Setup animation images 
    func configure(animateImage: [UIImage], duration: TimeInterval) {
        imgView.animationImages = animateImage
        imgView.highlightedAnimationImages = animateImage
        
        imgView.animationDuration = duration
        imgView.animationRepeatCount = 0 //< 0 infinite
        
        imgView.startAnimating()

        // imgView has animation.         
        isAnimation = true
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
        
        // 
        if (self.isAnimation) {
            imgView.startAnimating()
        }
    }
    
    override func setHighlighted(_ highlighted: Bool, animated: Bool) {
        super.setHighlighted(highlighted, animated: animated)
        
        if (self.isAnimation) {
            imgView.startAnimating()
        }
    }

}

答案 5 :(得分:0)

这是我的解决方案,效果很好

class MyImageView: UIImageView {
    
    override func stopAnimating() {
        super.stopAnimating()
        startAnimating()
    }
}