I wanna make some changes in ViewModel
by passing items into the .sheet
and decide to save it or leave without changes. But faced the problem when changing the item and dismissing .sheet
with @Environment(\.dismiss)
the app is crushing. I can't figure out why it gives this behavior. My goal is make changes into the item on a .sheet
and control save it or not by pressing button. Would be thankful for help!
struct Transport: Identifiable {
var id = UUID().uuidString
var name: String
}
class TransportViewModel: ObservableObject {
@Published var transports = [Transport(name: "Airplane"), Transport(name: "Car"), Transport(name: "Ship")]
@Published var editedTransport: Transport?
func saveTransport() {
if let unwrappedTransport = editedTransport {
if let editedTransportIndex = transports.firstIndex(where: { $0.id == unwrappedTransport.id }) {
transports[editedTransportIndex] = unwrappedTransport
}
}
}
}
struct TransportListView: View {
@StateObject var transportViewModel = TransportViewModel()
var body: some View {
List {
ForEach(transportViewModel.transports) { transport in
Text(transport.name)
.onTapGesture {
transportViewModel.editedTransport = transport
}
}
}
.sheet(item: $transportViewModel.editedTransport) {
transportViewModel.editedTransport = nil
} content: { _ in
TransportEditSheet()
}
.environmentObject(transportViewModel)
}
}
struct TransportEditSheet: View {
@EnvironmentObject var transportViewModel: TransportViewModel
@Environment(\.dismiss) var dismiss
var body: some View {
Binding($transportViewModel.editedTransport).map { transport in
List {
TextField("", text: transport.name)
Button(action: { dismiss() }) {
Text("Cancel").foregroundColor(.red)
}
Button(action: {
transportViewModel.saveTransport()
dismiss() }) {
Text("Save").foregroundColor(.green)
}
}
}
}
}
CodePudding user response:
Take a look at this, seems to be working as expected
struct Transport: Identifiable {
var id = UUID().uuidString
var name: String
}
class TransportViewModel: ObservableObject {
@Published var transports = [Transport(name: "Airplane"), Transport(name: "Car"), Transport(name: "Ship")]
@Published var editedTransport: Transport?
func saveTransport() {
DispatchQueue.main.async {
if let unwrappedTransport = self.editedTransport {
if let editedTransportIndex = self.transports.firstIndex(where: { $0.id == unwrappedTransport.id }) {
self.transports[editedTransportIndex] = unwrappedTransport
}
}
}
}
}
struct TransportListView: View {
@StateObject var transportViewModel = TransportViewModel()
@State var editSheet = false
var body: some View {
List {
ForEach(transportViewModel.transports) { transport in
Text(transport.name)
.onTapGesture {
transportViewModel.editedTransport = transport
editSheet = true
}
}
}
.sheet(isPresented: $editSheet) {
TransportEditSheet()
}
.environmentObject(transportViewModel)
}
}
struct TransportEditSheet: View {
@EnvironmentObject var transportViewModel: TransportViewModel
@Environment(\.dismiss) var dismiss
var body: some View {
Binding($transportViewModel.editedTransport).map { transport in
List {
TextField("", text: transport.name)
Button(action: { dismiss() }) {
Text("Cancel").foregroundColor(.red)
}
Button(action: {
transportViewModel.saveTransport()
dismiss() }) {
Text("Save").foregroundColor(.green)
}
}
}
}
}