Creating a dice roll app following Angela Yu’s App Brewery bootcamp on Udemy. She uses image literals but those seem to have been deprecated on newer versions of Xcode.
I get the error: Cannot assign value of type ‘UIImage??’ to type ‘UIImage?’ Whenever I try to use diceArray.randomElement()
However, diceArray[Int.random(in:0...5]
seems to work fine. My suspicion is maybe to use .randomElement() I need to use imageView
but new to Swift so not sure if this is correct or what the difference even is. Any explanation would be appreciated. Thanks.
@IBAction func rollButtonPressed(_ sender: UIButton) {
var diceArray = [UIImage(named: "DiceOne"),UIImage(named: "DiceTwo"),UIImage(named: "DiceThree"),UIImage(named:"DiceFour"),UIImage(named:"DiceFive"),UIImage(named:"DiceSix")]
diceImageView1.image = diceArray.randomElement()
diceImageView2.image = diceArray[Int.random(in: 0...5)]
}
2
Answers
UIImage(named:
initializer returnsUIImage?
andrandomElement
returns an Optional so it’s??
, you can force itAs Sh_Khan pointed out, you have an array of Optionals since
UIImage.named(_:)
returns an Optional.I would suggest adding a call to compactMap at the end of your code that declares your array of images:
That will make
diceArray
an array ofUIImage
s instead ofOptional(UIImage)
(and strip out any failed attempts to load images.)Edit:
Alexander pointed out in the comments that this might be a case where force-unwrapping is a good thing.
If you write the code like this:
That version will also create an array of non-optional
UIImage
s. If you mis-name any of the images, or there are other problems, the above code will crash immediately. Once it runs without crashing, though, you can be confident that the images will continue to load.The version with
compactMap()
would simply create an array when any misnamed images were missing.