Skip to content

SwiftUI example of programmatic navigable views for NavigationView hierarchies

License

Notifications You must be signed in to change notification settings

supervisor194/NavTest

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NavTest

SwiftUI example of programmatic navigable views for NavigationView hierarchies

This example takes 3 View structs, A,B and C that want to live in a stack navigation view hierarchy. Sometimes we may want to pop the initial view open to the 3rd View C, while maintaining the nice navigation that the stack navigation view provides, the back buttons and forward navigation. The following code has A,B and C conform to a few protocols and adds them to a containing model called the class NavModel: ObservableObject. Additonally, the A,B and C are 'wrapped' by 3 separate View structs to maintain some additional state about what has appeared or disappeared. While not strictly needed to get programmatic navigation working, these wrappers can be helpful in more complex situations where one does not want to instantiate the underlying A,B and C multiple times. One can remove the Wrapped(A|B|C) and push the onAppear/onDisappear elsewhere. The Wrappers have proven to be useful in other situations and so I've kept them here.

Two protocols NavView and NavViewModel along with the class NavModel: ObservableObject offer a simple structure for building SwiftUI View hierarchies that utilize the NavigationView along with a .navigationViewStyle(StackNavigationViewStyle()). The NavModel knows about the optional Views for the hierarchy. Generally, we want to lay the Views out in a well known fashion, A before B before C or some such. These may also be optional. Perhaps A, B and C represent some SwiftUI package with reusable views. There may be occassions for configuring them into various hiearchies, like A, C or B, C or just B or just C.

protocol NavView {
    var viewModel: NavViewModel { get }
}

protocol NavViewModel : AnyObject {
    var name: String { get }
    var uuid: UUID { get }
    var selected: [String:Int?] { get set }
    var isVisible: Bool { get set }
    var navModel: NavModel { get }
    func doOnAppear(currentView: NavView, dismiss: DismissAction, toSelect: KeyedId?)
    func doOnDisappear(toNil: KeyedId?)
}

class NavModel : ObservableObject {
    
    var a: A?
    var b: B?
    var c: C?
    ...
}

The NavModel is asked to consume a NavTo upon appearing in order to execute the programmatic navigation async fashion.

.onAppear {
      Task.detached {
           await navModel.navigateOnAppear()
      }
}

The NavViewModel in this example supports a single named select key, var selected: [String:Int?] per View. These can be used to select on the View's own items or to trigger NavigationLink instances that will match on some tag. The per View selected could be used to select a list item or as in this example, a button 4 via a KeyedId:

// to select button 4 on view A
let navTo = NavTo(downTo: [
    DownTo(view: navModel.a!, ids: [KeyedId(key: "buttons", id: 4)])
])

To programmaticaly trigger the NavigationLink to a sub view B:

   NavigationLink(destination: WrappedB(navModel: vModel.navModel, toSelect: KeyedId(key: "onBAppear", id: 1)), tag: 1, selection: $vModel.selected["B"]) {
        Text("to B")
   }

An iOS App, NavTestApp ties things together for this example by setting up 3 Views, A,B and C and programmatically navigating to C upon open, while preserving all the back buttons and hierarchy for stack navigation. The navigation is guided by the [NavTo]:

        // descend to B then C
        let navTo2 = NavTo(downTo: [
            DownTo(view: navModel.a!, ids: [KeyedId(key: "B", id: 1)]),
            DownTo(view: navModel.b!, ids: [KeyedId(key: "C", id: 1)]),
            DownTo(view: navModel.c!, ids: [KeyedId(key: "C", id: 7)])
        ])

About

SwiftUI example of programmatic navigable views for NavigationView hierarchies

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages