diff --git a/App/Sources/View Modifiers/ResignFocusModifier.swift b/App/Sources/View Modifiers/ResignFocusModifier.swift deleted file mode 100644 index e6ae001..0000000 --- a/App/Sources/View Modifiers/ResignFocusModifier.swift +++ /dev/null @@ -1,43 +0,0 @@ -import SwiftUI - -/// A view modifier that resigns the first responder status when the view is tapped. -/// -/// This modifier is useful for dismissing the keyboard or other input controls -/// when the user taps on an area of the view that doesn't have interactive content. -struct ResignFocusModifier: ViewModifier { - - // MARK: Body - - /// The content and behavior of the view modifier. - /// - /// Adds a tap gesture that sends the `resignFirstResponder` action - /// to dismiss any active first responder (such as a text field). - func body(content: Content) -> some View { - content - .onTapGesture { - UIApplication.shared.sendAction( - #selector(UIResponder.resignFirstResponder), - to: nil, - from: nil, - for: nil - ) - } - } - -} - -// MARK: - View Extension - -extension View { - - /// Adds a tap gesture that resigns the first responder when the view is tapped. - /// - /// This is useful for dismissing the keyboard or other input controls - /// when the user taps outside of an interactive element. - /// - /// - Returns: A view that resigns first responder status on tap. - func onResignFocus() -> some View { - modifier(ResignFocusModifier()) - } - -} diff --git a/App/Sources/Views/TaskList/TaskListContent.swift b/App/Sources/Views/TaskList/TaskListContent.swift index ed79fc7..a751f83 100644 --- a/App/Sources/Views/TaskList/TaskListContent.swift +++ b/App/Sources/Views/TaskList/TaskListContent.swift @@ -8,12 +8,6 @@ extension TaskListView { /// This view is responsible for querying and displaying the list of tasks based on the specified /// group and completion status filter. It exists as a separate view to enable dynamic query /// updates when filter parameters change. - /// - /// Task reordering is enabled based on the ``TodoGroup/canReorder`` property. - /// Groups that support reordering (``TodoGroup/today``, ``TodoGroup/upcoming``, - /// ``TodoGroup/overdue``) allow users to drag and drop tasks to change their order. - /// The ``TodoGroup/completed`` group does not support reordering as tasks are - /// displayed in chronological order by completion date. struct Content: View { // MARK: Type aliases @@ -124,7 +118,9 @@ extension TaskListView { items } .listStyle(.grouped) - .onResignFocus() + .onTapGesture { + resignFocus() + } } } } @@ -139,6 +135,12 @@ private extension TaskListView.Content { // MARK: Computed /// A view that renders the task items with appropriate modifiers. + /// + /// This computed property constructs a `ForEach` view over the tasks and conditionally + /// applies the `.onMove` modifier based on the `canReorder` capability. This approach + /// ensures that: + /// - All todo task lists support swipe-to-delete via `.onDelete` + /// - Only todo task groups that can be manually reordered enable drag-and-drop via `.onMove` @ViewBuilder var items: some View { let items = ForEach(todos) { @@ -158,6 +160,22 @@ private extension TaskListView.Content { } } + // MARK: Functions + + /// Dismisses the keyboard by resigning first responder status. + /// + /// This function sends a `resignFirstResponder` action through the responder chain, + /// causing any active text field or text view to resign its first responder status + /// and dismiss the keyboard. + func resignFocus() { + UIApplication.shared.sendAction( + #selector(UIResponder.resignFirstResponder), + to: nil, + from: nil, + for: nil + ) + } + } // MARK: - Previews