SwiftUI Navigation

30 Views Asked by At

i'm facing some issues with my clone app. now i'm trying to create a clone messenger app. the problem is when user successful log in to the app, the main screen didn't show up as i expected how it look like when i run simulator on that view. Is there anyone can help me out with this ?

i was create a log in view and a messages view which is showing all user chat. this messages view is also include a side menu view too and i have succeeded to make the animation for it. i also import the search bar on messages view too. but the problem is when user log in successfully, the search bar didn't show up and the side menu has overlay to the navigation bar like the first imagewhat i'm facing which is far from what i expected like the second image what i expected. i have used NavigationLink in order to navigate from login view to messages views. when i ran the simulator on the messages view, the view've shown up as i expected ( the navigation bar didn't overlay the side menu view and the search bar showed up when the messages view loaded. but when i run the app or try to run the simulator from the login view, when i click the button log in which is a navigation link, i've moved to the messages view but it didn't show the search bar from the beginning and the navigation bar was overlay the side menu view. how can i fix that ?

struct LoginView: View {
    
    var body: some View {
        NavigationStack {
            ...
                //MARK: Log in button
                NavigationLink {
                    MessagesView()
                        //.navigationBarBackButtonHidden()
                } label: {
                    Text("log in")
                        .textCase(.uppercase)
                        .font(.headline)
                        .foregroundStyle(Color(.white))
                        .frame(width: UIScreen.main.bounds.width - 32, height: 48)
                }
                .background(Color(.systemBlue))
                .clipShape(.buttonBorder)
            }
            ...
        }
    }
}

and here is the code for messages view

struct MessagesView: View {
    
    @State var showSideMenu: Bool = false
    @State var searchText = ""
    @State var offset: CGFloat = 0
    @State var lastStoredOffset: CGFloat = 0
    @GestureState var gestureOffset: CGFloat = 0
    let names = ["Holly", "Josh", "Rhonda", "Ted","1", "2", "3", "4","5", "6", "7", "8"]
    
    var body: some View {
        
        let sideWidth = getRect().width - 90
        
        //MARK: Bar title and searchbar
        HStack(spacing: 0) {
            SideMenuView(showSideMenu: $showSideMenu)
            NavigationStack {
                VStack {
                    ScrollView {
                        ForEach(searchResults, id: \.self) { name in
                            NavigationLink {
                                ChatView()
                                    .navigationBarBackButtonHidden()
                            } label: {
                                ChatLogView()
                                    .padding(.horizontal)
                            }
                        }
                    }
                }
                .navigationTitle("PMe!")
                .navigationBarTitleDisplayMode(.inline)
                .toolbar {
                    ToolbarItemGroup(placement: .topBarLeading) {
                        Button {
                            withAnimation{showSideMenu.toggle()}
                        } label: {
                            Image(systemName: "line.3.horizontal")
                                .font(.title2)
                                .fontWeight(.bold)
                        }
                    }
                    ToolbarItemGroup(placement: .topBarTrailing) {
                        NavigationLink {
                            NewChatView()
                                .navigationBarBackButtonHidden()
                        } label: {
                            Image(systemName: "square.and.pencil")
                                .font(.title2)
                                .fontWeight(.bold)
                        }
                    }
                }
                .overlay(
                    Rectangle()
                        .fill(
                            Color.primary.opacity(Double(offset / sideWidth) / 5)
                        )
                        .ignoresSafeArea(.container, edges: .vertical)
                        .onTapGesture {
                            withAnimation {
                                showSideMenu.toggle()
                            }
                        }
                )
                .searchable(text: $searchText, placement : .navigationBarDrawer(displayMode: .automatic))
            }
            .frame(width: getRect().width)
        }
        .frame(width: getRect().width + sideWidth)
        .offset(x: -sideWidth / 2)
        .offset(x: offset > 0 ? offset : 0)
        .gesture(
            DragGesture()
                .updating($gestureOffset, body: { value, out, _ in
                    out = value.translation.width
                })
                .onEnded(onEnd(value: ))
        )
        .navigationBarBackButtonHidden()
        .navigationBarTitleDisplayMode(.inline)
        .animation(.easeInOut, value: offset == 0)
        .onChange(of: showSideMenu) {
            if showSideMenu && offset == 0 {
                offset = sideWidth
                lastStoredOffset = offset
            }
            
            if !showSideMenu && offset == sideWidth {
                offset = 0
                lastStoredOffset = 0
            }
        }
        .onChange(of: gestureOffset) {
            onChange()
        }
        
        var searchResults: [String] {
            if searchText.isEmpty {
                return names
            } else {
                return names.filter { $0.contains(searchText) }
            }
        }
    }
    
    
    func onEnd(value: DragGesture.Value) {
        let sideWidth = getRect().width - 90
        let translation = value.translation.width
        
        withAnimation {
            if translation > 0 {
                if translation > (sideWidth / 2) {
                    offset = sideWidth
                    showSideMenu = true
                }
                else {
                    if offset == sideWidth {
                        return
                    }
                    offset = 0
                    showSideMenu = false
                }
            } else {
                if -translation > (sideWidth / 2) {
                    offset = 0
                    showSideMenu = false
                } else {
                    if offset == 0 || !showSideMenu {
                        return
                    }
                    
                    offset = sideWidth
                    showSideMenu = true
                }
            }
        }
        
        lastStoredOffset = offset
    }
    
    func onChange() {
        let sideWidth = getRect().width - 90
        
        offset = (gestureOffset != 0) ? (gestureOffset + lastStoredOffset < sideWidth ? gestureOffset + lastStoredOffset : offset) : offset
    }
}
0

There are 0 best solutions below