30

我在视图中有一个列表(我们称之为视图 A),我通过 NavigationLink 从视图 A 推送视图 B,并将 CurrentSubjectValue 操作到初始视图 A。添加数据的那一刻,didChangd.send(value) 是派往查看 AI 收到警告,提示更新不属于视图的单元格。根据我之前的 UINavigationController 行为,视图 A 似乎已从不直观的窗口中删除。任何想法?

视图 A(主视图)

struct MainView: View {

    @ObjectBinding var currentProfileIdStore = CurrentProfileIdStore.shared

    var body: some View {

        NavigationView {
            if (currentProfileIdStore.didChange.value == nil) {
                NavigationLink(destination: ProfilesView()){ Text("show profiles view")}
            } else {
                List {
                    Section {
                        ForEach(0..<1) { _ in
                            PresentationLink(destination: ProfilesView()) {
                                Text("Profiles")
                            }
                        }
                    }

                    Section {
                        ForEach(0..<1) { _ in
                            Text("Items")
                        }
                    }
                }.listStyle(.grouped)
            }
        }.navigationBarTitle(currentProfileIdStore.didChange.value ?? "unknown")

    }
}

然后显示配置文件视图

struct ProfilesView : View {

    @ObjectBinding var profileManager = CurrentProfileIdStore.shared
    @ObjectBinding var profileProvider = ProfileProvider.shared

    var body: some View {

        NavigationView {

            List {
                Section {
                    ForEach(0..<1) { _ in
                        NavigationLink(destination: NewProfile()) {
                            Text("Add Profile")
                        }
                    }
                }


                Section {
                    ForEach(self.profileProvider.didChange.value) { profile in
                        VStack {

                            if profile.id == self.profileManager.didChange.value {
                                Image(systemName: "g.circle").transition(.move(edge: .top))
                            }

                            ProfileCellView(profile: profile)
                            Text(self.profileManager.didChange.value ?? "unknown").font(.footnote).color(.secondary)
                        }
                    }
                }

            }
            .navigationBarTitle("Profiles")
                .listStyle(.grouped)
        }
    }
}

然后我们可以添加一个新的配置文件

struct NewProfile: View {

    @State var name: String = ""
    @State var successfullyAdded: Bool = false

    @ObjectBinding var keyboardStatus = KeyboardStatus()
    var profileProvider = ProfileProvider.shared

    var body: some View {

        NavigationView {
                VStack {
                    if self.successfullyAdded  {
                        Text("Successfully added please go back manually :)").lineLimit(nil)
                    }
                    Form {
                        Section(header: Text("Enter name")) {
                            TextField("Enter your name", text: $name)
                        }
                    }
                    if name.count > 3 {
                        Button(action: {
                            self.profileProvider.addProfile(new: Profile(name: self.name, id: UUID().uuidString)) {
                                assert(Thread.isMainThread)
                                self.successfullyAdded = true
                            }
                        }) {
                            Text("Add")
                        }.transition(.move(edge: .bottom))
                    }
                }.padding(.bottom, self.keyboardStatus.didChange.value)
        }.navigationBarTitle("Add Profile")

    }
}

然后有提供者

class ProfileProvider: BindableObject {

    enum Query {
        case all

        var filter: (Profile) -> Bool {
            switch self {
            case .all:
                return { p in true }
            }
        }
    }

    static var samples: [Profile] = []

    static var shared: ProfileProvider = {

        return ProfileProvider(query: .all)
    }()

    var didChange = CurrentValueSubject<[Profile], Never>([])

    private var query: Query?

    private init(query: Query? = nil) {

        self.query = query
        assert(Thread.isMainThread)

        dispatchDidChange()
    }

    func dispatchDidChange() {
        assert(Thread.isMainThread)
        if let valid = self.query {
            didChange.send(ProfileProvider.samples.filter {  valid.filter($0) })
        } else {
            didChange.send([])
        }
    }

    func addProfile(new: Profile, comp: () -> Void) {

        ProfileProvider.samples.append(new)
        comp()
        dispatchDidChange()
    }

请记住,多个视图共享相同的提供者主题。所以在添加新配置文件时会出现问题。

self.profileProvider.addProfile(new

还有两个问题,一个是返回 mainView 时按钮不再起作用。此外,当模态呈现时,我还不知道如何手动返回。

4

0 回答 0