I'm new to SwiftUI and trying have hit a stumbling block on this one.
Essentially I want to rename a collection which is an element of an array, which is an environment object.
Firstly my data model struct: Collection
struct Collection: Identifiable {
var id: UUID
var name: String = ""
let createdDate: Int?
}
My viewmodel class: ViewModel
class ViewModel: ObservableObject {
@Published var displayedCollectionsArray: [Collection] = [
Collection(id: UUID(), name: "Travel gems", createdDate: 12345),
Collection(id: UUID(), name: "Collection 2", createdDate: 12345),
Collection(id: UUID(), name: "Collection 3", createdDate: 12345)
]
}
Then my parent view: ContentView
struct ContentView: View {
@EnvironmentObject var allPlaces: ViewModel
var body: some View {
NavigationView {
List {
ForEach(allPlaces.displayedCollectionsArray) { collection in
VStack {
NavigationLink(
destination: Text("Detail View here"),
label: {
CollectionCardView(collection: collection, isHidden: false, collecName: collection.name)
}
) // End Argument list for Navigation Link
} // End vstack
} // end for each
.navigationBarHidden(true)
} // end scrollview
} // end NavigationView
}
}
Then my label view: CollectionCardView
struct CollectionCardView: View {
@EnvironmentObject var allPlaces: ViewModel
var collection: Collection
@State var isHidden: Bool = false
var testkey = "hello"
@State var collecName: String
var body: some View {
VStack (alignment: .leading) {
HStack {
ZStack (alignment: .leading) {
Text(collection.name)
.foregroundColor(Color.black)
.opacity(isHidden ? 0 : 1)
.frame(width: 200, height: 40, alignment: .leading)
if collection.name != "Travel gems" {
TextField(testkey, text: $collecName)
.foregroundColor(Color.black)
.textFieldStyle(RoundedBorderTextFieldStyle())
.frame(width: 200, height: 40, alignment: .leading)
.opacity(isHidden ? 1 : 0)
}
}
if collection.name != "Travel gems" {
Image(systemName: "square.and.pencil")
.foregroundColor(Color.gray)
.onTapGesture {
isHidden.toggle()
}
}
}
.padding(.leading, 24)
.padding(.trailing, 24)
} // End VStack
.padding(.top, 10)
.padding(.bottom, 10)
}
}
The problem that I have is that because the textfield is inside my label view, which has a destination view attached to it via a navigation link in the parent view, rather than going into edit it when I tap on it, it just navigates me to the destination view.
Perhaps expectedly, when I click back from the destination view, the cursor is in the textfield and I am able to edit its contents.
You can see that I am using a ScrollView
, and when I test a List
instead, it does work, but I prefer a scroll view because of the way it is formatting my content with dividers and padding. (in the production version of my code, there is a lot more going on with LazyGrids
and Image
s etc that don't play nice with List
).
BONUS POINTS! How can I programmatically highlight the text in the textfield when it toggles?