Aidan McVay
Aidan McVay

Reputation: 65

How would I view the next image in an array of images?

In this function, I need to change the image of the image view, moving it onto the next image in the array.

private func updateImage(index: Int) {
    for x in 0..<urlArray.count
    {
        let imageUrl:URL = URL(string: "\(urlArray.object(at: x) as! String)")!
        let request:URLRequest = URLRequest.init(url: imageUrl)
        NSURLConnection.sendAsynchronousRequest(request, queue: OperationQueue.main, completionHandler: { (response, imageDta, error) in
            if (error == nil)
            {
                self.imagesArray.add(UIImage(data: imageDta!)!)
                if self.imagesArray.count > 0
                {
                    self.iv.image = self.imagesArray.object(at: 0) as! UIImage
                }
            }else{
                print("ERROR - \(error!)")
            }
        })
    }

}

However, currently, the image being used is set as the image at index 0 in my array. How would I move onto the next image if this function is called multiple times?

This is the line that I mainly need help with:

self.iv.image = self.imagesArray.object(at: 0) as! UIImage

UPDATE: I've tried to add the code Charly Pico suggested to my functions but it doesn't seem to be moving onto the next image in the array, I think it's to do with how it's being called. I'm going to go into detail in how my file is constructed and works to hopefully clarify how I want to use the change image code.

var urlArray:NSMutableArray! = NSMutableArray()
var imagesArray:NSMutableArray! = NSMutableArray()

These arrays which hold the URL's and Images are outside of any function.

func GetTheStories() {
    let ref = FIRDatabase.database().reference().child("Content")
    ref.observe(FIRDataEventType.value, with: {(snapshot) in
        self.fileArray.removeAll()
        if snapshot.childrenCount>0{
            for content in snapshot.children.allObjects as![FIRDataSnapshot]{
                let contentInfo = content.value as? [String: String]
                let contentType = contentInfo?["contentType"]
                let storyLink = contentInfo?["pathToImage"]
                let content = storyLink   
                self.urlArray = NSMutableArray.init(array:[storyLink])                    
            }   
        }  
    })
}

This is the function I call to append the URL's from my Firebase server to the URLSARRAY.

override func viewDidAppear(_ animated: Bool) {

    for x in 0..<urlArray.count
    {
        let imageUrl:URL = URL(string: "\(urlArray.object(at: x) as! String)")!
        let request:URLRequest = URLRequest.init(url: imageUrl)
        NSURLConnection.sendAsynchronousRequest(request, queue: OperationQueue.main, completionHandler: { (response, imageDta, error) in
            if (error == nil)
            {
                self.imagesArray.add(UIImage(data: imageDta!)!)
                if self.imagesArray.count > 0
                {
                    self.iv.image = self.imagesArray.object(at: 0) as! UIImage
                }
            }else{
                print("ERROR - \(error!)")
            }
        })
    }
}

This is the function Charly created and explained which allows me to set the initial image on the ImageView when the screen loads

private func updateImage(index: Int) {
    var imageToPresent = 0
    for x in 0..<urlArray.count
    {
        let imageUrl:URL = URL(string: "\(urlArray.object(at: x) as! String)")!
        let request:URLRequest = URLRequest.init(url: imageUrl)
        NSURLConnection.sendAsynchronousRequest(request, queue: OperationQueue.main, completionHandler: { (response, imageDta, error) in
            if (error == nil)
            {
                self.imagesArray.removeAllObjects()
                self.imagesArray.add(UIImage(data: imageDta!)!)
                if self.imagesArray.count > 0
                {
                    for x in 0..<self.imagesArray.count
                    { 
                        if self.iv.image == self.imagesArray.object(at: x) as! UIImage
                        {
                            imageToPresent = x + 1 
                            if imageToPresent >= self.imagesArray.count
                            {   
                                imageToPresent = 0
                            }
                        }
                    }
                    self.iv.image = self.imagesArray.object(at: imageToPresent) as! UIImage
                }
            }else{
                print("ERROR - \(error!)")
            }
        })
    } 
}

This is the function being called to update the image to the next one in the array. However, I believe it's not working either because my attempt to apply Charly's code below is not correct. This function is called in the ViewDidLoad like so

updateImage(index: 0)

And it is called to update the image here. This function is called when the Segmented progress bar changes to the next one.

func segmentedProgressBarChangedIndex(index: Int) {
    print("Now showing index: \(index)")
    updateImage(index: index)
}

I know it's a bit confusing as to why I'm not using buttons and actions, this is mainly because I'm trying to create an Instagram-style story, with segments that when finished, or the screen is tapped, change the image to the next in the array. I know there's a lot to look over but I think this will explain how I want to use the images array in greater detail.

Upvotes: 2

Views: 396

Answers (3)

Charlie Pico
Charlie Pico

Reputation: 2036

so, lets say that your imagesArray contains 2 images, what I recommend doing is the following:

//Create a @IBAction and attach it to a UIButton in your Storyboard as a touchUpInside action.
@IBAction func changeImage()
{
   //Set a variable with Int as 0.
   var imageToPresent = 0

   //Create a for to check image by image inside the array.
   for x in 0..<imagesArray.count
   {

      //Compare the image at self.iv with the image in imagesArray at index x. And if the images are the same add a + 1 to imageToPresent.
      if self.iv.image == imagesArray.object(at: x) as! UIImage
      {
         imageToPresent = x + 1

         //Check if imageToPresent isn't bigger or equal than imagesArray, otherwise we will get an error and the App will crash.
         if imageToPresent >= imagesArray.count
         {

            //If imageToPreset if bigger or equal to imagesArray.count, it means that there are no more images at a higher index, so we return imageToPresent to 0.
            imageToPresent = 0
         }
      }
   }

   //Set the new image of imagesArray at index imageToPresent as UIImage to self.iv.
   self.iv.image = imagesArray.object(at: imageToPresent) as! UIImage
}

Every time you want to change self.iv image you need to touch the button for the action to be triggered.

UPDATE

So I added a NSTimer to simulate that in 3 seconds your Progress View finishes animating, after the 3 seconds it rotates the image to another one, you can add this code after the for that loads all the images from the urls:

Timer.scheduledTimer(withTimeInterval: 3.0, repeats: true) { (timer) in
        self.changeImage()
    }

And first of all update your urlArray to this:

urlArray = NSMutableArray.init(array: ["https://firebasestorage.googleapis.com/v0/b/motive-73352.appspot.com/o/Content%2F20170525130622.jpg?alt=media&token=1e654c60-2f47-43c3-9298-b0282d27f66c","https://www.videomaker.com/sites/videomaker.com/files/styles/magazine_article_primary/public/articles/18984/363%20C03%20Lighting%20primary.png"])

So you have at least 2 images to make the image rotation.

Upvotes: 1

Lou Franco
Lou Franco

Reputation: 89192

This function is trying to do a lot of things at once, so it's hard to tell how to make it do what you want, but, you do have an index parameter. Using that instead of the 0 here:

  if self.imagesArray.count > index
  {
        self.iv.image = self.imagesArray.object(at: index) as! UIImage
  }

Would wait for that image to load and then set that to the view.

NOTE: you need to check that the index is within bounds

Upvotes: 0

rmp
rmp

Reputation: 3513

change the line to use the index being passed into your function like this

self.iv.image = self.imagesArray.object(at: index) as! UIImage

Upvotes: 0

Related Questions