Classes
The following classes are available globally.
-
Declaration
Swift
private class ResourceBundleClass
-
This is the app delegate for the main app.
See moreDeclaration
Swift
@main @MainActor class RiValT_AppDelegate : UIResponder, UIApplicationDelegate
-
This is the scene delegate for the main app.
See moreDeclaration
Swift
@MainActor class RiValT_SceneDelegate : UIResponder, UIWindowSceneDelegate
-
This provides basic utilities and UI for all screens in the app.
See moreDeclaration
Swift
@MainActor class RiValT_Base_ViewController : UIViewController
extension RiValT_Base_ViewController: UIPopoverPresentationControllerDelegate
-
This will not turn grey. Instead, it will become clear.
See moreDeclaration
Swift
@MainActor class RiValT_DisappearingBarButton : UIBarButtonItem
-
A base class for the bar button items in the Group Editor Screen.
Declaration
Swift
@MainActor class BaseCustomBarButtonItem : UIBarButtonItem
-
This represents the bar button item for the display preferences popover. It changes its image to represent the currently selected timer display.
See moreDeclaration
Swift
@MainActor class DisplayBarButtonItem : BaseCustomBarButtonItem
-
This represents the bar button item for the sound preferences popover. It changes its image to represent the currently selected alarm sound.
See moreDeclaration
Swift
@MainActor class SoundBarButtonItem : BaseCustomBarButtonItem
-
This class draws a border around the currently selected group.
See moreDeclaration
Swift
@MainActor class SectionBackgroundView : UICollectionReusableView
-
This is a UIPageViewController subclass, that will manage individual presentations of the
RiValT_EditTimer_ViewController
class.It’s main purpose, is to add “swipe to select” services, for groups containing multiple timers.
This class is embedded into an instance of
See moreRiValT_TimerEditor_PageViewContainer
, and it is basically “invisible.”Declaration
Swift
@MainActor class RiValT_TimerEditor_PageViewController : UIPageViewController
-
This is used as a wrapper for each individual timer, and provides accessors.
We make it a class, so it can be easily referenced.
See moreDeclaration
Swift
class Timer : Equatable
extension Timer: Hashable
extension Timer: CustomDebugStringConvertible
-
This class allows us to have “placeholders,” for the “add” items at the ends of the rows, or the bottom of the matrix.
See moreDeclaration
Swift
class RiValT_TimerArray_Placeholder
extension RiValT_TimerArray_Placeholder: Equatable
extension RiValT_TimerArray_Placeholder: Identifiable
extension RiValT_TimerArray_Placeholder: Hashable
-
This is a basic view class, for the display cells in the collection view.
See moreDeclaration
Swift
@MainActor class RiValT_BaseCollectionCell : UICollectionViewCell
-
This describes “add” cells in the collection view. These are simple “cross” buttons, that allow new timers to be appended.
See moreDeclaration
Swift
@MainActor class RiValT_TimerArray_AddCell : RiValT_BaseCollectionCell
-
This describes each cell, representing a timer, in the collection view.
See moreDeclaration
Swift
@MainActor class RiValT_TimerArray_IconCell : RiValT_BaseCollectionCell
-
This is the main view controller for the “About This App” screen (accessed from the global settings popover).
See moreDeclaration
Swift
@MainActor class RiValT_About_ViewController : RiValT_Base_ViewController
-
This is displayed in a popover, and allows the user to select which display type the group will use.
It presents a segmented switch at the top, with three choices, and a larger preview area, directly below the switch. The preview area shows a “mockup” of the selected display type.
It can be:
Numerical
Circular
Stoplights
Declaration
Swift
@MainActor class RiValT_DisplaySettings_ViewController : RiValT_Base_ViewController
-
This is a simple popover that shows a list of checkboxes and buttons, affecting global app preferences.
See moreDeclaration
Swift
@MainActor class RiValT_Settings_ViewController : RiValT_Base_ViewController
-
This view controller is for the popover that appears, when the user selects the sound prefs bar button item.
This has a segmented switch at the top, representing the user’s choice for final alarm sound.
It can be:
Silent
Sound Only
Vibration Only (iPhones only)
Sound and Vibration (iPhones only)
When the user makes a selection, a picker view may appear, directly under the switch. This appears for either Sound Only, or Sound and Vibration. This picker allows the user to choose from the app’s custom sounds.
If there is more than one timer in the group, a “Transition Sound” picker will appear, at the bottom of the screen. This allows the user to select a short transition sound, between timers.
See moreDeclaration
Swift
@MainActor class RiValT_SoundSettings_ViewController : RiValT_Base_ViewController
extension RiValT_SoundSettings_ViewController: UIPickerViewDataSource
extension RiValT_SoundSettings_ViewController: UIPickerViewDelegate
extension RiValT_SoundSettings_ViewController: UIPickerViewAccessibilityDelegate
extension RiValT_SoundSettings_ViewController: AVAudioPlayerDelegate
-
This is the view controller for the “multi-timer” screen, where we can arrange timers in groups and add new ones.
It allows the user to drag and drop timers, so they can visually rearrange the matrix.
BASIC STRUCTURE
This controller displays a UICollectionView instance, filled with vertical rows, representing “timer groups.” Each row is a group.
Each group can have up to 4 horizontally-arranged timers. Timers in a group, execute sequentially, from left, to right.
When a timer transitions from a left timer, to the one to its right (the left timer ends, and starts the right timer automatically), a “transition sound” may be played.
When the rightmost timer ends, the “alarm sound” is played.
The user can drag timers around, by long-pressing on a timer. The timer can move within a group, or from one group to another.
Groups can have options specified, that apply to all timers in a group. When a timer is moved from one group to another, it adapts to the group setings for the new group.
Timer Selection and Group Selection
One timer must always be selected. This is indicated by a black background, and a colored digital font for the timer value[s].
If a timer is selected, then its group is also selected. Group selection is indicated by a horizontal “gradient” highlight, across the row.
If there is more than one row, or more than one timer in a group, then a number will appear, at the right end of the row selection highlight.
If there is more than one timer in the group, then this number will be a tappable button. Tapping it, will advance the timer selection, wrapping, if at the end.
GLOBAL SETTINGS
In the left of the Navigation Bar, is a “gear” icon. This displays a popover, with checkboxes that affect options for the entire app (not just single groups).
Start Timer Immediately Checkbox
If this checkbox is checked, then hitting the “Play” triangle will immediately start the timer. If it is unchecked, then the timer will start in a “paused” state, and will require an additional step, to start counting down.
“One-Tap” Timer Editing Checkbox
If this checkbox is checked, then simply tapping on a timer, will bring in the Timer Editor Screen for that timer.
If it is unchecked, then tapping on a timer will simply select the timer, and an “Edit” item will appear in the Toolbar, at the bottom of the screen.
That “Edit” item will need to be tapped, to bring in the Timer Editor Screen for whichever timer is selected.
Show Toolbar In Timer Checkbox (Not displayed for Mac -Mac always shows the toolbar, and it can’t be hidden)
In iPhone and iPad, you can have a toolbar optionally displayed across the bottom of the Running Timer Screen. This toolbar is always shown, for Mac Catalyst.
If the toolbar is shown, then the user must tap on items in the toolbar, to control the timer.
If the toolbar is not shown, then swipe and tap gestures are used to control the running timer (discussed in the Running Timer Screen).
Auto-Hide Toolbar Checkbox (Only displayed when “Show Toolbar In Timer” is shown and selected)
If this is selected, then the toolbar will fade out, after a few seconds of user inactivity (the timer keeps going, though). Tapping on the screen, brings the toolbar back.
About This App Button
Tapping on this button will dismiss the popover, and bring in the “About This App” Screen.
GROUP SETTINGS
In the top, right of the Navigation Bar, are two items: A little “screen” icon, representing the current display mode for the group, and a “clock” icon, representing the final alarm state for the group.
These apply to the currently selected group, and may change, to reflect the current group’s setting.
Display Type
Tapping on the Display icon, brings up a popover, allowing the user to select the type of Running Timer Display to be used for the group. It is a simple popover, with a segmented switch, and a preview area, under it, showing the display type.
Sounds
Tapping on the sound icon, will bring up a ppopver, allowing the user to choose a final alarm sound, and, optionally, a transition sound (only shown, when there is more than one timer in the group).
This popover is a bit more complex than the Display Popover, as it has a segmented switch, allowing the user to choose the type of alarm to use, at the end of the countdown, an optional picker, for selecting a sound, and, optionally, a second picker, allowing the user to select a transition sound.
TOOLBAR
There’s a toolbar, displayed at the bottom of the screen, that affects the selected timer.
Delete Button (Trash Can Icon)
Selecting this, will bring up a confirmation alert, asking if you really want to delete the timer. If you confirm, the timer is deleted, and the next one is selected.
Play Button (Triangle)
Selecting this, starts the selected timer (goes directly to the Running Timer Screen).
Edit Button (Optional)
This is only displayed, if “One-Tap Edit” is off. Selecting it, opens the Timer Editor Screen for the selected timer.
See moreDeclaration
Swift
@MainActor class RiValT_GroupEditor_ViewController : RiValT_Base_ViewController
extension RiValT_GroupEditor_ViewController: UICollectionViewDragDelegate
extension RiValT_GroupEditor_ViewController: UICollectionViewDropDelegate
extension RiValT_GroupEditor_ViewController: UICollectionViewDelegate
extension RiValT_GroupEditor_ViewController: UIScrollViewDelegate
-
This is a common base class, for the embedded running timers.
See moreDeclaration
Swift
@MainActor class RiValT_RunningTimer_Base_ViewController : RiValT_Base_ViewController
-
This draws the circle that represents elapsed time.
It does this by creating layers, each containing the portion of the timer that represents a threshold.
See moreDeclaration
Swift
@MainActor class RiValT_CirlcleDisplayView : UIView
-
This implements the circular running timer display.
The display is a “donut ring,” that is “eaten away,” in a counterclockwise direction, as the timer progresses.
See moreDeclaration
Swift
@MainActor class RiValT_RunningTimer_Circular_ViewController : RiValT_RunningTimer_Base_ViewController
-
This implements a “wrapper” for the running timer views.
It embeds the timer display (either numerical, circular, or stoplight), and handles the all of the user interaction (the timer embed is read-only).
This view references a timer instance, which, in turn, is also referenced by the embedded views.
See moreDeclaration
Swift
@MainActor class RiValT_RunningTimer_ContainerViewController : UIViewController
extension RiValT_RunningTimer_ContainerViewController: RVS_BasicGCDTimerDelegate
-
This implements the numerical (LED numbers) running timer display.
It draws the LEDs, along with a blur filter (to give the “gas” appearance), and a hex grid layer (to simulate gas fluorescent displays).
See moreDeclaration
Swift
@MainActor class RiValT_RunningTimer_Numerical_ViewController : RiValT_RunningTimer_Base_ViewController
-
This implements the stoplights running timer display.
It displays three round circles, and highlights each one, as that threshold is reached.
See moreDeclaration
Swift
@MainActor class RiValT_RunningTimer_Stoplights_ViewController : RiValT_RunningTimer_Base_ViewController
-
This view controller allows us to set the timer thresholds for each individual timer.
This has a segmented switch, which allows the user to pick which of the thresholds they want to edit. Until a Start Time has been set, the Warning Time and Final time choices are disabled.
Once a Start Time is selected, the Warning Time and Final Time choices become available. They cannot be set equal to, or higher than, the Start Time. The Final Threshold can also not be higher than the Warning Threshold, unless the Warning Threshold is at 00:00:00 (off).
There is also a “Play” triangle, below the time picker. This is disabled, if the Start Time is at 00:00:00, but becomes enabled, once a Start Time has been specified. Selecting this, brings in the Running Timer Screen for the current timer.
See moreDeclaration
Swift
@MainActor class RiValT_EditTimer_ViewController : RiValT_Base_ViewController
extension RiValT_EditTimer_ViewController: UIPickerViewDataSource
extension RiValT_EditTimer_ViewController: UIPickerViewDelegate
extension RiValT_EditTimer_ViewController: UIPickerViewAccessibilityDelegate
-
This class acts as a “wrapper” for an instance of the
RiValT_TimerEditor_PageViewController
class. It also provides a Navigation Item, as well as a toolbar, for selecting amongst multiple timers in a group.If there is only one timer in the group, then the toolbar is not displayed.
If there are more than one timers, the toolbar has numbered squares, representing each timer. Selecting a numbered square, brings that timer into the editor.
This also presents a “Delete” (trashcan) icon in the upper right corner (Navigation Bar). That acts in exactly the same manner as the “Delete” button in the Group Editor Screen. Selecting it, brings up a confirmation alert, and choosing to delete, will dismiss the screen.
See moreDeclaration
Swift
@MainActor class RiValT_TimerEditor_PageViewContainer : RiValT_Base_ViewController
extension RiValT_TimerEditor_PageViewContainer: UIPageViewControllerDataSource
extension RiValT_TimerEditor_PageViewContainer: UIPageViewControllerDelegate
-
This class exists to give the Watch Connectivity a place to work.
See moreDeclaration
Swift
class RiValT_WatchDelegate : NSObject
extension RiValT_WatchDelegate: WCSessionDelegate
-
This class implements the “executable heart” of the timer app.
BASIC OVERVIEW
This is a countdown timer, in seconds. It starts from a “starting” time, and counts down to 0, at which time it starts an alarm.
It is a class, as opposed to a struct, so it can be referenced, and so that it can be easily mutated.
The “granularity” of the timer is seconds. It does not deal with fractions of a second. Callbacks only happen on the second or state transitions, and can occur in any thread.
It has six “modes” of operation:
- ### STOPPED MODE
The timer is “stopped.” It is set to the starting time, and the timer is not running.
- ### COUNTDOWN MODE
This is the basic countdown mode, starting from the “starting time” threshold.
- ### WARNING MODE
This is a threshold, in seconds. Once the coundown reaches this, the timer goes into “warning” mode. This cannot be less than the final threshold (or 0), and cannot be higher than the starting threshold.
- ### FINAL MODE
This is a threshold, in seconds. Once the coundown reaches this, the timer goes into “final” mode. The timer is running. This cannot be less than 0, and cannot be higher than the warning threshold.
- ### ALARM MODE
Once it hits 0, it goes into “alarm” mode. The timer stops running, once this threshold is encountered.
- ### PAUSED MODE
The timer countdown is in one of the above ranges, but has been “paused.” It is not running.
See moreDeclaration
Swift
open class TimerEngine : Codable, Identifiable
-
This contains an entire model of the timer app.
The model consists of groups, which consist of timers. Each timer is a “wrapped”
TimerEngine
instance.This is a class, so it can be referenced.
See moreDeclaration
Swift
class TimerModel : Equatable
extension TimerModel: Sequence
extension TimerModel: CustomDebugStringConvertible
-
This is a group of sequential timers.
The timers are executed in the order of their storage in the
_timers
array.This is a class, so it can be referenced.
See moreDeclaration
Swift
class TimerGroup : Equatable
extension TimerGroup: Hashable
extension TimerGroup: Sequence
extension TimerGroup: CustomDebugStringConvertible
-
This class stores our timer settings as app persistent storage.
See moreDeclaration
Swift
class RiValT_Settings : RVS_PersistentPrefs