Activity 1
Build a two-tab shell
Create Library and Profile tabs, each containing its own navigation controller and root screen.
Hint: Give every tab a title and system image and verify each stack is preserved.
UIKit Development
Build hierarchical and top-level UIKit navigation with system container controllers and explicit routing decisions.
Before you begin
Learning stage
UINavigationController manages an ordered stack: pushing moves deeper into a hierarchy and popping returns. Each content controller configures its own navigationItem while the container owns the navigation bar and transitions. Avoid manually adding a navigation bar to every screen.
UITabBarController switches among a small number of peer destinations. Each tab often owns a separate navigation controller so it preserves its own stack. Tabs represent stable top-level areas, not transient filters or a long list of unrelated actions.
Navigation is application state. A coordinator or router can construct controllers, translate deep links into valid stacks, and prevent individual screens from knowing every destination. Keep transitions on the main actor, avoid pushing the same route twice, and define what happens when a tab is reselected or a modal interrupts a flow.
Learning stage
A small coordinator owns construction and push decisions while the controller emits intent.
@MainActor
final class LearningCoordinator {
let navigationController = UINavigationController()
func start() {
let list = CourseListViewController()
list.onSelectCourse = { [weak self] courseID in
self?.showCourse(id: courseID)
}
navigationController.setViewControllers([list], animated: false)
}
private func showCourse(id: Course.ID) {
guard !(navigationController.topViewController is CourseDetailViewController) else {
return
}
let detail = CourseDetailViewController(courseID: id)
navigationController.pushViewController(detail, animated: true)
}
}Learning stage
Connect the UIKit concept to complete, maintainable application features.
Learning stage
Identify lifecycle, ownership, identity, layout, accessibility, and user-experience risks.
Learning stage
Build the behavior in a small Xcode project and inspect it across realistic states.
Activity 1
Create Library and Profile tabs, each containing its own navigation controller and root screen.
Hint: Give every tab a title and system image and verify each stack is preserved.
Activity 2
Model a link to a course detail and build the required tab selection and navigation stack.
Hint: Validate identifiers before changing visible navigation.
Learning stage
Answer each question before revealing the explanation.
QUESTION 1
Moving deeper into a content hierarchy
The stack preserves the path so the user can navigate back.
QUESTION 2
So each top-level area can maintain an independent hierarchical stack.
Switching tabs should not normally destroy the user's place in another area.
Learning stage
Explain the design in terms of lifecycle, identity, ownership, system behavior, and trade-offs.
Short answer: Use system containers for hierarchy and peer destinations, and keep route construction in a focused coordinator when flows grow.
Content controllers publish user intentions. A coordinator validates routes, constructs dependencies, and pushes, presents, or selects tabs. Each tab can own a navigation stack, and deep links are translated into explicit container state rather than simulated taps.
Possible follow-ups
Learning stage
UIKit container controllers encode familiar navigation behavior. Treat their stacks and selections as explicit state and centralize complex routing decisions.