почему модальное представление SwiftUI обновляет здесь родительскую переменную (код прилагается) - PullRequest
0 голосов
/ 06 апреля 2020

В приведенном ниже коде, если я изменю значение TextField и затем нажму «Отмена» (т. Е. Потом не сохранит coredata), после того, как это модальное представление будет скрыто, значение будет изменено в списке родительского интерфейса пользователя?

Эта линия эффективно проходит мой реф? Если да, как изменить, чтобы быть эффективно по значению?

ОБНОВЛЕНИЕ: На самом деле кажется, что код в кнопке Сохранить получает вызов непосредственно после кода в кнопке отмены, то есть в случае, если я нажимаю кнопку Отмена. Не знаете, почему это происходит?

Код:

import SwiftUI

struct GCListsViewEdit: View {
    @Environment (\.presentationMode) var presentationMode
    @State var titleStr : String = ""
    var gcItem : GCList?

    var body: some View {
        NavigationView {
            Form {
                Section(header: Text("Enter Details")) {
                    TextField("List Title", text: self.$titleStr)
                        .onAppear {
                            self.titleStr = self.gcItem?.title ?? ""  // ** HERE **
                        }
                }
                HStack {
                    Button("Cancel") {
                        self.presentationMode.wrappedValue.dismiss()
                    }
                    Spacer()
                    Button("Save") {
                        guard !self.titleStr.isEmpty else {
                            return
                        }
                        guard let item = self.gcItem else {
                            return
                        }
                        item.title = self.titleStr
                        GCCoreData.save()
                        self.presentationMode.wrappedValue.dismiss()
                    }
                }
            }
            .navigationBarTitle("Edit List")
        }
    }
}

РОДИТЕЛЬ - только часть тела

var body : some View {
    NavigationView {
        VStack {

            // -- Main List  --
            List() {
                ForEach(gcLists) { gcList in
                    HStack {
                        if self.editMode {
                            Button(action: {}) {
                              Text("\(gcList.title)")
                            }
                            .onTapGesture {
                                self.selectedListViewItem = gcList
                                self.newListItemTitle = gcList.title
                                self.showEditView.toggle()
                            }
                            .sheet(isPresented: self.$showEditView, content: {
                                GCListsViewEdit(gcItem: self.selectedListViewItem!)
                            })
                        } else {
                            NavigationLink(destination: GCTasksView(withGcList: gcList)) {
                                Text("\(gcList.title)")
                            }
                        }
                    }
                }
                .onDelete(perform: self.deleteList)
                .onMove(perform: self.move)

            }
            .environment(\.editMode, editMode ? .constant(.active) : .constant(.inactive))
            .alert(isPresented: $showingAlert) {
                Alert(
                    title: Text(verbatim: "Important Message"),
                    message: Text(self.alertString),
                    dismissButton: Alert.Button.default(Text(verbatim: "Cancel"))
                )
            }
            .navigationBarTitle( Text("Todo Lists") )
            .navigationBarItems(
                trailing: Button(action: {
                    print("Edit" as Any)
                    self.editMode = !self.editMode
                } ) {
                    Text(editMode ? "Done" : "Edit")
                }
            )

            // -- Add List Item ---selectedListViewItem
            Button("Add List") {
                self.newListItemTitle = ""
                self.showAddView.toggle()
            }
            .sheet(isPresented: $showAddView, content: { GCListsViewAdd() } )

        }
    }
}

1 Ответ

1 голос
/ 07 апреля 2020

Form является своего рода List, а List имеет специфицированную c обработку стандартных кнопок в строке - она ​​делает активным весь ряд, поэтому при нажатии строки в любом месте активируется кнопка (или кнопки) .

В вашем примере, даже если вы нажмете между Отмена и Сохранить, оба действия будут выполнены.

Существует несколько возможных решений:

1 ) использовать жесты касания (удерживая кнопки или заменяя их другими видами, «Текст», «Изображение» и т. д. c.), например


HStack {
    Button("Cancel") {}
    .onTapGesture {
        print(">> do cancel")
    }
    Spacer()
    Button("Save") {}
    .onTapGesture {
        print(">> do save")
    }
}

2), использовать пользовательский стиль кнопок, поскольку List перехватывает только DefaultButtonStyle кнопки

struct CustomButton: ButtonStyle {
    func makeBody(configuration: Self.Configuration) -> some View {
        configuration.label
            .foregroundColor(configuration.isPressed ? Color.gray : Color.blue)
        }
}

HStack {
    Button("Cancel") {
        print(">> do cancel")
    }.buttonStyle(CustomButton())
    Spacer()
    Button("Save") {
        print(">> do save")
    }.buttonStyle(CustomButton())
}

3) перемещают кнопки из Form для этого экрана (например, в NavigationBar)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...