Reputation: 1431
I'm trying to animate a UIImageView with images that I created programmatically. Whenever I call startAnimating()
I get the error
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
I understand that this error is thrown when one of the images in imageView.animationImages
is nil, but none of mine are.
Create a new single-view iOS-9 application and paste the following code in viewDidLoad()
of the view controller to see what's going on.
super.viewDidLoad()
//Create an imageview and add it to the view
let imageView = UIImageView()
imageView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(imageView)
imageView.leftAnchor.constraintEqualToAnchor(view.leftAnchor).active = true
imageView.rightAnchor.constraintEqualToAnchor(view.rightAnchor).active = true
imageView.bottomAnchor.constraintEqualToAnchor(view.bottomAnchor).active = true
imageView.topAnchor.constraintEqualToAnchor(view.topAnchor).active = true
//Create an image
let solidColorFilter = CIFilter(name: "CIConstantColorGenerator")!
solidColorFilter.setValue(CIColor(color: UIColor.redColor()), forKey: "inputColor")
let cropFilter = CIFilter(name: "CICrop")!
cropFilter.setValue(CIVector(CGRect: CGRectMake(0, 0, 300, 300)), forKey: "inputRectangle")
cropFilter.setValue(solidColorFilter.outputImage, forKey: "inputImage")
//Create animation images
var animationImages = [UIImage]()
let hueAdjustFilter = CIFilter(name: "CIHueAdjust")!
hueAdjustFilter.setValue(cropFilter.outputImage, forKey: "inputImage")
for (var i: CGFloat = 0; i < 10; i++) {
hueAdjustFilter.setValue(-CGFloat(M_PI) + CGFloat(i/10.0) * 2.0 * CGFloat(M_PI), forKey: "inputAngle")
let hueAdjustedImage = UIImage(CIImage: hueAdjustFilter.outputImage)
animationImages.append(hueAdjustedImage)
}
print("Break here to inspect images in animationImages array. None are nil")
//Try to animate the images using imageview animationImages
imageView.animationImages = animationImages
imageView.animationDuration = 4.0
imageView.startAnimating() //ERROR THROWN HERE
Please help! Thanks!
Upvotes: 1
Views: 265
Reputation: 1431
I figured it out. When a UIImage is created from a CIImage the CGImage property of the UIImage is nil. I guess the backing layer for the UIImageView uses the CGImage to render itself. Anyways, to get a CGImage from a CIImage I had to create a CIContext and then call CIContext.createCGImage:FromRect:
, then use the CGImage to create a UIImage... here's code
//Create a context
let myEAGLContext = EAGLContext(API: EAGLRenderingAPI.OpenGLES2)
let options = [kCIContextWorkingColorSpace: NSNull()]
let myContext = CIContext(EAGLContext: myEAGLContext, options: options)
//Create animation images
var animationImages = [UIImage]()
let hueAdjustFilter = CIFilter(name: "CIHueAdjust")!
hueAdjustFilter.setValue(cropFilter.outputImage, forKey: "inputImage")
for (var i: CGFloat = 0; i < 10; i++) {
hueAdjustFilter.setValue(-CGFloat(M_PI) + CGFloat(i/10.0) * 2.0 * CGFloat(M_PI), forKey: "inputAngle")
let hueAdjustedCGImage = myContext.createCGImage(hueAdjustFilter.outputImage, fromRect: CGRectMake(0, 0, 300, 300))
let finalImage = UIImage(CGImage: hueAdjustedCGImage)
animationImages.append(finalImage)
}
Upvotes: 3