Swift - Assign Images to respective ImageView outlets based on REST data - ios

This is inside my viewForHeaderInSection. That means, this happens through each section.
for i in 0..<mySections[section].items!.count {
print("Valid For \(mySections[section].items[i]).")
let imagesArray = [header.icon1, header.icon2, header.icon3, header.icon4, header.icon5]
imagesArray[i].image = UIImage(named: "IconHamburger")
}
So for each section, I get the values for "Valid For".
E.g. Section 1 gets
Valid For ABC.
Valid For PQR.
Valid For XYZ.
Section 2 gets
Valid For ABC.
Valid For XYZ.
and so on...
My question is how do I assign image name to the images in my imagesArray? With condition like -
if Valid For is ABC, image name is "ImageAbc"
if Valid For is PQR, image name is "ImagePqr"
With my current code snippet above, all my image outlets get "IconHamburger" assigned.
Also, I have 5 images in my array and, the "Valid For" items are always <= 5.
So if I get 3 "Valid For" items, images need to be assigned only for the first three images.
Current output Screenshot from a section here -

It doesn't seem like you're very far off from what you're describing. Maybe this?
for i in 0..<mySections[section].items!.count {
let validItems = mySections[section].items[i]
let imagesArray = [header.icon1, header.icon2, header.icon3, header.icon4, header.icon5]
// Map your items to your image name formats (ABC -> ImageAbc)
let validImageNames = validItems.map { "Image" + $0.lowercased().capitalized }
// Update images in your image array
validImageNames.enumerated().forEach { index, imageName in
// Check for index in range
guard index < imagesArray.count else { return }
// Update image
imagesArray[index].image = UIImage(named: imageName)
}
}

Related

Swift ios only pick string values from array

In my app I have an array that looks like this:
var imgArray = [(Data, String)]()
It holds images and the images names and I append data by doing this:
if let firstImage = self.firstImage {
if let firstImageData = firstImage.compressImage() {
self.imgArray.append(firstImageData, self.randomImageName(length: 15))
}
}
Now I need to send all the image names inside that array using alamofire and I tried this:
for imgName in self.imgArray {
parameters["images[]"] = imgName.1
}
But my server responds by saying that images[] is empty, so I think that my ios code never sends an array named images[] containing the image names
Update
I changed the parameter to this:
parameters["images"] = [imgName.1]
This will upload one image, it seems like it overwrites the value each time so I need a way to grap all Strings from the imgArray array
Solution:
parameters["images"] = imgArray.map{$0.1}
This will add all of the image names from imgArray

Creating UIImageView with a tag. Swift 3

I have an int n that holds value.
I want to create a loop that will create UIImageViews with consecutive tags.
My code:
var n:Int = 1
if arrayOfEmojis.count != 0 {
for emoji in arrayOfEmojis {
let emojiView = self.view.viewWithTag(n) as! UIImageView
emojiView.image = emoji
...
}
but the emojiView isn't created.
When I use "if let emojiView = " it also just not created.
Am i using "viewWithTag(n)" func wrong?
_______edit_________
was using .viewWithTag() wrong, had to just assign a tag with .tag property.
However, now, I want to get that view using the tag that was assigned.
I figured now i can use .viewWithTag() func?
I get unexpectedly found nil... when calling :
(n was used in previous loop where imageViews was created, and it was updated to the number of imageViews that was created):
if arrayOfEmojis.count != 0 {
for j in 1...n {
var view1 = self.view.viewWithTag(j) as! UIImageView
arrayOfEmojiViews.append(view1)
}
}
I think you are misunderstanding the purpose of using view​With​Tag(_:​):
Returns the view whose tag matches the specified value.
It does not create a new instance, it is used for getting a specific identified view based on its tag value.
If I am not mistaking, you want to create new instances, by mentioning:
I want to create a loop that will create UIImageViews with
consecutive tags*.
It should be similar to:
var n:Int = 1
var currentTag = 0
if arrayOfEmojis.count != 0 {
for emoji in arrayOfEmojis {
let emojiView = UIImageView(image: emoji)
emojiView.tag = currentTag
currentTag += 1
// don't forget to set the frame for the emojiView
...
}
}
For each iteration, a new instance of UIImageView will be created -by using init(image:​) initializer- and setting its tag value "consecutively" based on the current value of currentTag variable.

Trying to get the current value of a UIImage

My app is a slideshow that changes once a minute with a photo corresponding to each minute in the day. I currently have it checking the time and updating the image every tenth of second, as this will be on many devices at a large public event.
The relevant bits are:
#IBOutlet weak var theBrokenWatch: UIImageView!
if theBrokenWatch.image != UIImage(named: theImageName as String) {
theBrokenWatch.image = getUncachedImage(named: theImageName)
print("changed image to", theCurrentTime as String)
}
func getUncachedImage (named name : String) -> UIImage? {
if let imgPath = NSBundle.mainBundle().pathForResource(name, ofType: nil) {
return UIImage(contentsOfFile: imgPath)
}
return nil
}
Right now the if statement doesn't work. It did work when I was setting the image using imageNamed:, but that had major memory issues with 720 photos. (The CurrentTime is calculated and the matching image path built as theImageName.)
How can I check to see if the image needs to be changed (i.e. it's not what I just calculated as the current time)?
You don't want to use an uncached image to check for equality. Each time its generated, the image object will be different (the image data will be the same, but the wrapper object will be re-generated, and therefore not equal; image equality is not based of of actual bit contents).
Instead, key off the image name. Create a new var, imageName, and set that when you set the image. Then, when your timer fires, check your cached imageName against the new one, and only change the .image var if they're different.

How to get a random image from a folder in swift?

So far I have created a folder of images and I am able to assign 1 of the images to a UIImageView.
But what I want to do now is create a random generator, that will pick a random image from the folder, so if I was to create a button, I could display all of the images separately and randomly on a single UIImageView.
However, this folder is going to have more than 100 images, so I don't want to hard code each one into an array. Also, the names of the image has to be unique to the image itself.
I have been searching online but cannot find information on how to code what will suit my needs. So how would I get and display a random image(s) from a folder in swift?
You can name your images like this
image_0
image_1
image_2
Then use this code to populate your UIImageView
let numberOfImages: UInt32 = 100
let random = arc4random_uniform(numberOfImages)
let imageName = "image_\(random)"
imageView.image = UIImage(named: imageName)
Update
Since you don't want to rename your images you can create a plist file (type Array) where you put all the names of your images
And finally
func loadRandomImage() {
let path = NSBundle.mainBundle().pathForResource("Images", ofType: "plist")!
let names = NSArray(contentsOfFile: path) as! [String]
let random = Int(arc4random_uniform(UInt32(names.count)))
let imageName = names[random]
imageView.image = UIImage(named: imageName)
}
You either need to create an array of string filenames and pick a random filename from the array, or you need to use the file manager (NSFileManager) to get a list of the files in your folder and then pick from THAT array. Nether is very difficult.

How can I set the value of this variable?

I want to change the value of a UIImage view.
This is what I've got so far.
import UIKit
import Foundation
struct imageViews {
var Slope1ImageView: UIImage?
var slopeStatus = dataValues()
func setSlope1Image(slopeStatus1: Int) -> UIImage {
var image: String
switch slopeStatus1 {
case 0:
image = "NotWorkingStatus"
default:
image = "WorkingStatus"
}
var statusImage = UIImage(named: image)
return statusImage
}
}
This my setup.
I have a file which gets an object from Parse.
This will either be 0 or 1.
I then assign the 0 or the 1 to a variable in a struct.
In my code above I have created a instance of this struct.
I have then created a function which will take in a variable from my struct and check if it has the value of zero, it then sets the variable image to the respective image. If it doesn't it sets it to a different image.
How do I set the variable of Slope1ImageViews to the image selected by the function in this way.
Slope1ImageView = setSlope1Image(slopeStatus.SlopeStatus1)
each time I try I get an error along the lines of
cannot assign to "Slope1ImageView" in "self"
I'm at my wits end!
Any help would be greatly appreciated.
I think your problem is with Slope1ImageView. If the first letter is uppercased, Swift assumes you're referring to a class. Furthermore, you need to assign the local to either a variable or a constant. Structs should also have the first letter uppercased. Assuming everything else is set up correctly, you probably just need to do something like this.
struct ImageViews {
// existing code...
}
var instanceOfStruct = ImageViews()
var slope1imageView: UIImage = instanceOfStruct.setSlope1Image(slopeStatus.SlopeStatus1)
There's a lot going on here, I'll touch on some.
Declaration
You shouldn't be using a struct. Images are rather large objects in general and you don't want them to be copied across your app. They should remain reference types and be in a class. Structs/Classes should also be capitalized to adhere to common practice, while properties should be lower case. You also have your name as a plural which implies that it is an array, it shouldn't be this way. Also, don't name something imageView unless its an imageView. On that same line, don't name something image if it's a string. Also, don't prefix a function with set unless it sets something. Your function returns something, so a get prefix is probably better. I feel like you want to set the image within self, so let's do that. So first step is to change this:
struct imageViews {
var Slope1ImageView: UIImage?
var slopeStatus = dataValues()
func setSlope1Image(slopeStatus1: Int) -> UIImage {
var image: String
switch slopeStatus1 {
case 0:
image = "NotWorkingStatus"
default:
image = "WorkingStatus"
}
var statusImage = UIImage(named: image)
return statusImage
}
}
To this:
class SlopeStatus {
var slope1Image: UIImage?
var slopeStatus = dataValues()
func setSlope1Image(slopeStatus1: Int) {
var imageString: String
switch slopeStatus1 {
case 0:
image = "NotWorkingStatus"
default:
image = "WorkingStatus"
}
slope1Image = UIImage(named: image)
}
}
Assignment
You're trying to assign a UIImage to a Class with this:
Slope1ImageView = setSlope1Image(slopeStatus.SlopeStatus1)
With the changes above, it should probably be
var slopeStatusImageObject = SlopeStatus()
slopeStatusImageObject.setSlope1Image(slopeStatus.SlopeStatus1)

Resources