首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使自定义SwiftUI视图与ObservedObjects兼容NavigationLink iOS 16

使自定义SwiftUI视图与ObservedObjects兼容NavigationLink iOS 16
EN

Stack Overflow用户
提问于 2022-09-13 02:17:39
回答 1查看 228关注 0票数 0

我不认为下面的例子是详尽无遗的(来自与Swift的黑客攻击)。许多在线示例都倾向于将其保持在这样的基础上,其中NavigationLinks是基于简单的哈塞克模型实现的。

代码语言:javascript
运行
复制
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中很容易完成的事情。

代码语言:javascript
运行
复制
NavigationLink(destination: someView(viewModel: self.viewModel) { Text("Test Link") } 

现在一切都是有规划的。我可以将一些属性封装在指向我的SwiftUI视图的枚举中吗?如果是这样的话,我还能保留对我想要传递给视图的正确运行时对象的引用吗?在实现这个导航层次结构时,除了基本示例之外,还有点迷失了。

请参阅下面我提出的最简单的例子来说明我所面临的具体问题:

代码语言:javascript
运行
复制
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)
        }
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-09-14 01:27:50

iOS 16 & Xcode 14

以下是满足基本编程导航堆栈管理设计模式和自定义视图的最小答案。

代码语言:javascript
运行
复制
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设置。

我希望这能有所帮助,我当然是在学习。我肯定这并不完美,但这是个开始。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73696898

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档