I would like to add a UIImageView
animated inside an UICollectionViewCell
so I came up with this code:
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)
}
}
This is my MainViewController with a CollectionView
added programmatically.
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)
}
}
And this is my custom UICollectionViewCell
with an UIImageView
My problem is when you tap a cell the UIImageView
disappears. Trying to solve the problem I started to look another UICoolectionView
delegate methods. Then I tried to use shouldHighlightItemAtIndexPath
, But If I use this method returning false the animation works fine but the collection view stops responding to didSelectItemAtIndexPath
.
This is a github repository with a code that shows the issue: https://github.com/gazolla/ImageAnimation (updated with solution)
SOLUTION:
With matt's help, I made the following changes in my code:
1) add images array to highlightedAnimationImages
property
let animationArray = ["1","2","3","4","5", "6","7","8"].map{UIImage(named: $0)!}
cell.imgView.highlightedAnimationImages = animationArray
2) Restart animation when cells are deselected
func collectionView(collectionView: UICollectionView, didDeselectItemAtIndexPath indexPath: NSIndexPath) {
if let cell = collectionView.cellForItemAtIndexPath(indexPath) as? CustomCell{
cell.imgView.startAnimating()
}
}
3) Restart animation when cells are selected
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
let cell = collectionView.cellForItemAtIndexPath(indexPath) as! CustomCell
cell.imgView.startAnimating()
//...
}
SOLUTION 2:
After some tests, I found out that when you tap and hold a cell UIImageView
disappears again, So we have to restart animation in another two methods:
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()
}
}