如何在 swiftui 中弹出到 TabView 应用程序中的特定视图。我也使用了 StackNavigation 但不在 swiftui 中工作
Posted
技术标签:
【中文标题】如何在 swiftui 中弹出到 TabView 应用程序中的特定视图。我也使用了 StackNavigation 但不在 swiftui 中工作【英文标题】:How to pop to specific view in the TabView Application in swiftui. I used StackNavigation also but not working in swiftui 【发布时间】:2021-12-04 06:43:33 【问题描述】:我在弹出特定视图时遇到问题。让我解释一下层次结构。
ContentView -> 2 个选项卡,TabAView 和 TabBView TabBView 内部。有 1 个视图使用 ConnectView:连接按钮在哪里。点击连接按钮后,用户移动到另一个视图,称为 UserAppView。从这里用户可以检查他的个人资料并更新。 Update API 调用后,需要从 UserFirstFormView 弹出到 UserAppView。
这是更好地理解我的问题的代码。
ContentView.swift
struct ContentView: View
enum AppPage: Int
case TabA=0, TabB=1
@StateObject var settings = Settings()
@ObservedObject var userViewModel: UserViewModel
var body: some View
NavigationView
TabView(selection: $settings.tabItem)
TabAView(userViewModel: userViewModel)
.tabItem
Text("TabA")
.tag(AppPage.TabA)
TabBView(userViewModel: userViewModel)
.tabItem
Text("Apps")
.tag(AppPage.TabB)
.accentColor(.white)
.edgesIgnoringSafeArea(.top)
.onAppear(perform:
settings.tabItem = .TabA
)
.navigationBarTitleDisplayMode(.inline)
.environmentObject(settings)
这是 TabAView:
struct TabAView: View
@ObservedObject var userViewModel: UserViewModel
@EnvironmentObject var settings: Settings
init(userViewModel: UserViewModel)
self.userViewModel = userViewModel
var body: some View
Vstack
/// code
.onAppear(perform:
/// code
)
.environmentObject(settings)
这是另一个 TabBView:
struct TabBView: View
@ObservedObject var userViewModel: UserViewModel
init(userViewModel: UserViewModel)
self.userViewModel = userViewModel
var body: some View
VStack (spacing: 10)
NavigationLink(destination: ConnectView(viewModel: ConnectViewModel(id: id!), userViewModel: userViewModel))
UserCardWidget()
在 TabBView 上使用了 1 个 connectView,用户将通过该 connectView 进行连接。此处使用 ConnectViewModel 调用连接 API。
class ConnectViewModel: ObservableObject
var id: String?
init(id: String)
self.id = id
func connect(completion: @escaping () -> Void)
APIService.shared.connectApp(id: self.id!) connected in
DispatchQueue.main.async
self.isConnected = connected ?? false
completion()
这是连接视图
struct ConnectView: View
@ObservedObject var connectViewModel: ConnectViewModel
@ObservedObject var userViewModel: UserViewModel
@State var buttonTitle = "CONNECT WITH THIS"
@State var isShowingDetailView = false
var body: some View
VStack
Spacer()
if let id = connectViewModel.id
NavigationLink(destination: UserAppView(id: id, userViewModel: userViewModel), isActive: $isShowingDetailView)
Button(buttonTitle, action:
connectViewModel.connect
buttonTitle = "CONNECTED"
isShowingDetailView = true
)
这是调用 API 以获取一些与用户相关的详细信息的 UserAppViewModel:
类 UserAppViewModel: ObservableObject
var id = ""
func getdetails()
APIService.shared.getDetails() userDetails in
DispatchQueue.main.async
/// code
这是 UserAppView 类
struct UserAppView: View
@ObservedObject var userViewModel: UserViewModel
@State private var signUpInButtonClicked: Bool = false
@StateObject private var userAppViewModel = UserAppViewModel()
init(id: String, userViewModel: UserViewModel)
self.id = id
self.userViewModel = userViewModel
var body: some View
VStack
Text(userAppViewModel.status)
VStack
Spacer()
NavigationLink(
destination: ProfileView(userAppViewModel: userAppViewModel, isActive: $signUpInButtonClicked)) EmptyView()
if /// Condition
Button(action:
signUpInButtonClicked = true
, label:
ZStack
/// code
.frame(maxWidth: 77, maxHeight: 25)
)
.onAppear(perform:
**userAppViewModel.getDetails**(id: id)
)
从这里,用户可以导航到 ProfileView。
struct ProfileUpdateView: View
@State private var navigationSelectionFirstFormView = false
@State private var navigationSelectionLastFormView = false
public var body: some View
VStack
NavigationLink(destination: UserFirstFormView(userAppViewModel: userAppViewModel), isActive: $navigationSelectionFirstFormView)
EmptyView()
NavigationLink(destination: UserLastFormView(userAppViewModel: userAppViewModel), isActive: $navigationSelectionLastFormView)
EmptyView()
.navigationBarItems(trailing: Button(action:
if Condition
navigationSelectionFirstFormView = true
else
navigationSelectionLastFormView = true
, label:
HStack
Text("Action")
.foregroundColor(Color.blue)
)
)
此外,他们的用户将移至下一个屏幕以更新个人资料。
struct UserFirstFormView: View
var body: some View
VStack
/// code
///
Button("buttonTitle", action:
API Call completion: status in
if status
self.rootPresentationMode.wrappedValue.dismiss()
)
)
.frame(maxHeight: 45)
一旦收到 API 响应,我会尝试从该视图中弹出,但没有任何效果。
出于机密的考虑,我已删除了大部分代码,但此代码将解释原因和错误。请查看代码并帮助我。
【问题讨论】:
【参考方案1】:您可以将导航链接与标签:和选择:重载一起使用,并让视图模型控制打开的链接,这里是一个示例
enum profileViews
case view1
case view2
在您的 viewModel 中添加一个已发布的变量来保存活动视图
@Published var activeView: profileViews?
然后在您的导航链接中,您可以这样做
NavigationLink(
destination: secondView(profileViewModel: ProfileViewModel ),
tag: profileViews.view1,
selection: self.$profileViewModel.activeView
)
然后你可以弹出任何视图,只需更新视图模型中的变量
self.profileViewModel.activeView = nil
【讨论】:
如果这个视图模型会被大量使用,也许单例或环境对象可以更好地帮助你,而不是传递视图模型的引用。 是的,从UserAppView来看,这个模型用在7个视图中。 我没有观察这个 UserAppViewModel,我在 UserAppView 中创建了 StateObject。我已经编辑了这个问题。即使在 activeView 为零后视图也不会弹出。 :( 我没有观察这个 UserAppViewModel,我在 UserAppView 中创建了 StateObject,然后在后续视图中观察以上是关于如何在 swiftui 中弹出到 TabView 应用程序中的特定视图。我也使用了 StackNavigation 但不在 swiftui 中工作的主要内容,如果未能解决你的问题,请参考以下文章