Reputation: 65
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
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
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
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