Newbie trying to use a UIImages array to pass to control button Images

Trying to get me feet wet on my first app after watching 6 months of tutorials, ITS TIME!

I'm trying to setup a simple volleyball court with 6 players (buttons). I want to be able to control the button's images and have a simple array of 12 player images. I want to use the array for easy manipulation of rotating the floor lineups etc.

I'm getting stuck with trying to pass a UIImage array value to the button.setImage command. I realize I'm getting mixed up and confusing the UIImage with String etc. but not sure how to correct.

                                          /* UIImage_Literals below have images in them */

var playerPics : [UIImage] = [UIImage_Literal1,UIImage_Literal2UIImage_Literal3]
button.setImage(playerPics[1], for: .normal) -----ERROR ATTEMPT1

var playerImg : [String] = ["Image2.jpg","Image3.jpg"]
button.setImage(playerImg[1], for: .normal) -----ERROR ATTEMPT 2

The above is not my exact code and may have bad syntax but its an example of what I'm trying. The button.setImage wants a different type than what I'm providing.

Everyone thank you for your help, I'm a old guy retired but very interested in SWIFT. I realize I'm showing my lack of SWIFT fundamentals here but as mentioned I've been binge watching tutorials too long and have to start at something.

Again thanks.

According to the Apple Docs on setImage(_:for:) the first parameter is looking for a UIImage not the string name of the image.

Instead, to make this work you should use:

button.setImage(UIImage(named: playerPicks[i]), for: .normal)

This may not be the most efficient code but it should get the job done for you.

Thank you very much, very much appreciated.

Unfortunately, I'm still facing that error:

Cannot convert value of type 'UIImage' to expected to expected argument type 'string'.

The setImage() method expects an image as its first argument. Could you have typed setTitle() instead maybe? That expects a String argument.

Also posting your code would make it easier for folks to help you.

class ViewController: UIViewController {

@IBOutlet weak var button_Pos4: UIButton!

var vbPlayerName : [String] = ["Julia","Alicia ","Alexandra"]

var vbPlayerPics : [UIImage] = [#imageLiteral(resourceName: "Image1"),#imageLiteral(resourceName: "Image2"),#imageLiteral(resourceName: "Image3"]


override func viewDidLoad() {
    super.viewDidLoad()

    button_Pos4.setImage(UIImage(named: vbPlayerPics[1]), for: .normal)
}

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

So basically just looking for the correct syntax:

Step 1)

@IBOutlet weak var button: UIButton!

Step 2:

var vbPlayerPics : [UIImage] = [#imageLiteral(resourceName: "Image1") /* NOTE - IMAGE IN CODE

Step 3:

button.setImage(UIImage(named: vbPlayerPics[0]), for: .normal)

This returns on the last line:
Cannot convert value of type 'UIImage' to expected to argument type 'string'.

I think I saw topic in the Stanford tutorials, checking now...

Types are misaligned. The array contains instances of UIImage while the initializer for a UIImage.init(named:) expects a String. This is the reason you see that error message.

One other thing. For experimenting it's okay to use image literals, however for anything else you should rather use the real types.

Something like this should compile.

class YourViewController : UIViewController {
  /* ... */
  var vbPlayerName: [String] = ["Julia", "Alicia", "Alexandra"]

  // The init of UIImage can fail, so it creates a an `Optional<UIImage>` or `UIImage?`
  var vbPlayerPics: [UIImage?] = [
    UIImage(named: "Image1"), 
    UIImage(named: "Image2"), 
    UIImage(named: "Image3")
  ]

  override func viewDidLoad() {
    super.viewDidLoad()
    button_Pos4.setImage(vbPlayerPics[1], for: .normal)
  }
  /* ... */
}

I started from scratch just to get the operation correct:

import UIKit

class ViewController: UIViewController {

var vbPlayerName: [String] = ["Julia", "Alicia", "Alexandra"]

var vbPlayerImages: [UIImage?] = [
UIImage(named: "Image1"),
UIImage(named: "Image2"),
UIImage(named: "Image3"),
]
@IBOutlet weak var button: UIButton!


override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    
button.setImage(vbPlayerImages[0], for: .normal)
    
}

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

}

Thank you everyone for the help, the errors are gone but alas the images don't appear.
I tried Image1.jpg and Image1 with same results.

BTW, the 3 images Image1,Image2,Image3 are in assets..

It may require constrains/sizing etc... I'm on it! no errors is good.

You can just start the very first and easy step of debugging as you teach yourself all the basics.

Add something like this into your viewDidLoad method and see what it prints.

print(vbPlayerImages)

If all images are there then the images are correctly loaded from the asset catalog, otherwise there is something wrong with the names or the linked asset catalog. If they are loaded but do not appear then your image view has some issues. Use the view debugger in Xcode to inspect your view hierarchy.


PS: For better readability in the forums you can use Markdown to format your posts (especially for code samples). ;)

1 Like

A debugging approach I would try is to put a UIImageView on the storyboard and make an outlet to the code. Then programmatically set the image property of that. This will help you determine if there is a problem with your images or how you are setting them in the buttons. As in computer repair, debugging is often about eliminating possibilities.

On a meta note, having a goal app is a great way to learn iOS development. Learning for its own sake, which I have done, can be demotivating.

To add on that, it can also be overwhelming to start with a whole App when learning the programming language itself. That is because there is much, much more into building apps than understanding the quirks of the language. I highly recommend you to read the Swift book side by side with your experiments in app development.

You’re mostly correct here. The only mistake is passing in:

button_Pos4.setImage(UIImage(named: vbPlayerPics[1]), for: .normal)

vbPlayerPics is already an array of images, not of image names, so you just need to pass in a value from there, not a UIImage named one of those

Replacing that with the following will make it work:

button_Pos4.setImage(vbPlayerPics[1], for: .normal)

Ok, off and on for a few hours with no luck.

I took vermont42's idea and created a image view and populated it with a image from the array.

YUP... Worked.

@IBOutlet weak var TestPic: UIImageView!

TestPic.image = vbPlayerImages[1]

SUCCESS.

So the array is fine? but supplying to button.setimage is not?

import UIKit

class ViewController: UIViewController {

/* Simple button with players images*/
@IBOutlet weak var vbButton: UIButton!

/*Simple UIView */
@IBOutlet weak var TestPic: UIImageView!

var vbPlayerName: [String] = ["Julia", "Alicia", "Alexandra"]

var vbPlayerImages: [UIImage?] = [
    UIImage(named: "Image1"),
    UIImage(named: "Image2"),
    UIImage(named: "Image3"),
    ]

override func viewDidLoad() {
    super.viewDidLoad()

TestPic.image = vbPlayerImages[1] 
 /* SUCCESS SHOWS IMAGE IN IMAGEVIEW */
    
vbButton.setImage(vbPlayerImages[1], for: .normal)
/* DOES NOT SHOW IMAGE */

}

The following code works for me, so yours should work also. If you want to email me your project, I will take a look at it.

class ViewController: UIViewController {
  @IBOutlet var button: UIButton!

  override func viewDidLoad() {
    super.viewDidLoad()
    var images: [UIImage?] = [UIImage(named: "foo")]
    button.setImage(images[0], for: .normal)
  }
}

00%20AM

Thank you a ton for helping and I feel bad bugging.

I tried every suggestion, knew what was wrong but still had no success.

I looked in the inspectator and everything appeared linked properly etc.

So, all of a sudden it worked!

I think, well actually I don’t know, but it now works!

I’m super excited going forward, it was just so disappointing getting stuck on a easy concept.

OK, thank you for your time, very much appreciated.

Stuff suddenly working without your understanding why is common. A positive spin on your experience is that you practiced debugging.