ChrisHooked
ChrisHooked

Reputation: 60

Change UIImageView.image with delay

Okay, so I'm trying to create a "slideshow" of sorts by creating a class that would store an array of UIImages, and have a function that would choose a random index from the array and then assign the associate image to the image view in ViewController.h

import UIKit
import AVFoundation

class ViewController: UIViewController {


var audioPlayer = AVAudioPlayer()
var audioPath = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("1-08 Patient Love", ofType: "mp3")!)
var playPauseBtn = UIBarButtonItem()
var musicPaused: Bool = false

@IBOutlet var toolbar: UIToolbar!  
@IBOutlet var bg1: UIImageView!
@IBOutlet var bg2: UIImageView!
@IBOutlet var bg3: UIImageView!
@IBOutlet var bg4: UIImageView!
@IBOutlet var bg5: UIImageView!
@IBOutlet var bg6: UIImageView!
@IBOutlet var bg7: UIImageView!
@IBOutlet var bg8: UIImageView!
@IBOutlet var bg9: UIImageView!
@IBOutlet var bg10: UIImageView!
@IBOutlet var bg11: UIImageView!

override func viewDidLoad() {
    super.viewDidLoad()

    do{
        audioPlayer = try AVAudioPlayer(contentsOfURL: audioPath)}
    catch {
            print("Audio file not found.")
        }
}

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

@IBAction func playPause(sender: UIBarButtonItem){

    var items = toolbar.items!

    if musicPaused == false {

        playPauseBtn = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Pause, target: self, action: "playPause:")

        items[0] = playPauseBtn

        toolbar.setItems(items, animated: true)

        audioPlayer.play()
        musicPaused = true

    }else{

        var items = toolbar.items!

        playPauseBtn = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Play, target: self, action: "playPause:")
        items [0] = playPauseBtn
        toolbar.setItems(items, animated: true)

        audioPlayer.pause()
        musicPaused = false
    }
}

@IBAction func stopButton(sender: AnyObject) {

    var items = toolbar.items!
    audioPlayer.stop()
    audioPlayer.currentTime = 0
    playPauseBtn = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Play, target: self, action: "playPause:")
    items[0] = playPauseBtn
    toolbar.setItems(items, animated: true)
    musicPaused = false
}
}

This is my view controller.swift file. I don't have a reference yet to the function I'm trying to write in a slideshow.swift file here

import UIKit

var imageArray: [UIImage] = [
UIImage(named: "dec11.jpg")!,
UIImage(named: "dec18.jpg")!,
UIImage(named: "dec19.jpg")!,
UIImage(named: "dec19-2.jpg")!,
UIImage(named: "dec24.jpg")!,
UIImage(named: "dec25.jpg")!,
UIImage(named: "dec30.jpg")!,
UIImage(named: "jan1.jpg")!,
UIImage(named: "jan20.jpg")!,
UIImage(named: "jan24.jpg")!,
UIImage(named: "jan30.jpg")!
]

The slideshow class is

class slideshow: NSObject {

func changeImage() -> UIImage{
    //wait 2 secs
    let seconds = 2.0
    let delay = seconds * Double(NSEC_PER_SEC)  // nanoseconds per seconds
    let dispatchTime = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))

    dispatch_after(dispatchTime, dispatch_get_main_queue(), {

        //here code perfomed with delay
        //generate random number
        let randomIndex = Int(arc4random_uniform(11))

        var imageAtIndex = imageArray[randomIndex]

        return imageAtIndex
    })
}
}

Would it be easier to just write this all in view controller? I changed the function declaration as per the suggestion of other users, but I'm still getting the same error.

Upvotes: 0

Views: 1079

Answers (2)

Steve
Steve

Reputation: 951

The following code is untested but you should be able to do something like the following. The slideshow class contains the list of possible images with a start and stop method. The animate method calls recursively so you don't have to call it from your vc every time.

import UIKit
import AVFoundation

class ViewController: UIViewController {

var audioPlayer = AVAudioPlayer()
var audioPath = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("1-08 Patient Love", ofType: "mp3")!)
var playPauseBtn = UIBarButtonItem()
var musicPaused: Bool = false

@IBOutlet var toolbar: UIToolbar!  
@IBOutlet var bg: UIImageView!

override func viewDidLoad() {
    super.viewDidLoad()

    do{
        audioPlayer = try AVAudioPlayer(contentsOfURL: audioPath)}
    catch {
            print("Audio file not found.")
        }
}

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

@IBAction func playPause(sender: UIBarButtonItem){

    var items = toolbar.items!

    if musicPaused == false {

        playPauseBtn = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Pause, target: self, action: "playPause:")

        items[0] = playPauseBtn

        toolbar.setItems(items, animated: true)

        audioPlayer.play()
        musicPaused = true
        slideshow.startSlideshow(bg)

    }else{

        var items = toolbar.items!

        playPauseBtn = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Play, target: self, action: "playPause:")
        items [0] = playPauseBtn
        toolbar.setItems(items, animated: true)

        audioPlayer.pause()
        slideshow.stopSlideshow()
        musicPaused = false
    }
}

@IBAction func stopButton(sender: AnyObject) {

    var items = toolbar.items!
    audioPlayer.stop()
    audioPlayer.currentTime = 0
    playPauseBtn = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Play, target: self, action: "playPause:")
    items[0] = playPauseBtn
    toolbar.setItems(items, animated: true)
    musicPaused = false
    slideshow.stopSlideshow()
}
}


class slideshow: NSObject {

var imageArray: [UIImage] = [
UIImage(named: "dec11.jpg")!,
UIImage(named: "dec18.jpg")!,
UIImage(named: "dec19.jpg")!,
UIImage(named: "dec19-2.jpg")!,
UIImage(named: "dec24.jpg")!,
UIImage(named: "dec25.jpg")!,
UIImage(named: "dec30.jpg")!,
UIImage(named: "jan1.jpg")!,
UIImage(named: "jan20.jpg")!,
UIImage(named: "jan24.jpg")!,
UIImage(named: "jan30.jpg")!
]
var shouldAnimate: boolean?

func startSlideshow(imageView: UIImageView) {
    shouldAnimate = true
    self.animate()
}

func stopSlideshow() {
    shouldAnimate = false
}

func animate() {
        //wait 2 secs
    let seconds = 2.0
    let delay = seconds * Double(NSEC_PER_SEC)  // nanoseconds per seconds
    let dispatchTime = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))

    dispatch_after(dispatchTime, dispatch_get_main_queue(), {

        //here code perfomed with delay
        //generate random number
        let randomIndex = Int(arc4random_uniform(11))

        var imageAtIndex = imageArray[randomIndex]

        imageView.image = imageAtIndex
        if (shouldAnimate) {
          self.animate()
        }
    })
  }
}

Upvotes: 0

wottle
wottle

Reputation: 13650

You can't have two declarations of the variable image. You have one that is passed into the function:

@IBAction func changeImage (image: UIImage){

And another that is part of your delayed action:

    //return image at index
    var image = imageAtIndex

You don't want to return the image, you want to set the image property of the UIImageView to the image from the array, assuming your array contains UIImage.

So change your function decalaration to be

func changeImage (imageViewToChange: UIImageView){

Then change the dispatch_after code to be

dispatch_after(dispatchTime, dispatch_get_main_queue(), {

    //here code performed after delay
    //generate random number
    let randomIndex = Int(arc4random_uniform(11))

    //return image at index
    imageViewToChange.image = imageArray[randomIndex]
})

Upvotes: 1

Related Questions