Base UI Components
Relevant source files
The following files were used as context for generating this wiki page:
- Putio/AppDelegate.swift
- Putio/Features/Files/FilesViewController.swift
- Putio/Features/Files/FilesViewController+Navigation.swift
- Putio/Features/Files/FilesViewController+Selection.swift
- Putio/Features/Files/MoveFilesViewController.swift
- Putio/Assets.xcassets/Colors/putio.background.colorset/Contents.json
- Putio/Assets.xcassets/Colors/putio.yellow.colorset/Contents.json
Introduction
Base UI components in the put.io iOS application provide a consistent visual language and behavioral framework across the legacy UIKit-based architecture. These components include global styling configurations, reusable state-driven views, and standardized navigation elements. The system ensures that features like file browsing, settings, and media management maintain a cohesive look and feel, specifically adhering to a dark-themed interface.
The UI architecture primarily relies on Stylize.UIKit for global appearance overrides and the StatefulViewController protocol for managing content transitions between loading, empty, and error states. This structure allows developers to focus on feature-specific logic while delegating common UI behaviors to shared helpers and extensions.
Global Styling and Appearance
The application enforces a specific visual identity through global appearance proxies and asset-based color sets. The primary color palette centers on "Putio Yellow" and a deep black background, ensuring high contrast and brand recognition.
Theme Configuration
Global appearance is applied during application launch in the AppDelegate. The window is configured with a forced dark interface style and specific background and tint colors.
| Property | Value/Source | Purpose |
|---|---|---|
backgroundColor | UIColor.Putio.black | Primary background color for all windows. |
tintColor | UIColor.Putio.yellow | Primary interaction and accent color. |
overrideUserInterfaceStyle | .dark | Forces dark mode regardless of system settings. |
Sources: Putio/AppDelegate.swift:97-101, Putio/Assets.xcassets/Colors/putio.yellow.colorset/Contents.json, Putio/Assets.xcassets/Colors/putio.background.colorset/Contents.json
Visual Hierarchy Diagram
The following diagram illustrates how global styles flow from the AppDelegate to individual view controllers.
Sources: Putio/AppDelegate.swift:51-64
Stateful View Management
The project utilizes the StatefulViewController protocol to handle the lifecycle of views that depend on network data. This allows for a standardized way to present loading indicators, empty states, and error messages.
State Transitions
View controllers, such as FilesViewController and MoveFilesViewController, implement a state machine to transition between different UI states based on API results.
| State | Component | Usage Scenario |
|---|---|---|
loading | LoaderView | Displayed while fetching data from the Putio SDK. |
empty | EmptyStateView | Shown when a directory or list contains no items. |
offline | OfflineStatusView | Triggered by network reachability failures. |
error | EmptyStateView | Generic fallback for unknown or decoding errors. |
404 | EmptyStateView | Specific state for missing files or directories. |
Sources: Putio/Features/Files/FilesViewController.swift:75-103, Putio/Features/Files/MoveFilesViewController.swift:34-38
State Machine Logic
Navigation and Toolbar Components
Navigation in the app is standardized using custom UIBarButtonItem configurations and specialized toolbars for bulk operations.
Navigation Bar Buttons
Standardized buttons are created via extensions to ensure consistency. For example, the "File Actions" button uses a specific symbol configuration and the brand's yellow tint.
- File Actions Button: Uses
ellipsis.circle(SF Symbol) with a regular weight and 18pt size. - Chromecast Button: A
GCKUICastButtonis integrated into the navigation bar of media-heavy views.
Sources: Putio/Features/Files/FilesViewController+Navigation.swift:7-17, Putio/Features/Files/FilesViewController+Navigation.swift:23-28
Editing Toolbar
For selection-based features (e.g., Files, History), a secondary toolbar is used. This toolbar appears at the bottom of the safe area and provides actions like "Move", "Trash", or "Delete".
func configureToolbar() {
let toolbar = UIToolbar()
toolbar.tintColor = UIColor.Putio.yellow
let deleteTitle = userSettings.trashEnabled
? NSLocalizedString("Trash", comment: "")
: NSLocalizedString("Delete", comment: "")
let moveBtn = UIBarButtonItem(title: NSLocalizedString("Move", comment: ""), style: .plain, target: self, action: #selector(moveSelectedFiles))
let deleteBtn = UIBarButtonItem(title: deleteTitle, style: .plain, target: self, action: #selector(deleteSelectedFiles))
toolbar.items = [moveBtn, UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil), deleteBtn]
}
Sources: Putio/Features/Files/FilesViewController+Navigation.swift:101-130
Bulk Selection Interactions
The UI components support a "Selection Mode" that modifies the standard navigation interface to allow for batch processing of items.
Selection Flow
- Enter Editing: The user triggers "Select" from the file actions menu.
- UI Modification: The back button is hidden, a "Select All" button is added to the left, and "Done" is added to the right.
- Toolbar Visibility: The
editingToolbaris unhidden, and the main tab bar is hidden to focus on the selection task. - Action Feedback: Navigation titles update dynamically (e.g., "1 Item", "5 Items") to reflect the selection count.
Sources: Putio/Features/Files/FilesViewController+Selection.swift:15-35, Putio/Features/Files/FilesViewController+Selection.swift:105-120
Conclusion
The Base UI Components of the put.io iOS app establish a robust foundation for a dark-themed, data-driven mobile experience. By centralizing styling in the AppDelegate and utilizing StatefulViewController for consistent state management, the architecture ensures that complex file operations and media browsing remain intuitive and visually unified. Citing: Putio/AppDelegate.swift, Putio/Features/Files/FilesViewController.swift.