Hi,
I use a Picker in a NavigationView like this:
struct ContentView: View {
@State private var selectedFlavor = Flavor.chocolate
enum Flavor: String, CaseIterable, Identifiable {
case chocolate
case vanilla
case strawberry
var id: String { self.rawValue }
}
var body: some View {
NavigationView {
Form {
Picker("Flavor", selection: $selectedFlavor) {
Text("Chocolate").tag(Flavor.chocolate)
Text("Vanilla").tag(Flavor.vanilla)
Text("Strawberry").tag(Flavor.strawberry)
}
}
.navigationTitle(Text("I scream"))
}
}
}
Screen shot:
I would expect a title over the selection of "Flavor" when the Picker is opened in a new view (marked in red), but there is no title and I did not find out how to add one without altering the title of the parent view:
If you add a .navigationBarTitle() in the Form or Picker you only change the parent view title.
Do I miss something here or is it not possible to show the Picker title during selection in the new view?
I am using Xcode 13.0 and Swift 5 and the simulator for the screen shot ran iOS 15.0.
Thanks,
Christian
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
Hi,
I programmed an app to draw cards from a deck. After a card is drawn it is hidden from the deck. The drawn state is a property of a card struct in an array inside a deck struct.
This worked well in the past since iOS 14. Since Xcode 16 this does not work as before anymore.
This is the Card struct with a Boolfor the drawn state:
struct Card: Codable, Identifiable, Equatable, Hashable {
var isDrawn: Bool
…
}
The cards are stored in an array that is inside a CardDeck struct among other properties:
struct CardDeck: Codable {
var cards: [Card] = []
var cardSpacing: CGFloat
…
mutating func hideCard(card: Card) {
if let cardIndex = self.cards.firstIndex(of: card) {
self.cards[cardIndex].isDrawn = true
}
}
}
The deck is a published property of an observable DeckStore class for permanent storage:
class CardDeckStore: ObservableObject {
@Published var deck: CardDeck = CardDeck()
…
}
The DeckStore class is @StateObject in the App struct:
@main
struct CardApp: App {
@StateObject var store = OpaliaCardDeckStore()
var body: some Scene {
WindowGroup {
ContentView(deck: $store.deck)
}
}
}
Here is the simplified DrawCardsView where I present and draw the cards:
struct DrawCardsView: View {
@Binding var deck: CardDeck
var body: some View {
// Was a NavigationView before
NavigationStack() {
HStack(spacing: deck.cardSpacing) {
ForEach($deck.cards) { $card in
if card.isDrawn {
CardBackView(card: card)
.hidden()
}
else {
NavigationLink(destination: DrawnCardView(card: card, deck: $deck)) {
CardBackView(card: card)
}
}
}
}
}
}
}
To hide a drawn card, hideCard() is called in the DrawnCardView:
struct DrawnCardView: View {
var card: Card
@Binding var deck: CardDeck
@State var drawnCard: DrawnCard = .init()
var body: some View {
DrawnCardSimpleView(drawnCard: self.drawnCard)
.onDisappear(perform: {
deck.hideCard(card: self.card)
})
}
}
I am not a pro in programming and there are better solutions to program this, but this worked until I upgraded to Xcode 16. Now it seems the isDrawn state of a card does not update the DrawCardsView right away anymore. A drawn card is not hidden and still present when returning to DrawCardsView from DrawnCardView. After tapping the same card again or another update of the UI, the card will then be hidden.
I do not know the reason. It seems the binding of the isDrawn state inside an element of the card array in the observable object is not working anymore. Other properties of the observable object like cardSpacing do work as expected.
I can empty the cards array and fill it with new cards without problems in the DrawCardsView.
I eliminated the ForEach loop by addressing the array elements directly, but to no avail. I tried different solutions I found on the internet, but nothing worked.
I was under the impression that every change in an observable object would update the UI.
Any ideas for a explanation/solution?
Thanks,
Christian
Topic:
UI Frameworks
SubTopic:
SwiftUI