ThreeTodo App
Efficient Task Management
Overview
From April 13 to April 21, 2024, I independently built ThreeTodo, a lightweight iOS task manager emphasizing fluid navigation, minimal UI, and drag-and-drop efficiency. The project demanded a swift, five-day turnaround—an ideal environment to showcase my agile approach and expertise in user-centric design. ThreeTodo’s hallmark is its intuitive multi-page structure (Plan / Today / Thoughts), requiring minimal taps or screens to keep track of evolving tasks and ideas.
Core Highlights
-
Rapid Development
- Single-handedly coded and tested within just five days, from initial concept to functional MVP.
- Utilized SwiftUI for swift prototyping, iterative feedback, and clean layout definitions.
-
Minimal Navigation & UI
- Only three primary views—Plan, Today, and Thoughts—to reduce complexity.
- Implemented drag-and-drop gestures for reordering tasks, cross-screen transfers, and quick deletion in a single touch flow.
- No extraneous steps (due dates, priority setups)—one-tap additions or inline edits.
-
User-centric Approach
- Emphasis on inline editing with dynamic text expansions (auto height), eliminating sub-menus or separate edit screens.
- Contextual actions: hold long-press to insert dividers, multi-task deletion, or use a built-in “trash” drop zone.
-
Agile Success & Feedback
- Deployed an MVP that testers praised for clarity and practical usage in daily to-do management.
- Demonstrated readiness for quick project turnarounds in dynamic, fast-paced environments.
Key Functionalities
1. Draggable Tasks & Cross-Screen Flows
-
Single Source of Truth:
- Maintained tasks in three arrays (
plans,todays,thoughts) with a global functionremoveTaskGlobally()to seamlessly move a task from one screen to another if dragged outside.
- Maintained tasks in three arrays (
-
Swipe-based Navigation:
- SwiftUI TabView with
.pagestyle—Plan, Today, Thoughts—enables horizontal swiping. - Each tab maintains its own list of tasks, but a user can drag tasks from one list onto another tab’s “plus” button to re-categorize.
- SwiftUI TabView with
Sample: Drag & Drop for Cross-Screen Transfer
func handleDropTask(withId taskId: UUID) {
if let task = removeTaskGlobally(taskId) {
tasks.append(task)
}
}2. Inline Editing & Resizable Text Fields
-
Dynamic TextEditor:
- Each task dynamically resizes based on content length.
- No separate “edit mode”; text is always directly editable in place.
-
Height Estimation:
- Calculated text height using
NSLayoutManagerandNSTextContainerto ensure the UI expansions remain fluid and stable.
- Calculated text height using
Sample: Dynamic Sizing for Task Text
private func estimateHeight(text: String, width: CGFloat) -> CGFloat {
let attributes: [NSAttributedString.Key: Any] = [
.font: UIFont.systemFont(ofSize: fontSize)
]
let textStorage = NSTextStorage(string: text, attributes: attributes)
let textContainer = NSTextContainer(size: CGSize(width: width - 30,
height: .greatestFiniteMagnitude))
let layoutManager = NSLayoutManager()
layoutManager.addTextContainer(textContainer)
textStorage.addLayoutManager(layoutManager)
layoutManager.glyphRange(for: textContainer)
let rect = layoutManager.usedRect(for: textContainer)
return ceil(rect.size.height)
}3. Contextual Menus & Divider Templates
-
Dividers:
- Long-press on the “+” button toggles between adding normal tasks or divider tasks.
- Dividers help visually group tasks—Morning / Afternoon / Evening, or custom user-defined sets.
-
Template System:
- Users can create an array of divider sets (
["Morning", "Afternoon", "Evening"]etc.) and insert them as needed. - Efficiently reuses repeated structures for daily planning or priority grouping.
- Users can create an array of divider sets (
Sample: TemplateSelector & Inline Generation
TemplateSelector(templates: $templates) { selectedTemplate in
for name in selectedTemplate.names {
tasks.append(TaskItem(text: name, isDivider: true))
}
}4. Swift & SwiftUI Architecture
- Single
ContentView: orchestrates data arrays for three subviews (Plan, Today, Thoughts). -
Per-Tab custom
TodoListView**:- Each view includes a “trash” area for convenient mass deletion or single drag-drop disposal.
- Each list uses SwiftUI’s
Listwith.onMove(perform:)to reorder tasks seamlessly.
- UserDefaults Persistence:
- Data is periodically encoded via
JSONEncoderfor quick, simple local storage.
- Data is periodically encoded via
Sample: Multi-Tab & Data Persistence
func saveData() {
if let encodedPlans = try? JSONEncoder().encode(plans),
let encodedTodays = try? JSONEncoder().encode(todays),
let encodedThoughts = try? JSONEncoder().encode(thoughts) {
UserDefaults.standard.set(encodedPlans, forKey: "Plans")
UserDefaults.standard.set(encodedTodays, forKey: "Todays")
UserDefaults.standard.set(encodedThoughts, forKey: "Thoughts")
}
}Project Outcomes
- Immediate Praise: Beta testers found the app’s simplicity extremely appealing—“No fluff, just tasks.”
- Demonstrated Agility: Showed that a week-long project can produce a highly functional, user-friendly to-do manager with advanced features (drag, context menus, partial screen transfers).
- Scalable: The approach can easily integrate additional boards/screens or more advanced collaborative features—foundation is deliberately clean and easily extensible.
Personal Growth & Reflection
-
Technical Mastery
- Mastered bridging advanced iOS text measurement (
NSLayoutManager) with SwiftUI’s reactive layout. - Fine-tuned multi-gesture logic for a truly drag-centric UX, from in-list reordering to cross-list moves.
- Mastered bridging advanced iOS text measurement (
-
Rapid Delivery & Problem-Solving
- Balanced “must-have” features (inline editing, drag-and-drop) with a minimal UI to meet a five-day MVP deadline.
- Employed iterative refinements—shipping quickly and refining on user feedback in real time.
-
User-Centered Design
- Avoided common complexities like due dates or priorities, focusing on frictionless daily usage.
- Keenly leveraged “divider” logic and templates to reduce repetitive overhead and highlight user creativity.
Final Thoughts
ThreeTodo exemplifies my ability to craft a purpose-driven app under tight deadlines, employing a lean feature set that resonates with everyday to-do needs. By championing straightforward user flows (dragging, minimal tapping) and implementing technical solutions (dynamic text expansion, flexible data structures, context menus), I delivered a tool that merges usability, performance, and clarity—all in under a week.
This project underscores my competence in rapidly transforming an idea into a polished, robust product. It stands as proof of my coding versatility in Swift and my dedication to user-friendly software design that truly meets real-world demands.