error preventing me from building my project that is ambiguous - ios

I am getting this error in my SwiftUI file. I have tried compiling in Swift 5.3, and 5.4 beta, but I keep getting the same error. This file contains custom views that come from an in-house framework created by me. This framework works fine on other projects, so I have eliminated this being the issue. I have many if statements creating the views based on user selection. The code worked before, but it randomly started stating this error.
import SwiftUI
struct Cheatsheet: View {
var Letters = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","Number 1","Number 2","Number 3","Number 4","Number 5","Number 6","Number 7","Number 8","Number 9","Number 0","Number Sign"]
#State private var selection = 0
var body: some View {
VStack {
//Logic
if selection == 0 {
NavigationView {
NavigationLink(destination: LetterA()) { LetterA()
}
}
}
if selection == 1 {
NavigationView {
NavigationLink(destination: LetterB()) { LetterB()
}
}
}
if selection == 2 {
NavigationView {
NavigationLink(destination: LetterC()) { LetterC()
}
}
}
if selection == 3 {
NavigationView {
NavigationLink(destination: LetterD()) { LetterD()
}
}
}
if selection == 4 {
NavigationView {
NavigationLink(destination: LetterE()) { LetterE()
}
}
}
if selection == 5 {
NavigationView {
NavigationLink(destination: LetterF()) { LetterF()
}
}
}
if selection == 6 {
NavigationView {
NavigationLink(destination: LetterG()) { LetterG()
}
}
}
if selection == 7 {
NavigationView {
NavigationLink(destination: LetterH()) { LetterH()
}
}
}
if selection == 8 {
NavigationView {
NavigationLink(destination: LetterI()) { LetterI()
}
}
}
if selection == 9 {
NavigationView {
NavigationLink(destination: LetterJ()) { LetterJ()
}
}
}
if selection == 10 {
NavigationView {
NavigationLink(destination: LetterK()) { LetterK()
}
}
}
if selection == 11 {
NavigationView {
NavigationLink(destination: LetterL()) { LetterL()
}
}
}
if selection == 12 {
NavigationView {
NavigationLink(destination: LetterM()) { LetterM()
}
}
}
if selection == 13 {
NavigationView {
NavigationLink(destination: LetterN()) { LetterN()
}
}
}
if selection == 14 {
NavigationView {
NavigationLink(destination: LetterO()) { LetterO()
}
}
}
if selection == 15 {
NavigationView {
NavigationLink(destination: LetterP()) { LetterP()
}
}
}
if selection == 16 {
NavigationView {
NavigationLink(destination: LetterQ()) { LetterQ()
}
}
}
if selection == 17 {
NavigationView {
NavigationLink(destination: LetterR()) { LetterR()
}
}
}
if selection == 18 {
NavigationView {
NavigationLink(destination: LetterS()) { LetterS()
}
}
}
if selection == 19 {
NavigationView {
NavigationLink(destination: LetterT()) { LetterT()
}
}
}
if selection == 20 {
NavigationView {
NavigationLink(destination: LetterU()) { LetterU()
}
}
}
if selection == 21 {
NavigationView {
NavigationLink(destination: LetterV()) { LetterV()
}
}
}
if selection == 22 {
NavigationView {
NavigationLink(destination: LetterW()) { LetterW()
}
}
}
if selection == 23 {
NavigationView {
NavigationLink(destination: LetterX()) { LetterX()
}
}
}
if selection == 24 {
NavigationView {
NavigationLink(destination: LetterY()) { LetterY()
}
}
}
if selection == 25 {
NavigationView {
NavigationLink(destination: LetterZ()) { LetterZ()
}
}
}
//END -> Logic
Picker(selection: $selection, label: Text("")) {
ForEach(0 ..< Letters.count) {
Text(Letters[$0])
}
}
}
}
}
struct Cheatsheet_Previews: PreviewProvider {
static var previews: some View {
Cheatsheet()
}
}

It is possible to have not more than 10 views in one container, so group them by 10th, like
Group {
if selection == 0 {
NavigationView {
NavigationLink(destination: LetterA()) { LetterA()
}
}
}
if selection == 1 {
NavigationView {
NavigationLink(destination: LetterB()) { LetterB()
}
}
}
...
if selection == 9 {
NavigationView {
NavigationLink(destination: LetterJ()) { LetterJ()
}
}
}
}
Group {
if selection == 10 {
NavigationView {
NavigationLink(destination: LetterK()) { LetterK()
}
}
}
...
}
or, better, rethink the design to use ForEach view builder.

Problem is here
Picker(selection: $selection, label: Text("")) {
ForEach(0 ..< Letters.count) {
Text(Letters[$0])
}
}
you need self with Letters so it should be
Picker(selection: $selection, label: Text("")) {
ForEach(0 ..< Letters.count) {
Text(self.Letters[$0])
}
}
And second problem is the amount of views added in 1 group, you can't have more than 10 views per 1 group. You would be better off just making a function that takes care of the switching. and its cleaner.
Here is an example
struct Test: View {
var Letters = ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","Number 1","Number 2","Number 3","Number 4","Number 5","Number 6","Number 7","Number 8","Number 9","Number 0","Number Sign"]
#State private var selection = 0
var body: some View {
VStack {
// Logic
getLetterView(selection: self.selection)
//END -> Logic
Picker(selection: $selection, label: Text("")) {
ForEach(0 ..< Letters.count) {
Text(self.Letters[$0])
}
}
}
}
}
func getLetterView(selection: Int) -> AnyView? {
var destination: AnyView? = nil
if selection == 0 {
destination = AnyView(LetterA())
} else if(selection == 1) {
destination = AnyView(LetterB())
} else if(selection == 2) {
destination = AnyView(LetterC())
} else if(selection == 3) {
destination = AnyView(LetterD())
} else if(selection == 4) {
destination = AnyView(LetterE())
} else if(selection == 5) {
destination = AnyView(LetterF())
} else if(selection == 6) {
destination = AnyView(LetterG())
} else if(selection == 7) {
destination = AnyView(LetterH())
} else if(selection == 8) {
destination = AnyView(LetterI())
} else if(selection == 9) {
destination = AnyView(LetterJ())
}
// Rest of your if conditions
return AnyView(NavigationView {
NavigationLink(destination: destination) {
destination
}
})
}

Related

Picker conflicts with NavigationLink gesture

I am trying to create the following card view.
With the following code to achieve it.
struct SimpleGame: Identifiable, Hashable {
var id = UUID()
let name: String
}
enum PlayingStatus: String {
case In = "I"
case Out = "O"
case Undecided = "U"
}
struct TestView: View {
let games: [SimpleGame] = [
.init(name: "First"),
.init(name: "Second")
]
#State private var currentStatus: PlayingStatus = .Undecided
var body: some View {
NavigationView {
List(games) { game in
Section {
VStack {
NavigationLink(value: game) {
Text("\(game.name)")
}
Divider()
Picker("Going?", selection: $currentStatus) {
Text("No Response")
.tag(PlayingStatus.Undecided)
Text("Going")
.tag(PlayingStatus.In)
Text("Not going")
.tag(PlayingStatus.Out)
}
.font(.body)
}
}
}
.navigationDestination(for: Game.self) { game in
Text("Detail View")
}
.listStyle(InsetGroupedListStyle())
.navigationTitle("Upcoming")
}
}
}
But a tap on element wrapped by NavigationLink is registering as a tap on the Picker. Anyone know of a way around this?
iOS 16/Xcode 14
you could try this:
List {
ForEach(games, id: \.name) { game in
Section {
NavigationLink(value: game) {
Text("\(game.name)")
}
// -- here
VStack {
Divider()
Picker("Going?", selection: $currentStatus) {
Text("No Response").tag(PlayingStatus.Undecided)
Text("Going").tag(PlayingStatus.In)
Text("Not going").tag(PlayingStatus.Out)
}
.font(.body)
}
}
}
}
What often works for me is extending the view.
struct TestView: View {
var body: some View {
List {
ForEach(games, id: \.name) { game in
Section {
NavigationLink(value: game) {
Text("\(game.name)")
}
// -- here
VStack {
Divider()
picker
}
}
}
}
}
}
Extension TestView {
private var picker: some View {
Picker("Going?", selection: $currentStatus) {
Text("No Response").tag(PlayingStatus.Undecided)
Text("Going").tag(PlayingStatus.In)
Text("Not going").tag(PlayingStatus.Out)
}
.font(.body)
}
}

SwiftUI searchable modifier cancel button dismisses parent view's sheet presentation

I have a swiftui list with a .searchable modifier, contained within a navigation view child view, within a sheet presentation. When the Cancel button is used, not only is the search field dismissed (unfocused, keyboard dismissed etc), but the navigation view dismisses (ie moves back a page) and then the containing sheet view also dismisses.
This list acts as a custom picker view that allows the selection of multiple HKWorkoutActivityTypes. I use it in multiple locations and the bug only sometimes presents itself, despite being implemented in almost identical views. If I swap the .sheet for a .fullScreenCover, then the presentation of the bug swaps between those previously unaffected and those that were.
The parent view (implemented as a form item, in .sheet):
struct MultipleWorkoutActivityTypePickerFormItem: View, Equatable {
static func == (lhs: MultipleWorkoutActivityTypePickerFormItem, rhs: MultipleWorkoutActivityTypePickerFormItem) -> Bool {
return lhs.workoutActivityTypes == rhs.workoutActivityTypes
}
#Binding var workoutActivityTypes: [HKWorkoutActivityType]
var workoutActivityTypeSelectionDescription: String {
var string = ""
if workoutActivityTypes.count == 1 {
string = workoutActivityTypes.first?.commonName ?? ""
} else if workoutActivityTypes.count == 2 {
string = "\(workoutActivityTypes[0].commonName) & \(workoutActivityTypes[1].commonName)"
} else if workoutActivityTypes.count > 2 {
string = "\(workoutActivityTypes.first?.commonName ?? "") & \(workoutActivityTypes.count - 1) others"
} else {
string = "Any Workout"
}
return string
}
var body: some View {
NavigationLink {
MultipleWorkoutActivityTypePickerView(selectedWorkoutActivityTypes: $workoutActivityTypes)
.equatable()
} label: {
HStack {
Text("Workout Types:")
Spacer()
Text(workoutActivityTypeSelectionDescription)
.foregroundColor(.secondary)
}
}
}
}
And the child view:
struct MultipleWorkoutActivityTypePickerView: View, Equatable {
static func == (lhs: MultipleWorkoutActivityTypePickerView, rhs: MultipleWorkoutActivityTypePickerView) -> Bool {
return (lhs.favouriteWorkoutActivityTypes == rhs.favouriteWorkoutActivityTypes && lhs.selectedWorkoutActivityTypes == rhs.selectedWorkoutActivityTypes)
}
#State var searchString: String = ""
#Environment(\.dismissSearch) var dismissSearch
#Environment(\.isSearching) var isSearching
//MARK: - FUNCTIONS
#Binding var selectedWorkoutActivityTypes: [HKWorkoutActivityType]
#State var favouriteWorkoutActivityTypes: [FavouriteWorkoutActivityType] = []
#State var searchResults: [HKWorkoutActivityType] = HKWorkoutActivityType.allCases
let viewContext = PersistenceController.shared.container.viewContext
func loadFavouriteWorkoutActivityTypes() {
let request: NSFetchRequest<FavouriteWorkoutActivityType> = FavouriteWorkoutActivityType.fetchRequest()
request.sortDescriptors = [NSSortDescriptor(keyPath: \FavouriteWorkoutActivityType.index, ascending: true)]
do {
try favouriteWorkoutActivityTypes = viewContext.fetch(request)
} catch {
print(error.localizedDescription)
}
print("FavouriteWorkoutActivityType - Load")
}
func updateSearchResults() {
if searchString.isEmpty {
searchResults = HKWorkoutActivityType.allCases
} else {
searchResults = HKWorkoutActivityType.allCases.filter { $0.commonName.contains(searchString) }
}
}
func createFavouriteWorkoutActivityType(workoutActivityType: HKWorkoutActivityType) {
let newFavouriteWorkoutActivityType = FavouriteWorkoutActivityType(context: viewContext)
newFavouriteWorkoutActivityType.workoutActivityTypeRawValue = Int16(workoutActivityType.rawValue)
newFavouriteWorkoutActivityType.index = Int16(favouriteWorkoutActivityTypes.count)
print(newFavouriteWorkoutActivityType)
do {
try viewContext.save()
} catch {
print(error.localizedDescription)
}
loadFavouriteWorkoutActivityTypes()
}
func updateFavouriteWorkoutActivityTypeIndex(favouriteWorkoutActivityType: FavouriteWorkoutActivityType) {
//reoder
}
func deleteFavouriteWorkoutActivityType(favouriteWorkoutActivityType: FavouriteWorkoutActivityType) {
viewContext.delete(favouriteWorkoutActivityType)
do {
try viewContext.save()
} catch {
print(error.localizedDescription)
}
loadFavouriteWorkoutActivityTypes()
}
func deleteFavouriteWorkoutActivityTypeFor(workoutActivityType: HKWorkoutActivityType) {
for favouriteWorkoutActivityType in favouriteWorkoutActivityTypes {
if favouriteWorkoutActivityType.workoutActivityTypeRawValue == workoutActivityType.rawValue {
viewContext.delete(favouriteWorkoutActivityType)
}
}
do {
try viewContext.save()
} catch {
print(error.localizedDescription)
}
loadFavouriteWorkoutActivityTypes()
}
func deleteItems(offsets: IndexSet) {
offsets.map { favouriteWorkoutActivityTypes[$0] }.forEach(viewContext.delete)
renumberItems()
do {
try viewContext.save()
} catch {
print(error.localizedDescription)
}
loadFavouriteWorkoutActivityTypes()
}
func renumberItems() {
if favouriteWorkoutActivityTypes.count > 1 {
for item in 1...favouriteWorkoutActivityTypes.count {
favouriteWorkoutActivityTypes[item - 1].index = Int16(item)
}
} else if favouriteWorkoutActivityTypes.count == 1 {
favouriteWorkoutActivityTypes[0].index = Int16(1)
}
// print("ChartsViewModel - Renumber")
do {
try viewContext.save()
} catch {
print(error.localizedDescription)
}
loadFavouriteWorkoutActivityTypes()
}
func moveItems(from source: IndexSet, to destination: Int) {
// Make an array of items from fetched results
var revisedItems: [FavouriteWorkoutActivityType] = favouriteWorkoutActivityTypes.map{ $0 }
// change the order of the items in the array
revisedItems.move(fromOffsets: source, toOffset: destination)
// update the userOrder attribute in revisedItems to
// persist the new order. This is done in reverse order
// to minimize changes to the indices.
for reverseIndex in stride( from: revisedItems.count - 1,
through: 0,
by: -1 )
{
revisedItems[reverseIndex].index =
Int16(reverseIndex)
}
// print("ChartsViewModel - Move")
do {
try viewContext.save()
} catch {
print(error.localizedDescription)
}
loadFavouriteWorkoutActivityTypes()
}
var body: some View {
List {
if searchString == "" {
Section {
ForEach(favouriteWorkoutActivityTypes) { favouriteWorkoutActivityType in
if let workoutActivityType = HKWorkoutActivityType(rawValue: UInt(favouriteWorkoutActivityType.workoutActivityTypeRawValue)) {
HStack {
HStack {
Label {
Text(workoutActivityType.commonName)
} icon: {
Image(systemName: (selectedWorkoutActivityTypes.contains(workoutActivityType) ? "checkmark.circle" : "circle"))
}
Spacer()
}
.contentShape(Rectangle())
.onTapGesture {
if !selectedWorkoutActivityTypes.contains(where: {$0 == workoutActivityType}) {
selectedWorkoutActivityTypes.append(workoutActivityType)
print("does not contain, adding:", workoutActivityType.commonName)
} else {
selectedWorkoutActivityTypes = selectedWorkoutActivityTypes.filter({$0 != workoutActivityType})
print("does contain, removing:", workoutActivityType.commonName)
}
}
Button {
withAnimation {
deleteFavouriteWorkoutActivityType(favouriteWorkoutActivityType: favouriteWorkoutActivityType)
}
} label: {
Image(systemName: "heart.fill")
}
.buttonStyle(BorderlessButtonStyle())
}
}
}
.onDelete(perform: deleteItems(offsets:))
.onMove(perform: moveItems(from:to:))
if favouriteWorkoutActivityTypes.count < 1 {
Text("Save your favourite workout types by hitting the hearts below.")
.foregroundColor(.secondary)
}
} header: {
Text("Favourites:")
}
}
Section {
ForEach(searchResults, id: \.self) { workoutActivityType in
HStack {
HStack {
Label {
Text(workoutActivityType.commonName)
} icon: {
Image(systemName: (selectedWorkoutActivityTypes.contains(workoutActivityType) ? "checkmark.circle" : "circle"))
}
Spacer()
}
.contentShape(Rectangle())
.onTapGesture {
if !selectedWorkoutActivityTypes.contains(where: {$0 == workoutActivityType}) {
selectedWorkoutActivityTypes.append(workoutActivityType)
print("does not contain, adding:", workoutActivityType.commonName)
} else {
selectedWorkoutActivityTypes = selectedWorkoutActivityTypes.filter({$0 != workoutActivityType})
print("does contain, removing:", workoutActivityType.commonName)
}
}
if favouriteWorkoutActivityTypes.contains(where: { FavouriteWorkoutActivityType in
workoutActivityType.rawValue == UInt(FavouriteWorkoutActivityType.workoutActivityTypeRawValue)
}) {
Button {
withAnimation {
deleteFavouriteWorkoutActivityTypeFor(workoutActivityType: workoutActivityType)
}
} label: {
Image(systemName: "heart.fill")
}
.buttonStyle(BorderlessButtonStyle())
} else {
Button {
withAnimation {
createFavouriteWorkoutActivityType(workoutActivityType: workoutActivityType)
}
} label: {
Image(systemName: "heart")
}
.buttonStyle(BorderlessButtonStyle())
}
}
}
} header: {
if searchString == "" {
Text("All:")
} else {
Text("Results:")
}
}
}
.searchable(text: $searchString.animation(), prompt: "Search")
.onChange(of: searchString, perform: { _ in
withAnimation {
updateSearchResults()
}
})
.onAppear {
loadFavouriteWorkoutActivityTypes()
}
.navigationBarTitle(Text("Type"), displayMode: .inline)
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
EditButton()
}
}
}
}

SwiftUI Form Cell losing selection UI when drilling into details?

I have the following code:
enum SelectedDetails:Int, CaseIterable {
case d0
case d1
}
struct CellSelectionTestView : View {
#State var selection:SelectedDetails? = .d0
var body: some View {
NavigationView {
Form {
Section(header: Text("Section 0")) {
NavigationLink(destination: D0DetailsView(),
tag: .d0,
selection: $selection) {
D0CellView().frame(height: 80)
}
NavigationLink(destination: D1CellView(),
tag: .d1,
selection: $selection) {
D1CellView().frame(height: 80)
}
}
}
}
}
}
struct D0CellView: View {
var body: some View {
Text("D0")
}
}
struct D0DetailsView: View {
var body: some View {
VStack {
List {
ForEach(0..<10) { n in
NavigationLink.init(destination: OptionsDetailsView(index:n)) {
Text("show \(n) details")
}
}
}
.refreshable {
}
}
}
}
struct OptionsDetailsView: View {
let index:Int
var body: some View {
Text("OptionsDetailsView \(index)")
}
}
struct D1CellView: View {
var body: some View {
Text("D1")
}
}
When I tap on D0 cell, it shows this:
D0 cell correctly shows the selected state UI.
Then I tap on one of the show <n> details cells and the selection goes away:
How do I keep D0 cell selected UI stated active until I tap on another cell like D1 for example regardless of what I do in the details view to the right? I need to keep UI context as the user does what is needed within the details shown when D0 is tapped. Why is that selection going away if I didn't even tap on D1?
Strange, but it seems like NavigationView can only keep one selection. I found a workaround by integrating a second NavigationView with .stacked style in your child view:
struct D0DetailsView: View {
var body: some View {
NavigationView {
VStack {
List {
ForEach(0..<10) { n in
NavigationLink {
OptionsDetailsView(index:n)
} label: {
Text("show \(n) details")
}
}
}
.refreshable {
}
}
}
.navigationViewStyle(.stack)
}
}
Another approach: save the last active selection and set the select background color manually:
struct CellSelectionTestView : View {
#State private var selection: SelectedDetails? = .d0
#State private var selectionSaved: SelectedDetails = .d0
var body: some View {
NavigationView {
Form {
Section(header: Text("Section 0")) {
NavigationLink(tag: .d0, selection: $selection) {
D0DetailsView()
} label: {
D0CellView().frame(height: 80)
}
.listRowBackground(selectionSaved == .d0 ? Color.gray : Color.clear)
NavigationLink(tag: .d1, selection: $selection) {
D1CellView()
} label:{
D1CellView().frame(height: 80)
}
.listRowBackground(selectionSaved == .d1 ? Color.gray : Color.clear)
}
}
}
.onChange(of: selection) { newValue in
if selection != nil { selectionSaved = selection! }
}
}
}

SwiftUI - Section style difference when embedding List within a VStack

It seems that there is a difference in showing a List Section header when you embed the List in a VStack. Does anybody know why this happens?
struct ContentView: View {
#State var toggle: Bool = false
let items: [String] = ["Apple", "Pear", "Banana"]
var body: some View {
NavigationView {
if toggle {
VStack {
list
}
} else {
list
}
}
}
var list: some View {
List {
Section {
ForEach(items, id: \.self) { item in
Text(item)
}
} header: {
Text("Fruit")
}
}
.navigationTitle(toggle ? "VStack" : "No VStack")
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button {
toggle.toggle()
} label: {
Text("Toggle")
}
}
}
}
}

SwiftUI - Present 3 different Views with different parameter

I need to present 3 different Views.
AddListView
ChangeColor
EditListView
They take different paramater. AddListView does not have parameter while ChangeColor and EditListView takes Color and NSManagedObject respectively. However for the sake of simplicity, EditListView's paramter is integer in this example.
I am using .fullScreenCover(item: <#T##Binding<Identifiable?>#>, content: <#T##(Identifiable) -> View#>) for presenting them.
.fullScreenCover(item: $presentedViewType) { type in
if type == .AddListView {
AddListView()
}
else if type == .EditListView {
if let index = selectedIndex {
EditListView(index: index)
}
}
else if type == .ChangeColor {
if let color = selectedColor {
ColorView(color: color)
}
}
}
selectedIndex and selectedColor is nil even though I initialize them before initializing presentedViewType. And hence, an EmptyView is presented.
This is the project.
enum PresentedViewType: Identifiable {
case AddListView
case ChangeColor
case EditListView
var id: Int {
return hashValue
}
}
struct ContentView: View {
#State var presentedViewType: PresentedViewType?
#State var selectedColor: Color?
#State var selectedIndex: Int?
var body: some View {
NavigationView {
List {
Section {
NavigationLink(destination: Text("All")) {
Text("All")
}
.background(Color.blue)
.contextMenu {
Button(action: {
selectedColor = .blue
presentedViewType = .ChangeColor
}) {
Label("Change Color", systemImage: "paintbrush.pointed.fill")
}
}
}
ForEach(0..<10) { index in
NavigationLink(destination: Text("Row Details \(index)")) {
Text("Row \(index)")
}
.contextMenu {
Button(action: {
selectedIndex = index
presentedViewType = .EditListView
}) {
Label("Edit", systemImage: "square.and.pencil")
}
}
}
}
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button(action: {
presentedViewType = .AddListView
}) {
Label("Add", systemImage: "plus")
}
}
}
.fullScreenCover(item: $presentedViewType) { type in
if type == .AddListView {
AddListView()
}
else if type == .EditListView {
if let index = selectedIndex {
EditListView(index: index)
}
}
else if type == .ChangeColor {
if let color = selectedColor {
ColorView(color: color)
}
}
}
}
}
}
struct ColorView: View {
#Environment(\.presentationMode) var presentationMode
#State var color: Color
var body: some View {
NavigationView {
Text("Color View")
.background(color)
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Button(action: {
presentationMode.wrappedValue.dismiss()
}) {
HStack {
Image(systemName: "xmark")
}
}
}
}
}
}
}
struct AddListView: View {
#Environment(\.presentationMode) var presentationMode
#State var text: String = ""
var body: some View {
NavigationView {
TextField("", text: $text)
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Button(action: {
presentationMode.wrappedValue.dismiss()
}) {
HStack {
Image(systemName: "xmark")
}
}
}
}
}
}
}
struct EditListView: View {
#Environment(\.presentationMode) var presentationMode
#State var index: Int
var body: some View {
NavigationView {
Text("Row \(index)")
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
Button(action: {
presentationMode.wrappedValue.dismiss()
}) {
HStack {
Image(systemName: "xmark")
}
}
}
}
}
}
}
I have to mention that they do not have fixed value. They have different value depending on which row you need to edit.
How to pass selectedIndex and selectedColor to EditListView and ColorView respectively?
Update
EditListView takes only selectedIndex while ColorView takes only selectedColor
You need to have #Binding properties inside EditListView and ColorView
struct EditListView: View {
#Binding var selectedIndex: Int?
// rest of view implementation
}
struct ColorView: View {
#Binding var selectedIndex: Int?
// rest of view implementation
}
and then pass the binding in the initialisers
.fullScreenCover(item: $presentedViewType) { type in
if type == .AddListView {
AddListView()
} else if type == .EditListView {
EditListView(index: $selectedIndex)
} else if type == .ChangeColor {
ColorView(color: $selectedColor)
}
}

Resources