web-dev-qa-db-fra.com

SwiftUI Picker dans un formulaire n'affiche pas la ligne sélectionnée

J'essaie d'avoir un sélecteur qui montre quelle option est actuellement sélectionnée.

Essayez le code suivant qui sélectionne correctement la bonne option mais le sélecteur n'affiche pas quelle option est sélectionnée:

import SwiftUI

struct ContentView: View {
@State var selectedIndex: Int = 0

let strings: [String] = {
    var strings: [String] = []
    for i in 0..<10 {
        strings.append("\(i)")
    }
    return strings
}()

var body: some View {
    NavigationView {
        VStack {
            Form {
                Picker(selection: $selectedIndex,
                       label: Text("Selected string: \(strings[selectedIndex])")) {
                    ForEach(0..<strings.count) {
                        Text(self.strings[$0]).tag($0)
                    }
                }
            }
        }
        .navigationBarTitle("Form Picker",
                            displayMode: NavigationBarItem.TitleDisplayMode.inline)
    }
}

}

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

Quelqu'un sait ce qui pourrait mal se passer? Il est observé en utilisant Xcode 11.1 et iOS 13.1

7
Jose Castellanos

J'ai créé le sélecteur simple que j'appelle "ListPicker" qui devrait convenir à la facture. Je l'ai écrit pour qu'il fonctionne bien dans un formulaire; si vous en avez besoin en dehors d'un formulaire, vous devrez le bricoler. Si vous voyez un moyen d'améliorer le code, veuillez ajouter un commentaire; c'est encore une expérience d'apprentissage pour nous tous.

// MARK: - LIST PICKER (PUBLIC)

struct ListPicker<Content: View>: View {
    @Binding var selectedItem: Int
    var label: () -> Content
    var data: [Any]

    var selectedLabel: String {
        selectedItem >= 0 ? "\(data[selectedItem])" : ""
    }

    var body: some View {
        NavigationLink(destination: ListPickerContent(selectedItem: self.$selectedItem, data: self.data)) {
            ListPickerLabel(label: self.label, value: "\(self.selectedLabel)")
        }
    }
}

// MARK: - INTERNAL

private struct ListPickerLabel<Content: View>: View {
    let label: () -> Content
    let value: String

    var body: some View {
        HStack(alignment: .center) {
            self.label()
            Spacer()
            Text(value)
                .padding(.leading, 8)
        }
    }
}

private struct ListPickerContentItem: View {
    let label: String
    let index: Int
    let isSelected: Bool
    var body: some View {
        HStack {
            Text(label)
            Spacer()
            if isSelected {
                Image(systemName: "checkmark")
                    .foregroundColor(.accentColor)
            }
        }.background(Color.white) // so the entire row is selectable
    }
}

private struct ListPickerContent: View {
    @Environment(\.presentationMode) var presentationMode
    @Binding var selectedItem: Int
    var data: [Any]
    var body: some View {
        List {
            ForEach(0..<data.count) { index in
                ListPickerContentItem(label: "\(self.data[index])", index: index, isSelected: index == self.selectedItem).onTapGesture {
                    self.selectedItem = index
                    self.presentationMode.wrappedValue.dismiss()
                }
            }
        }
    }
}

Ensuite, vous pouvez l'utiliser comme ceci:

@State var selectedCar: Int = 0
let cars = ["Jaguar", "Audi", "BMW", "Land Rover"]

Form {
    ListPicker(
        selectedItem: self.$selectedCar, 
        label: {
            Text("Cars")
        }, 
        data: self.cars
    )
}
1
P. Ent

Il s'agit d'un bug majeur dans SwiftUI. Si vous avez un sélecteur dans un formulaire, vous devez pouvoir afficher la valeur sélectionnée dans le formulaire. Sinon, vous devez lancer votre propre truc de type Picker.

0
P. Ent