Swiftui Picker Separate Texts For Selected Item and Selection View

SwiftUI picker separate texts for selected item and selection view

Possible solution without a Picker

As mention in my comment, there is not yet a solution for a native implementation with the SwiftUI Picker. Instead, you can do it with SwiftUI Elements especially with a NavigationLink. Here is a sample code:

struct Item {
let abbr: String
let desc: String
}

struct ContentView: View {

@State private var selectedIndex = 0
let items: [Item] = [
Item(abbr: "AA", desc: "aaaaa"),
Item(abbr: "BB", desc: "bbbbb"),
Item(abbr: "CC", desc: "ccccc"),
]

var body: some View {
NavigationView {
Form {
NavigationLink(destination: (
DetailSelectionView(items: items, selectedItem: $selectedIndex)
), label: {
HStack {
Text("Chosen item")
Spacer()
Text(self.items[selectedIndex].abbr).foregroundColor(Color.gray)
}
})
}
}
}
}

struct DetailSelectionView: View {
var items: [Item]
@Binding var selectedItem: Int

var body: some View {
Form {
ForEach(0..<items.count) { index in
HStack {
Text(self.items[index].desc)
Spacer()
if self.selectedItem == index {
Image(systemName: "checkmark").foregroundColor(Color.blue)
}
}
.onTapGesture {
self.selectedItem = index
}
}
}
}
}

If there are any improvements feel free to edit the code snippet.

Get selected item from picker | SwiftUI

Here is a simple example of right way of doing this, no need onTapGesture here:

struct ContentView: View {

let units: [String] = ["quot;, "quot;, "quot;, "quot;, "quot;]
@State private var selectedUnit: Int = 0

var body: some View {

Picker(selection: $selectedUnit, label: Text("You selected: \(units[selectedUnit])")) {
ForEach(units.indices, id: \.self) { unitIndex in Text(units[unitIndex]) }
}
.pickerStyle(MenuPickerStyle())
.onChange(of: selectedUnit, perform: { newValue in print("Selected Unit: \(units[newValue])", "Selected Index: \(newValue)")})
}
}

SwiftUI Catch the Picker value from another view

Use @Binding to bind your item.

struct CustomPicker<Item>: View where Item: Hashable {
let items: [Item]
let title: String
let text: KeyPath<Item, String>
let needOptional: Bool
let needSearchBar: Bool

@Binding var item: Item? // <--Here
@State var searchText: String = ""


//-----Other code---------//

And use @State here in content view for getting selected value.

struct ContentView: View {

@State private var selectedItem: Country? //<-- Here

private let countryArray: [Country] = [.init(name: "A"), .init(name: "B")]

var body: some View {
Form {
CustomPicker(items: countryArray, title: "Country", text: \Country.name, needOptional: true, needSearchBar: true, item: $selectedItem) // <-- Here
if let selectedItem = selectedItem {
Text(selectedItem.name)
}
}
}
}

How to call on a view when a Picker selection is selected

Here is an example for solving your problem:

enum CameraEnum: String, CaseIterable { case telephoto, wide, ultraWide}

struct ContentView: View {

@State private var selection: CameraEnum = .wide

var body: some View {

Picker(selection: $selection, label: EmptyView(), content: {

ForEach(CameraEnum.allCases, id:\.self) { item in

Text(item.rawValue)

}

})
.onAppear() { cameraFunction(selection) }
.onChange(of: selection, perform: { value in cameraFunction(value) })

}

private func cameraFunction(_ cameraValue: CameraEnum) {
print("Your camera selection is:", cameraValue)
}

}


Related Topics



Leave a reply



Submit