Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI: Sheet cannot show correct values in first time

Tags:

list

ios

swiftui

I found strange behavior in SwiftUI.

The sheet shows empty text when I tap a list column first time. It seems correct after second time.

Would you help me?

import SwiftUI

let fruits: [String] = [
    "Apple",
    "Banana",
    "Orange",
]

struct ContentView: View {
    @State var isShowintSheet = false
    @State var selected: String = ""
    var body: some View {
        NavigationView {
            List(fruits, id: \.self) { fruit in
                Button(action: {
                    selected = fruit
                    isShowintSheet = true
                }) {
                    Text(fruit)
                }
            }
        }
        .sheet(isPresented: $isShowintSheet, content: {
            Text(selected)
        })
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

list

first tap

after second tap

like image 512
omusubi Avatar asked Nov 12 '20 05:11

omusubi


People also ask

How to present sheet View modally in SwiftUI after pressing a button?

In this tutorial we’re going to learn how to present a new sheet view modally in SwiftUI after pressing a button. In order to achieve it, use .sheet () modifier on the Button view.

Does SwiftUI work with view models?

Watch the WWDC 2020 video Data essentials in SwiftUI. SwiftUI can work absolutely fine with view models, not sure where you’re getting that from - would you like to explain?

What does ispresented mean in SwiftUI?

On SwiftUI the sheet (isPresented) is a view modifier. A modifier that you apply to a view or another view modifier, producing a different version of the original value. Apple Documentation. This means that you are modifying the same view twice. On SwfitUI, the order is important, so only the last one is visible.


Video Answer


2 Answers

Use .sheet(item:) instead. Here is fixed code.

Verified with Xcode 12.1 / iOS 14.1

struct ContentView: View {
    @State var selected: String?
    var body: some View {
        NavigationView {
            List(fruits, id: \.self) { fruit in
                Button(action: {
                    selected = fruit
                }) {
                    Text(fruit)
                }
            }
        }
        .sheet(item: $selected, content: { item in
            Text(item)
        })
    }
}

extension String: Identifiable {
    public var id: String { self }
}

backup

like image 126
Asperi Avatar answered Sep 18 '22 17:09

Asperi


Thank you, Omid.

I changed my code from Asperi's code using @State like this.

import SwiftUI

struct Fruit: Identifiable, Hashable {
    var name: String
    var id = UUID()
}

let fruits: [Fruit] = [
    Fruit(name: "Apple"),
    Fruit(name: "Banana"),
    Fruit(name: "Orange"),
]

struct ContentView: View {
    @State var selected: Fruit?
    var body: some View {
        NavigationView {
            List(fruits, id: \.self) { fruit in
                Button(action: {
                    selected = fruit
                }) {
                    Text(fruit.name)
                }
            }
        }
        .sheet(item: $selected, content: { item in
            Text(item.name)
        })
    }
}
like image 39
omusubi Avatar answered Sep 21 '22 17:09

omusubi