UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

Day 28 - BetterRest - Challenge 2

Forums > 100 Days of SwiftUI

Hi togehter,

i came up with the following solution but it does not work the way I want it to.

Picker(selection: $coffeeAmount, label: Text(coffeeAmount == 1 ? "1 cup" : "\(coffeeAmount) cups"), content: {
                        ForEach(1 ..< 21)  { 
                            Text("\($0)")
                        }
                    })

It shows "2" as default in the Picker but coffeAmount seems to be "1" because the tenary operator shows "1 cup". When I select "1" it shows "0 cups" which should not even be possible.

2      

I don't exactly know why yet, but you made me realize that I have the same bug in my code. I was just hiding it by doing it this way.

Picker("", selection: $coffeeAmount) {
    ForEach(1..<21) {number in
        Text(number == 1 ? "\(number) cup" : "\(number) cups")
    }
}

If you use that as your Picker instead, it makes it look like it is working, but actually it is just making the picker show that 1 is selected, while coffeeAmount is actually set to zero in the background.

I have found a solution to the problem, and that is to use an id: .self parameter in the ForEach loop as shown below.

Picker("", selection: $coffeeAmount) {
    ForEach(1..<21, id: \.self) {number in
        Text(number == 1 ? "\(number) cup" : "\(number) cups")
    }
}

That solves the problem, but I can't really give you a detailed explanation of the reason why myself.

It looks like the Picker's values are set by by the ForEach loop to start at zero and count up regardless of what numbers you actually use in your range. You can see that if you just change your range to 83..<110 and test it.

But telling the ForEach loop to use .self as its id: parameter seems to tell it to use the actual numbers in your range, rather than counting up from zero.

2      

Your code would look like this...

Picker(selection: $coffeeAmount, label: Text(coffeeAmount == 1 ? "1 cup" : "\(coffeeAmount) cups"), content: {
    ForEach(1 ..< 21, id: \.self)  { 
        Text("\($0)")
    }
})

2      

thanks a lot.

id: .self solved the problem.

like your said, it seams to count from zero without the .self but i was not able to find a good explanation for this behavior.

2      

Thank you very much.

id:.self was able to address the issue.

It appears to count from zero without the.self, as you stated, but I have not been able to find a reasonable reason for this behaviour.

2      

Hacking with Swift is sponsored by Essential Developer

SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until April 28th.

Click to save your free spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.