← All repositories

listless

A simple list app for Apple platforms

git clone https://code.inqk.net/listless.git


commit 54fe3702c4345b6ff5ac14d306f56e484b0e99f2
parent 70be346be50f71014b8f4567f5df75d2c63e1bc1
Author: Michael Camilleri <[email protected]>
Date:   Fri, 27 Feb 2026 07:59:07 +0900

Improve semantics of return key on iOS keyboard

Co-Authored-By: Codex GPT 5.3 <[email protected]>

Diffstat

MListlessiOS/Helpers/TappableTextField.swift | 7++++++-
MListlessiOS/Views/TaskListView.swift | 1+
MListlessiOS/Views/TaskRowView.swift | 4++++

3 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/ListlessiOS/Helpers/TappableTextField.swift b/ListlessiOS/Helpers/TappableTextField.swift

@@ -8,6 +8,7 @@ struct TappableTextField: UIViewRepresentable {
     @Binding var text: String
     let isCompleted: Bool
     let onEditingChanged: (Bool, _ shouldCreateNewTask: Bool) -> Void
+    var returnKeyType: UIReturnKeyType = .done
     var onContentChange: ((String) -> Void)? = nil
 
     func makeUIView(context: Context) -> UITextView {
@@ -20,7 +21,7 @@ struct TappableTextField: UIViewRepresentable {
         textView.isScrollEnabled = false
         textView.autocorrectionType = .default
         textView.autocapitalizationType = .sentences
-        textView.returnKeyType = .done
+        textView.returnKeyType = returnKeyType
 
         let placeholder = UILabel()
         placeholder.text = "Enter task"
@@ -41,6 +42,10 @@ struct TappableTextField: UIViewRepresentable {
         if !textView.isFirstResponder {
             applyStyle(to: textView, text: text, isCompleted: isCompleted)
         }
+        if textView.returnKeyType != returnKeyType {
+            textView.returnKeyType = returnKeyType
+            textView.reloadInputViews()
+        }
         textView.isEditable = !isCompleted
         textView.isSelectable = !isCompleted
         if let placeholder = textView.viewWithTag(100) as? UILabel {

diff --git a/ListlessiOS/Views/TaskListView.swift b/ListlessiOS/Views/TaskListView.swift

@@ -211,6 +211,7 @@ struct TaskListView: View, TaskListViewProtocol {
                         totalTasks: displayActiveTasks.count,
                         isSelected: selectedTaskID == taskID,
                         isDragging: isDraggingStateBinding,
+                        isLastActiveTask: index == displayActiveTasks.count - 1,
                         focusedField: $focusedFieldBinding,
                         onToggle: { toggleCompletion($0) },
                         onTitleChange: { updateTitle($0, $1) },

diff --git a/ListlessiOS/Views/TaskRowView.swift b/ListlessiOS/Views/TaskRowView.swift

@@ -11,6 +11,7 @@ struct TaskRowView: View {
     let onTitleChange: (TaskItem, String) -> Void
     let onDelete: (TaskItem) -> Void
     let onSelect: (UUID) -> Void
+    let isLastActiveTask: Bool
     let onStartEdit: (UUID) -> Void
     let onEndEdit: (UUID, _ shouldCreateNewTask: Bool) -> Void
     @FocusState.Binding var focusedField: FocusField?
@@ -29,6 +30,7 @@ struct TaskRowView: View {
         totalTasks: Int = 1,
         isSelected: Bool,
         isDragging: Binding<Bool> = .constant(false),
+        isLastActiveTask: Bool = false,
         focusedField: FocusState<FocusField?>.Binding,
         onToggle: @escaping (TaskItem) -> Void,
         onTitleChange: @escaping (TaskItem, String) -> Void,
@@ -43,6 +45,7 @@ struct TaskRowView: View {
         self.totalTasks = totalTasks
         self.isSelected = isSelected
         _isDragging = isDragging
+        self.isLastActiveTask = isLastActiveTask
         self.onToggle = onToggle
         self.onTitleChange = onTitleChange
         self.onDelete = onDelete
@@ -80,6 +83,7 @@ struct TaskRowView: View {
                         else { onEndEdit(taskID, shouldCreateNewTask) }
                     }
                 },
+                returnKeyType: isLastActiveTask ? .next : .done,
                 onContentChange: { newTitle in
                     guard !task.isCompleted else { return }
                     onTitleChange(task, newTitle)