【发布时间】:2021-08-10 22:07:52
【问题描述】:
我正在使用 SwiftUI 和 Firestore 开发应用程序。
在主页上,我显示了 Firestore 中的项目列表,这些项目在后端有任何更新时都会正确更新。 现在在顶部加号按钮上,我正在导航到另一个屏幕以添加新项目。 添加新项目时,主页上的列表会更新,即再次将 AddNewItemView 推送到堆栈中。
在这种情况下,我想检测列表屏幕现在是否不可见并停止列出事件。
import SwiftUI
struct HomeView: View {
private let useCase: AuthLogoutProvider = AuthService.shared
@ObservedObject var viewModel: HomeViewModel
init(_ viewModel: HomeViewModel) {
self.viewModel = viewModel
}
private var addTeam: some View {
return HStack {
Text("Add Team +")
.font(.system(size: 20))
.fontWeight(.regular)
.foregroundColor(Color.secondary)
.padding(.vertical)
}
.frame(width: 150, height: 54)
.overlay(
RoundedRectangle(cornerRadius: 10)
.stroke(Color.secondary, lineWidth: 1)
)
}
var body: some View {
NavigationView {
VStack {
HStack {
NavigationLink(destination: AddTeamInputView(), label: {
addTeam
})
Spacer()
}
.padding()
List(viewModel.teamsInfoModels, id: \.id) { teamInfoModel in
VStack {
NavigationLink(destination: TeamDetailView(teamInfoModel), label: {
EmptyView()
})
TeamInfoCell(teamInfoModel)
}
}
Spacer()
}
.navigationTitle( Text("Countries"))
.navigationBarItems(
trailing: Button(action: {
useCase.signOut()
self.viewModel.logoutPerformed()
}) {
Text("Log out")
.font(.title2)
.fontWeight(.bold)
.foregroundColor(.secondary)
}
)
}
.onAppear {
print("HomeView onAppear")
}
.onDisappear {
print("HomeView onDisappear")
}
}
}
这是我的主页视图,其中包含团队列表和添加团队按钮
点击添加新按钮导航到另一个屏幕以在 Firestore 上添加团队
添加团队输入视图
struct AddTeamInputView: View {
@ObservedObject private var viewModel: AddTeamInputViewModel
init(_ viewModel: AddTeamInputViewModel = AddTeamInputViewModel()) {
self.viewModel = viewModel
print("AddTeamInputView init called")
}
var body: some View {
VStack {
HStack {
TextField("Enter Team name", text: $viewModel.teamName)
.font(.title2)
.foregroundColor(.secondary)
.frame(width: UIScreen.main.bounds.width - 40)
}
.padding(10)
.overlay(
RoundedRectangle(cornerRadius: 10)
.stroke(Color.secondary, lineWidth: 1)
)
if viewModel.move {
NavigationLink(destination: CountrySelectionView(viewModel: CountrySelectionViewModel(viewModel.createdTeam())), isActive: $viewModel.move) {
EmptyView()
}
}
AppButton(action: {
self.viewModel.addTeam()
}, title: "Save", width: 200)
.padding(.vertical, 40)
}
.navigationTitle("Name Your Team!")
}
}
添加团队视图模型
class AddTeamInputViewModel: ObservableObject {
init() {
print("AddTeamInputViewModel init")
}
@Published var teamName: String = ""
@Published var move: Bool = false
private var team: Team? = nil
func addTeam() {
TeamDataProvider.shared.createTeam(teamName) { (error, teamId) in
if let teamId = teamId {
if let team = TeamDataProvider.shared.team(forId: teamId) {
DispatchQueue.main.async {
self.team = team
print("Move to select country for team == \(self.team?.teamName ?? "") == \(self.move)")
self.move.toggle()
print("Move Value after toggle == \(self.move)")
}
} else {
print("Team issue")
}
} else {
print("Team issue")
}
}
}
func createdTeam() -> Team {
return team!
}
deinit {
print("AddTeamInputViewModel deinit called")
}
}
【问题讨论】:
-
您没有显示任何代码。假设,您有一些模型来确定将呈现 什么,表示 ListView 的数据为空或 nil。因此,您可能会在“真相之源”(模型)中找到答案。如果没有,请重新考虑您的设计。
-
如果您的 ListView 被模态视图覆盖,您的模型或 ViewModel 应该知道这一点。如果您的视图被导航堆栈上的另一个视图覆盖,您的模型 (ViewModel) 应该知道这一点。只有少数情况下模型不知道部分覆盖 ListView 的模态视图。在这种情况下,您不应该停止观察事件。
-
@CouchDeveloper 你能检查给定的代码并提出一些建议吗
-
我假设您会在 HomeView 中看到团队的更新,因为在 AddTeamInputView 中添加了一个新团队并将其提交给数据提供者。然后从您的 ViewModel 获取团队的 onChange 通知。恕我直言,这就是它应该如何工作的!但是,您可以将 AddTeamInputView 更改为模式视图(工作表),并在那里收集新的团队信息,然后在关闭时,让您的 HomeViewModel 处理“添加新团队”操作。因此,您可能只需要 一个 ViewModel,但需要一个更完整的底层 DataProvider (CRUD) API 和一个为团队提供属性的简单 InputView。
-
我理解你的意见,但我们对这个流程很严格,因为在添加团队之后还有另一个流程,比如邀请成员加入。这里的流程与您在 HomeView 上观察更改然后在 AddTeamView 上添加新团队的流程相同,该团队为 Homeview 创建另一个事件,然后 HomeView 意外推送 AddTeamView
标签: ios swift firebase swiftui publisher