Search code examples
swiftxcodeswiftuinavigationview

SwiftUI - Switching views with NavigationView


I am trying to add comments to my app. To do this, I obviously need to switch the view of my app. Currently, I have two files: PostView and PostRow. PostView is the actual view file, and PostRow is the file that shows the posts.

I am trying to create a button inside of PostRow that will switch the view from PostView to CommentView. However, if I just add NavigationView to PostRow, my posts don't load. If I add NavigationView to my PostView document, I get a ton of visual glitches.

I have no clue how to properly switch views with this document structure.

PostView.swift

import SwiftUI

struct PostView: View {
    var edges = UIApplication.shared.windows.first?.safeAreaInsets
    @StateObject var postData = PostViewModel()
    var body: some View {
        
        VStack{
            HStack{
                
                Text("Posts")
                    .font(.largeTitle)
                    .fontWeight(.heavy)
                .foregroundColor(.white)
            
                Spacer(minLength: 0)
            .padding(.top,edges!.top)
            //shadow
            .background(Color("bg"))
            .shadow(color: Color.white.opacity(0.06), radius: 5, x: 0, y: 5)
            
            if postData.posts.isEmpty{
                
                Spacer(minLength: 0)
                
                if postData.noPosts{
                    
                    Text("No Posts")
                }
                else{
                    ProgressView()
                }
                Spacer(minLength: 0)
            }
            else{
                ScrollView{
                    VStack(spacing: 15){
                        
                        ForEach(postData.posts){post in
                            
                            PostRow(post: post, postData: postData)
                        }
                    }
                    .padding()
                    .padding(.bottom,55)
                }
            }
        }
        .fullScreenCover(isPresented: $postData.newPost) {
            
            NewPost(updateId: $postData.updateId)
            }
        }
        
    }

PostRow.swift - part of document with button

HStack {
                Text(post.title)
                    .fontWeight(.bold)
                    .foregroundColor(.white)
                    .fixedSize(horizontal: false, vertical: true)
                
                Spacer(minLength: 0)
            }
            .padding(.top,5)
            .padding(.bottom,5)
            
            HStack {
                Spacer(minLength: 0)
                Text(post.time,style: .time)
                    .font(.caption2)
                    .fontWeight(.light)
                    .foregroundColor(.white)
            }
Button("Comments") {
                  //This is where I need to switch to the CommentsView  
                }

I believe this is a relatively easy question, I just can't seem to figure it out.

Thanks!


Solution

  • There are many ways of doing this. Here is one.

    import SwiftUI
    enum MainViewTypes: String{
        case comments
        case posts
    }
    struct ParentView: View {
        @SceneStorage("mainViewType") var mainViewType: String = MainViewTypes.posts.rawValue
        var body: some View {
            switch mainViewType{
            case MainViewTypes.comments.rawValue:
                //Comments View
                VStack{
                    Text("comments")
                    Button("go to posts", action: {
                        mainViewType = MainViewTypes.posts.rawValue
                    })
                }
            case MainViewTypes.posts.rawValue:
                //Posts view
                VStack{
                    Text("posts")
                    PostRowView()
                }
            default:
                Button("unknown", action: {
                    mainViewType = MainViewTypes.posts.rawValue
                })
            }
        }
    }
    struct PostRowView: View {
        @SceneStorage("mainViewType") var mainViewType: String = MainViewTypes.posts.rawValue
        var body: some View {
            Button("go to comments", action: {
                mainViewType = MainViewTypes.comments.rawValue
            })
        }
    }
    struct ParentView_Previews: PreviewProvider {
        static var previews: some View {
            ParentView()
        }
    }