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
How to Dispatch_Sync, Dispatch_Async, Dispatch_After, etc in Swift 3, Swift 4, and Beyond
Instantiated Optional Variable Shows as Nil in Xcode Debugger
How to Create Usdz File Using Xcode Converter
Creating Custom Tableview Cells in Swift
Segue and Button Programmatically Swift
Append Text or Data to Text File in Swift
How to Generate a Random Number in Swift Without Repeating the Previous Random Number
Is This Response from the Compiler Valid
Constant Unassigned Optional Will Not Be Nil by Default
Get Associated Value from Enumeration Without Switch/Case
How to Pass Multiple Enum Values as a Function Parameter