NXNavigationExtension

repository·main·Indexed 41 days ago

https://github.com/l1dan/nxnavigationextension

A lightweight, extensible library for managing UINavigationBar appearance and behavior in iOS for both SwiftUI and UIKit. It provides tools for background modification, transition animations, and intercepting back button or gesture events without modifying the native view hierarchy. Features include full-screen interactive pop gestures, custom back button views, and a dedicated SwiftUI modifier `.useNXNavigationView` for navigation bar configuration.

Tokens
9.4K
Snippets
30
Records
32
Agent score
52%

What's inside NXNavigationExtension

  1. Best practices and restrictions for NXNavigationExtension

    main

    To avoid conflicts with the framework and ensure stability, follow these usage rules:

    • Use a subclass of UINavigationController and register that subclass.
    • Register controllers in AppDelegate before modifying appearances.
    • Use the framework's methods to handle all navigation bar modifications.

    ❌ Do Not Use (Avoid these)

    • Do not register UINavigationController.self directly.
    • Do not use system methods like setNavigationBarHidden:, setNavigationBarHidden:animated:, or setHidden: to show/hide the bar.
    • Do not use system properties to modify transparency or appearance related properties.
    • Do not use <UIGestureRecognizerDelegate> methods to disable swipe-back gestures; use the framework's provided features instead.
    • Do not use edgesForExtendedLayout = UIRectEdge(rawValue: 0) unless specifically instructed by the framework's issue discussions.
  2. Register Navigation Controllers in AppDelegate

    main

    Unlike the UIKit version, the SwiftUI version requires you to specify a lookup rule for NXNavigationVirtualWrapperView, which acts as the bridge between SwiftUI and UIKit. You must register the relevant navigation controller classes in your AppDelegate using NXNavigationConfiguration.

    For iOS 15+, you should include both SplitViewNavigationController and UIKitNavigationController. For iOS 14, only SplitViewNavigationController is required.

    // AppDelegate.swift
    var classes: [AnyClass] = []
    if #available(iOS 15.0, *) {
        classes = [
            NSClassFromString("SwiftUI.SplitViewNavigationController"),
            NSClassFromString("SwiftUI.UIKitNavigationController"),
        ].compactMap { $0 }
    } else {
        classes = [
            NSClassFromString("SwiftUI.SplitViewNavigationController"), // iOS14
        ].compactMap { $0 }
    }
    
    let defaultConfiguration = NXNavigationConfiguration.default
    defaultConfiguration.registerNavigationControllerClasses(classes) { navigationController, configuration in
        // Configure the bridge using the default rule
        navigationController.nx_applyFilterNavigationVirtualWrapperViewRuleCallback(NXNavigationVirtualView.configureWithDefaultRule(for:))
        return configuration
    }
  3. Setup NXNavigationExtension for UIKit

    main

    To use the framework, you must first import the module and register your custom navigation controller classes in your AppDelegate. The framework operates on a per-view-controller basis rather than globally managing a UINavigationController, which allows for more granular control.

    Registration Steps

    1. Import the module: import NXNavigationExtension.
    2. Register your custom UINavigationController subclasses in AppDelegate using NXNavigationConfiguration().registerNavigationControllerClasses([...]).

    Best Practices

    • Do not register UINavigationController.self directly, as this will affect all navigation controllers globally. Instead, create a subclass of UINavigationController and register that.
    • Follow the "who uses it, who registers it" principle to avoid polluting other parts of your app.
    • Use the registration process before attempting to modify the appearance of view controllers managed by those navigation controllers.
    // Register one or multiple custom navigation controller classes
    NXNavigationConfiguration().registerNavigationControllerClasses([YourNavigationController.self])
    
    // Or multiple
    NXNavigationConfiguration().registerNavigationControllerClasses([YourNavigationController.self, YourNavigationController2.self])
  4. Dynamically configure navigation bar appearance

    main

    You can use NXNavigationConfiguration.default to apply global settings or provide a closure to dynamically modify the configuration based on the specific UINavigationController or UIViewController being presented.

    This allows you to:

    1. Apply a default configuration to all registered controllers.
    2. Provide specific logic for different UINavigationController subclasses.
    3. Provide specific logic for individual UIViewController instances using nx_prepareConfigureViewControllersCallback.
    let configuration = NXNavigationConfiguration.default
    
    // Set global defaults
    configuration.navigationBarAppearance.tintColor = .customTitle
    
    configuration.registerNavigationControllerClasses([YourNavigationController.self, YourNavigationController2.self]) { navigationController, configuration in
        // Logic for specific UINavigationController subclasses
        if navigationController is YourNavigationController {
            configuration.navigationBarAppearance.backgroundColor = .brown
            
            // Logic for specific UIViewController instances within this controller
            navigationController.nx_prepareConfigureViewControllersCallback { viewController, configuration in
                if viewController is MyViewController {
                    configuration.navigationBarAppearance.backgroundColor = .red
                }
            }
        }
        return configuration
    }
  5. Install NXNavigationExtension via CocoaPods

    main

    To integrate NXNavigationExtension into your Xcode project using CocoaPods, add the appropriate pod to your Podfile based on whether you are using SwiftUI or UIKit.

    ## For SwiftUI
    pod 'NXNavigationExtension/SwiftUI'
    
    ## For UIKit
    pod 'NXNavigationExtension'
  6. Integrate NXNavigationExtensionSwiftUI into your project

    main

    To use the SwiftUI extension, first import the module based on your dependency manager:

    • CocoaPods: import NXNavigationExtension
    • Carthage: import NXNavigationExtensionSwiftUI

    Compatibility Matrix:

    NavigationViewiOS 14iOS 15iOS 16iOS 17
    .automatic❌❌❌❌
    .columns❌❌❌❌
    .stack✅✅✅✅
    NavigationStack❌❌✅✅
    // CocoaPods
    import NXNavigationExtension
    
    // Carthage
    import NXNavigationExtensionSwiftUI
  7. Register Navigation Controllers for NXNavigationExtension

    main

    Before modifying navigation bar appearances, you must register your navigation controller classes. The framework uses a 'whitelist' mode to ensure it only affects the controllers you explicitly register, preventing global side effects.

    Important: Do not register UINavigationController.self directly, as this will affect all navigation controllers in your app. Instead, create a subclass of UINavigationController and register that subclass.

    import NXNavigationExtension
    
    // Register a single custom navigation controller class
    NXNavigationConfiguration().registerNavigationControllerClasses([YourNavigationController.self])
    
    // Register multiple custom navigation controller classes
    NXNavigationConfiguration().registerNavigationControllerClasses([YourNavigationController.self, YourNavigationController2.self])
  8. Install NXNavigationExtension via Swift Package Manager

    main

    To integrate NXNavigationExtension using Swift Package Manager, add the following dependency to your Package.swift file.

    dependencies: [
        .package(url: "https://github.com/l1Dan/NXNavigationExtension.git", .upToNextMajor(from: "4.2.7"))
    ]
  9. Install NXNavigationExtension via Carthage

    main

    To manage NXNavigationExtension using Carthage, add the following entries to your Cartfile.

    # For SwiftUI
    github "l1Dan/NXNavigationExtension" # Requires
    gitub "l1Dan/NXNavigationExtensionSwiftUI"
    
    # For UIKit
    gitub "l1Dan/NXNavigationExtension"
  10. Configure Global Navigation Settings

    main

    Use NXNavigationConfiguration.default to apply settings globally across your application. This is useful for setting a default background color or enabling full-screen interactive pop gestures for all view controllers.

    // Global background color
    let configuration = NXNavigationConfiguration.default
    configuration.navigationBarAppearance.backgroundColor = .red
    
    // Global full-screen pop gesture
    configuration.viewControllerPreferences.enableFullScreenInteractivePopGesture = true
  11. Important restrictions when using NXNavigationExtension

    main

    To avoid conflicts with the framework's internal logic, do not use the following system methods or properties directly:

    • Visibility: Do not use setNavigationBarHidden:, setNavigationBarHidden:animated:, or setHidden: to show/hide the navigation bar.
    • Transparency: Do not use system navigation bar properties to modify opacity/alpha.
    • Appearance: Do not use system appearance related properties on the navigation bar or navigation controller.
    • Gestures: Do not use <UIGestureRecognizerDelegate> methods to disable the back gesture.
    • Layout: Avoid setting edgesForExtendedLayout = UIRectEdge(rawValue: 0) on UIViewController unless absolutely necessary; use the default settings.