Reputation: 1835
I've read through about 15 posts on StackOverflow discussing the topic of UIImageViews and animating them to crossfade. I would like to eventually have a crossfade, but I can't even get the images to change at this point.
My code is
var next = 0
let names = ["image_1", "image_2", "image_3", "image_4"]
// While the image is still in memory, keep cycling every few seconds
while ImageView != nil {
print(next % 4)
// Grab the new image
let nextImage = UIImage(named: names[next % 4])
next++
// Set the new image
ImageView.image = nextImage
// Wait a few seconds
NSThread.sleepForTimeInterval(NSTimeInterval(4))
}
The image names are coming out of my xcassets. When I run it, the image doesn't change, but the loop still prints every few seconds
What am I doing wrong?
Upvotes: 0
Views: 41
Reputation: 131418
No. Wrong. Forget you ever heard about sleep and it's variants. It is a huge no-no from the main thread. It blocks the UI, will cause the system to kill your app, and also just plain doesn't work in this case. (UI changes don't take effect until your code returns and visits the event loop)
What you want to do is install and image, then start a timer or use dispatch_after to queue up code that will display a new image after some time interval, and THEN RETURN.
Your code might look like this:
var next = 0
func fetch()
{
// Grab the new image
let nextImage = UIImage(named: names[next % 4])
next++
// Set the new image
ImageView.image = nextImage
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(.5 * NSEC_PER_SEC))
{
fetch()
}
}
Upvotes: 1
Reputation: 435
You are running this Loop in the main Thread
So the loop blocks your MainThread and the ImageView cannot be updated.
UI-Stuff is not updated immediately when your code is hit.
You can do something like this:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
while ImageView != nil {
print(next % 4)
let nextImage = UIImage(named: names[next % 4])
next++
dispatch_async(dispatch_get_main_queue()) {
// UI Changes need to be done in the main thread
ImageView.image = nextImage
}
// blocking code needs to be done in another thread
NSThread.sleepForTimeInterval(NSTimeInterval(4))
}
}
Upvotes: 1