listless

A simple list app for Apple platforms
Log | Files | Refs | README | LICENSE

AppCommands.swift (2437B)


      1 import UIKit
      2 
      3 // MARK: - Menu Coordinator
      4 
      5 /// Bridges SwiftUI view state to UIKit menu items, mirroring the macOS
      6 /// `MenuCoordinator` pattern. `ItemListView.updateMenuCoordinator()` keeps
      7 /// actions and enabled flags current; `KeyCaptureView` dispatches actions
      8 /// and validates commands via the responder chain.
      9 @MainActor
     10 final class IOSMenuCoordinator {
     11     static let shared = IOSMenuCoordinator()
     12     private init() {}
     13 
     14     // Actions — set by ItemListView on each relevant state change.
     15     var newItem: (() -> Void)?
     16     var deleteItem: (() -> Void)?
     17     var moveUp: (() -> Void)?
     18     var moveDown: (() -> Void)?
     19     var markCompleted: (() -> Void)?
     20     var navigatePageUp: (() -> Void)?
     21     var navigatePageDown: (() -> Void)?
     22     var navigateToFirst: (() -> Void)?
     23     var navigateToLast: (() -> Void)?
     24 
     25     // Enabled state — read by KeyCaptureView in validate(_:).
     26     var canDelete = false
     27     var canMoveUp = false
     28     var canMoveDown = false
     29     var canMarkCompleted = false
     30 
     31     // Dynamic title — read by KeyCaptureView in validate(_:).
     32     var markCompletedTitle: String = "Mark as Complete"
     33 }
     34 
     35 // MARK: - Menu Selectors
     36 
     37 /// Selectors for menu item actions routed through the responder chain.
     38 /// `KeyCaptureView` (first responder) implements these as `@objc` methods.
     39 enum IOSMenuSelectors {
     40     static let newItem = #selector(IOSMenuActions.handleNewItem)
     41     static let deleteItem = #selector(IOSMenuActions.handleDeleteItem)
     42     static let moveUp = #selector(IOSMenuActions.handleMoveUp)
     43     static let moveDown = #selector(IOSMenuActions.handleMoveDown)
     44     static let markCompleted = #selector(IOSMenuActions.handleMarkCompleted)
     45     static let navigatePageUp = #selector(IOSMenuActions.handleNavigatePageUp)
     46     static let navigatePageDown = #selector(IOSMenuActions.handleNavigatePageDown)
     47     static let navigateToFirst = #selector(IOSMenuActions.handleNavigateToFirst)
     48     static let navigateToLast = #selector(IOSMenuActions.handleNavigateToLast)
     49 }
     50 
     51 /// Protocol declaring the `@objc` action methods so selectors can be
     52 /// referenced at compile time. `KeyCaptureView` conforms to this.
     53 @MainActor @objc protocol IOSMenuActions {
     54     func handleNewItem()
     55     func handleDeleteItem()
     56     func handleMoveUp()
     57     func handleMoveDown()
     58     func handleMarkCompleted()
     59     func handleNavigatePageUp()
     60     func handleNavigatePageDown()
     61     func handleNavigateToFirst()
     62     func handleNavigateToLast()
     63 }