Search code examples
swiftuiswiftui-navigationview

How to rebuild a NavigationView in SwiftUI


I'm rebuilding one of my apps in SwiftUI and wanted to add FaceID unlock. I found and used this article to add LocalAuthentication: https://medium.com/swlh/app-lock-with-face-id-touch-id-in-swiftui-2-0-feef21e8eba7

While the code does handle the authentication part in the way that I need it to (although I'm showing the "locked view" as a sheet) it does result in one nasty bug. When I dismiss the locked view (after successful authentication) my main view (which is a NavigationView) 'breaks' in the sense that the NavigationBar moves up into the statusbar. This behavior is also present in the code provided by the author of the article: https://github.com/JeevaTamil/AppLock

When I rotate my device the navigation 'restores' itself. So I was wondering if there is a way to force the NavigationView to rebuild itself, hopefully restoring the NavigationBar to the correct position. I'm using Xcode 13.4.1 with an iOS 15.5 target, but the issue is also present in the iOS16 beta. Both on device and in the simulator.


Solution

  • We can force rebuild any view by adding .id modifier dependent on some state. Any change of id to new value result in view rebuild.

    Here is an example

    @State private var force = false
    
    // ...
    
    NavigationView {
       Button("Rebuild") {
          force.toggle()    // << in any action/closure
       }
    }
    .id(force)   // << here !!
    

    Of course it is not a silver-bullet and expensive operation, and in some cases might be not needed, but solution depends on real issue code.