我不认为下面的例子是详尽无遗的(来自与Swift的黑客攻击)。许多在线示例都倾向于将其保持在这样的基础上,其中NavigationLinks是基于简单的哈塞克模型实现的。
struct ContentView: View {
var body: some View {
NavigationStack {
List(1..<50) { i in
NavigationLink(value: i) {
Label("Row \(i)", systemImage: "\(i).circle")
}
}
.navigationDestination(for: Int.self) { i in
Text("Detail \(i)")
}
.navigationTitle("Navigation")
}
}
}
我有一些观点,这些观点都是支持ObservedObjects的。例如,ViewA(firstViewModel: self.firstViewModel)
和ViewB(secondViewModel: self.secondViewModel
。我的ObservedObjects在根视图中实例化,其中定义了NavigationStack
。如何使用NavigationStack
16中的新NavigationLink
和iOS范式来支持导航到自定义SwiftUI视图?这是在iOS 15中很容易完成的事情。
NavigationLink(destination: someView(viewModel: self.viewModel) { Text("Test Link") }
现在一切都是有规划的。我可以将一些属性封装在指向我的SwiftUI视图的枚举中吗?如果是这样的话,我还能保留对我想要传递给视图的正确运行时对象的引用吗?在实现这个导航层次结构时,除了基本示例之外,还有点迷失了。
请参阅下面我提出的最简单的例子来说明我所面临的具体问题:
struct ContentView: View {
var body: some View {
NavigationStack {
ProfileView()
// there is other logic for other root views, but
// this problem can just focus on ProfileView in NavigationStack
}
}
}
struct ProfileView: View {
@StateObject var progressViewModel = ProgressViewModel()
@StateObject var challengesViewModel = ChallengesViewModel()
@StateObject var subscriptionViewModel = SubscriptionViewModel()
var body: some View {
VStack {
// Below is the code that is broken, and I'm not sure how to adapt it
// to the new iOS 16 navigation patterns since I am not reusing the same view
// as in the above example
NavigationLink(destination: ProgressView(progressViewModel: self.progressViewModel)) {
Text("User progress nav link")
}
NavigationLink(destination: ChallengesView(challengesViewModel: self.challengesViewModel)) {
Text("Challenges nav link")
}
NavigationLink(destination: SubscriptionView(subscriptionViewModel: self.subscriptionViewModel)) {
Text("Subscription nav link")
}
}
}
}
struct ProgressView: View {
@ObservedObject var progressViewModel: ProgressViewModel
var body: some View {
VStack {
Text(progressViewModel.overallUserProgressString)
}
}
}
struct ChallengesView: View {
@ObservedObject var challengesViewModel: ChallengesViewModel
var body: some View {
VStack {
Text(challengesViewModel.numberOfChallengesPerformedString)
}
}
}
struct SubscriptionView: View {
@ObservedObject var subscriptionViewModel: SubscriptionViewModel
var body: some View {
VStack {
Text(subscriptionViewModel.localSubscriptionPriceString)
}
}
}
发布于 2022-09-14 01:27:50
iOS 16 & Xcode 14
以下是满足基本编程导航堆栈管理设计模式和自定义视图的最小答案。
enum CustomNavTypes: String, Hashable {
case viewA = "View A"
case viewB = "View B"
case viewC = "View C"
}
struct CustomView: View {
@State var navigationViewStack: [CustomNavTypes] = []
var body: some View {
NavigationStack {
VStack {
Button(action: {
navigationViewStack.append(.viewA)
}) {
Text("View A")
}
Button(action: {
navigationViewStack.append(.viewB)
}) {
Text("View B")
}
Button(action: {
navigationViewStack.append(.viewC)
}) {
Text("View C")
}
}
.navigationDestination(for: ProfileNavTypes.self) { value in
switch value {
case .viewA: ViewA() // can still pass in view models objects if needed
case .viewB: ViewB()
case .viewC: ViewC()
}
}
}
}
}
我很感谢@malhal展示了纯MV方法的优点,但实际上,我并不指望所有的开发人员或应用程序都会利用纯MV的代码基(其中SwiftUI视图专门被视为预期的ViewModel,它就是.)。虽然MV提高了运行时性能并消除了许多样板代码,但我仍然设想许多人(包括我自己)为了方便而使用视图模型对象或管理通用范例,即使我们要迁移到更严格的MV设置。
我希望这能有所帮助,我当然是在学习。我肯定这并不完美,但这是个开始。
https://stackoverflow.com/questions/73696898
复制相似问题