web-dev-qa-db-ja.com

フォームのSwiftUI Pickerに選択した行が表示されない

現在選択されているオプションを示すピッカーを作成しようとしています。

正しいオプションを正しく選択する次のコードを試してください。ただし、ピッカーはどのオプションが選択されているかを表示しません。

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()
    }
}

誰が何が悪いのか知っていますか? Xcode 11.1とiOS 13.1を使用して監視されています

7

私は「ListPicker」と呼ぶシンプルなピッカーを作成しました。フォームでうまく機能するように書きました。フォームの外で必要な場合は、いじくり回す必要があります。コードを改善する方法を見つけたら、コメントを追加してください。これはまだ私たち全員にとっての学習経験です。

// 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()
                }
            }
        }
    }
}

その後、次のように使用できます。

@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

これはSwiftUIの大きなバグです。フォームにピッカーがある場合は、選択した値をフォームに表示できる必要があります。それ以外の場合は、独自のピッカーのようなものをロールバックする必要があります。

0
P. Ent