Each page of an iOS application (sometimes referred to as a scene) is managed by a view controller. The purpose of the view controller is to coordinate between the view and model, in line with the Model-View-Controller (MVC) architecture used in iOS apps.
The various view controllers in the app are managed by a navigation controller, which stores them in an array. The navigation controller pushes view controllers onto the stack as needed. Initially, the root view controller will be at the top of the navigation stack. Each user action within the current view controller pushes a new view controller onto the stack. Going back from one screen to the previous one pops the current view controller off the stack, revealing the previous view controller that is now at the top of the stack.
At least, this is my current understanding of the relationship between the navigation controller and the various view controllers. I’ll add to this as my understanding evolves.
Perhaps we could think of this as being a little like a multiplex movie theatre with a single box office. Each room within the multiplex has its own projectionist (view controller). The user accesses the application through via the box office and is directed to the correct room (app page). Imagine a person with a special ticket that is good for any of the movies that are showing. All they have to do is return to the box office (navigation controller) and get directed to the correct room.
The analogy is not perfect because it does not quite capture the idea of the stack. But it illustrates the way the navigation controller controls which view the user sees, and the autonomy of each view to manage its own affairs.