3

I have the following code:

enum ContentViewRouter {
    case details
}


struct ContentView: View {
    
    var body: some View {
        
        NavigationStack {
            ZStack {
                NavigationLink(value: ContentViewRouter.details) {
                    Text("Push")
                }
            }
            .navigationDestination(for: ContentViewRouter.self) { destiantion in
                switch destiantion {
                case .details:
                    DetailsView()
                }
            }
            .navigationTitle("TEST")
        }
    }
    
}

struct DetailsView: View {
    
    @State var query = ""
    
    var body: some View {
        
        Form {
            Section("TEST") {
                Text("DETAILS")
            }
        }
        .searchable(text: $query)
        .navigationTitle("DETAILS")
        
    }
    
}

When pushing the details view it creates this animation:

enter image description here

I want to get rid of this weird looking animation "glitch":

enter image description here

How can I get the push animation to come in smooth where the search bar doesn't appear for a split second and then go away? Seems like it's a bug or I am doing it wrong?

2
  • Did you have any luck recently with this glitch animation?
    – habibiboss
    Feb 16, 2023 at 20:41
  • no, no luck for now. I wish I had a solution for this.
    – zumzum
    Feb 16, 2023 at 22:22

2 Answers 2

0

The problem of that I think because you have .searchable which will create search bar and currently conflict with your .navigationTitle which both on the top. Maybe the search bar don't know where to put it because of the .navigationTitle

Update: After doing some research, I see that maybe the behavior maybe wrong in search bar .automatic

There are three ways to workaround

  1. If you want to keep your search bar then make NavigationView to split define navigationTitle and search bar
struct DetailsView: View {
    @State var query = ""
    
    var body: some View {
        NavigationView {
            Form {
                Section("TEST") {
                    Text("DETAILS")
                }
            }
            .searchable(text: $query)
        }
        .navigationTitle("DETAILS")
        
    }
}
  1. Keep the search bar always appear
struct DetailsView: View {
    @State var query = ""
    var body: some View {
        
        Form {
            Section("TEST") {
                Text("DETAILS")
            }
        }
        .searchable(text: $query, placement: .navigationBarDrawer(displayMode: .always))
        .navigationTitle("DETAILS")
    }
}
  1. If you want to completely remove search bar
struct DetailsView: View {
    
    @State var query = ""
    
    var body: some View {
        
        Form {
            Section("TEST") {
                Text("DETAILS")
            }
        }
        //.searchable(text: $query) // remove this
        .navigationTitle("DETAILS")
        
    }   
}
3
  • I do need to keep searchable. Option 1 approach puts an additional navigation bar in the view. I don't want that.
    – zumzum
    Nov 23, 2022 at 13:56
  • Dear @zumzum, I just figure one more solution make searchBar always appear. If there is any other methods I willupdate
    – Thang Phi
    Nov 23, 2022 at 14:13
  • yes, .always does remove the animation. Problem is, I lose the ability to put the searcher on the top right when on iPad... It seems to be like this is a SwiftUI bug. But I am not sure.
    – zumzum
    Nov 23, 2022 at 14:42
0

I found an easier solution by toggling the navigation bar visibility:

struct DetailsView: View {

    @State var query : String = ""
    @State private var toolbarVisibility : Visibility = .hidden

    var body: some View {

        Form {
            Section("TEST") {
                Text("DETAILS")
            }
        }
        .onAppear {toolbarVisibility = .automatic}
        .toolbar(toolbarVisibility, for: .navigationBar)
        .searchable(text: $query)
        .navigationTitle("DETAILS")

    }

}

This worked for me:

struct DetailsView: View {
    
    @State var query = ""
    @State private var formHasAppeared = false
    
    var body: some View {
        
        Form {
            Section("TEST") {
                Text("DETAILS")
            }
        }
        .onAppear { formHasAppeared = true }
        .if(formHasAppeared) { view in
            view.searchable(text: $query)
        }
        .navigationTitle("DETAILS")
        
    }
    
}

extension View {
    /// Applies the given transform if the given condition evaluates to `true`.
    /// - Parameters:
    ///   - condition: The condition to evaluate.
    ///   - transform: The transform to apply to the source `View`.
    /// - Returns: Either the original `View` or the modified `View` if the condition is `true`.
    @ViewBuilder func `if`<Content: View>(_ condition: Bool, transform: (Self) -> Content) -> some View {
        if condition {
            transform(self)
        } else {
            self
        }
    }
}

The extension came from here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.