MainScreenViewController
class MainScreenViewController : UIViewController, UIPickerViewDelegate, UIPickerViewDataSource, TheBestClockAlarmViewDelegate
extension MainScreenViewController: RVS_BasicGCDTimerDelegate
The entire app is basically handled by this one big fat View Controller. The idea is that users don’t leave the context to do their settings.
There are two “screens” that appear: The Appearance Editor (font, color), and the Alarm Editor (alarm time, activation, sound). These are actually hidden screens that appear over the main display screen.
Yeah, it’s a big ugly mess. Read the README to find out why the app is configured this way.
-
This is a list of a subset of fonts likely to be on the device. We want to reduce the choices for the user.
Declaration
Swift
let screenForThese: [String]
-
This is the base font size for the ante meridian label near the top of the screen.
Declaration
Swift
let amPmLabelFontSize: CGFloat
-
This is the base font size for the date display along the top.
Declaration
Swift
let dateLabelFontSize: CGFloat
-
This is the base font size for the row of alarm buttons along the bottom of the screen.
Declaration
Swift
let alarmsFontSize: CGFloat
-
This is the base font size for the various textual items in the Alarm Editor.
Declaration
Swift
let alarmEditorTopFontSize: CGFloat
-
This is the font size for the alarm sound/music selection picker.
Declaration
Swift
let alarmEditorSoundPickerFontSize: CGFloat
-
This is the base font size for the sound test button.
Declaration
Swift
let alarmEditorSoundButtonFontSize: CGFloat
-
The time interval
Declaration
Swift
let timeIntervalInSeconds: TimeInterval
-
The leeway, in milliseconds
Declaration
Swift
let leewayInMilliseconds: Int
-
This is the UIPickerView that is used to select the font.
Declaration
Swift
@IBOutlet weak var fontDisplayPickerView: UIPickerView!
-
This is the UIPickerView that is used to select the color.
Declaration
Swift
@IBOutlet weak var colorDisplayPickerView: UIPickerView!
-
This is the main view, holding the standard display items.
Declaration
Swift
@IBOutlet weak var mainNumberDisplayView: UIView!
-
This is a normally hidden view that holds the color and font selection UIPickerViews
Declaration
Swift
@IBOutlet weak var mainPickerContainerView: UIView!
-
This is the hidden slider for changing the brightness on the left side of the screen..
Declaration
Swift
@IBOutlet weak var leftBrightnessSlider: TheBestClockVerticalBrightnessSliderView!
-
This is the hidden slider for changing the brightness on the right side of the screen..
Declaration
Swift
@IBOutlet weak var rightBrightnessSlider: TheBestClockVerticalBrightnessSliderView!
-
This is the label that displays ante meridian (AM/PM).
Declaration
Swift
@IBOutlet weak var amPmLabel: UILabel!
-
This is the label that displays today’s date.
Declaration
Swift
@IBOutlet weak var dateDisplayLabel: UILabel!
-
This view will hold our alarm displays.
Declaration
Swift
@IBOutlet weak var alarmContainerView: UIView!
-
This is a view that will cover the screen if the user wants to edit an alarm.
Declaration
Swift
@IBOutlet weak var editAlarmScreenContainer: UIView!
-
This is the date picker in the alarm time editor.
Declaration
Swift
@IBOutlet weak var editAlarmTimeDatePicker: UIDatePicker!
-
This will be the container for the flashing view that appears when there’s an alarm.
Declaration
Swift
@IBOutlet weak var alarmDisplayView: UIView!
-
This is the view that will actually display the flashes.
Declaration
Swift
@IBOutlet weak var flasherView: UIView!
-
This is the “invisible” button that we use to dismiss the alarm editor.
Declaration
Swift
@IBOutlet weak var dismissAlarmEditorButton: UIButton!
-
This is a “partial mask” view for our alarm editor screen.
Declaration
Swift
@IBOutlet weak var editAlarmScreenMaskView: UIView!
-
This is the little “more info” button that is displayed at the bottom of the setup screen.
Declaration
Swift
@IBOutlet weak var infoButton: UIButton!
-
This switch will denote the “active” state of the alarm.
Declaration
Swift
@IBOutlet weak var alarmEditorActiveSwitch: UISwitch!
-
This is the localized label for that switch, but we make it a button, so it can be used to trigger the switch.
Declaration
Swift
@IBOutlet weak var alarmEditorActiveButton: UIButton!
-
This is the switch that selects whether or not to use a vibration (on supported devices).
Declaration
Swift
@IBOutlet weak var alarmEditorVibrateBeepSwitch: UISwitch!
-
This is the localized label for that switch, but we make it a button, so it can be used to trigger the switch.
Declaration
Swift
@IBOutlet weak var alarmEditorVibrateButton: UIButton!
-
This is the segmented switch that selects the type of sounds we’ll use.
Declaration
Swift
@IBOutlet weak var alarmEditSoundModeSelector: UISegmentedControl!
-
This is the picker view we use to select playback sounds for the alarm.
Declaration
Swift
@IBOutlet weak var editAlarmPickerView: UIPickerView!
-
This is the button that is pressed to test the sounds.
Declaration
Swift
@IBOutlet weak var editAlarmTestSoundButton: TheBestClockSpeakerButton!
-
This is the “STOP” long press gesture recognizer.
Declaration
Swift
@IBOutlet var shutUpAlreadyLongPressGestureRecognizer: UILongPressGestureRecognizer!
-
This is the “STOP” double-tap gesture recognizer.
Declaration
Swift
@IBOutlet var shutUpAlreadyDoubleTapRecognizer: UITapGestureRecognizer!
-
This is the “snooze” tap gesture recognizer.
Declaration
Swift
@IBOutlet var snoozeGestureRecogninzer: UITapGestureRecognizer!
-
This is a view that we temorarily put up while fetching the music collection.
Declaration
Swift
@IBOutlet weak var musicLookupThrobberView: UIView!
-
This is the throbber in that view.
Declaration
Swift
@IBOutlet weak var musicLookupThrobber: UIActivityIndicatorView!
-
This is the secondary picker view for selecting songs in the Alarm Editor.
Declaration
Swift
@IBOutlet weak var songSelectionPickerView: UIPickerView!
-
This is a special view that we use to mask the entire screen for initial music load.
Declaration
Swift
@IBOutlet weak var wholeScreenThrobberView: UIView!
-
This is the throbber in that screen.
Declaration
Swift
@IBOutlet weak var wholeScreenThrobber: UIActivityIndicatorView!
-
This is the view that holds the test song button.
Declaration
Swift
@IBOutlet weak var musicTestButtonView: UIView!
-
This is the test song button.
Declaration
Swift
@IBOutlet weak var musicTestButton: TheBestClockSpeakerButton!
-
This is a container view for the main edit alarm picker (Sounds and Artists).
Declaration
Swift
@IBOutlet weak var editPickerContainerView: UIView!
-
Thi is a container for the secondary music picker (songs)
Declaration
Swift
@IBOutlet weak var songSelectContainerView: UIView!
-
This is a container for the test sound button.
Declaration
Swift
@IBOutlet weak var testSoundContainerView: UIView!
-
This view is displayed when there is no music available.
Declaration
Swift
@IBOutlet weak var noMusicDisplayView: UIView!
-
This is the label that specifies that there is no music available.
Declaration
Swift
@IBOutlet weak var noMusicAvailableLabel: UILabel!
-
This label tells the user that the alarm will not go off until next time.
Declaration
Swift
@IBOutlet weak var alarmDeactivatedLabel: UILabel!
-
This is a transparent view that allows gesture recognizers to disable the alarm.
Declaration
Swift
@IBOutlet weak var alarmDisableScreenView: UIView!
-
This is the label that is displayed while the music is being looked up.
Declaration
Swift
@IBOutlet weak var musicLookupLabel: UILabel!
-
This is set to true if an alarm goes off. We then check it to see if we need to stop a playing audio loop when the alarm ends. Otherwise, we could keep playing forever.
Declaration
Swift
var alarmSounded: Bool
-
These are the persistent prefs that store our settings.
Declaration
Swift
var prefs: TheBestClockPrefs!
-
If the Alarm Editor is open, then this is the index of the alarm being edited. It is -1 if the Alarm Editor is not open.
Declaration
Swift
var currentlyEditingAlarmIndex: Int
-
This is the currently selected main font. It’s an index into our font selection Array.
Declaration
Swift
var selectedFontIndex: Int
-
This is an index into our color selection Array, denoting the color we have selected.
Declaration
Swift
var selectedColorIndex: Int
-
This indicates the brightness level of the screen.
Declaration
Swift
var selectedBrightness: CGFloat
-
This is an Array of the button objects that we generated for the alarms along the bottom of the screen.
Declaration
Swift
var alarmButtons: [TheBestClockAlarmView]
-
These are the names of the fonts that we have selected to be choices.
Declaration
Swift
var fontSelection: [String]
-
These are all the UIColors that we have to choose from. They are dynamically generated.
Declaration
Swift
var colorSelection: [UIColor]
-
These are URL Strings of the various sound files we have for the “sounds” setting.
Declaration
Swift
var soundSelection: [String]
-
This is the basic background color for the whole kit and kaboodle. It gets darker as the brightness is reduced.
Declaration
Swift
var backgroundColor: UIColor
-
This is the “heartbeat” of the clock. It’s a 1-second repeating timer.
Declaration
Swift
var timer: RVS_BasicGCDTimer!
-
This is used to cache the selected main font size. We sort of use it as a semaphore.
Declaration
Swift
var fontSizeCache: CGFloat
-
This contains information about music items.
Declaration
Swift
var songs: [String : [SongInfo]]
-
This is an index of the keys (artists) for the songs Dictionary.
Declaration
Swift
var artists: [String]
-
This is the narrowest that a screen can be to properly accommodate an Alarm Editor. Under this, and we need to force portrait mode.
Declaration
Swift
var alarmEditorMinimumHeight: CGFloat
-
This is a simple semaphore to indicate that we are in the process of loading music.
Declaration
Swift
var isLoadin: Bool
-
This records the number of snoozes. We use this if we don’t have “forever snooze” on.
Declaration
Swift
var snoozeCount: Int
-
This will provide haptic/audio feedback for opening and closing the editors, and for ending alarms.
Declaration
Swift
var impactFeedbackGenerator: UIImpactFeedbackGenerator?
-
This will provide haptic/audio feedback for selection “ticks.”
Declaration
Swift
var selectionFeedbackGenerator: UISelectionFeedbackGenerator?
-
This will be the audio player that we use to play the alarm sound.
Declaration
Swift
var audioPlayer: AVAudioPlayer? { get set }
-
Declaration
Swift
override var prefersHomeIndicatorAutoHidden: Bool { get }
-
This calculates all the time and date information when it is called.
Declaration
Swift
var currentTimeString: TimeDateContainer { get }
-
Declaration
Swift
var selectedColor: UIColor { get }
-
Declaration
Swift
var selectedFontName: String { get }
-
There can only be one…
Declaration
Swift
func numberOfComponents(in inPickerView: UIPickerView) -> Int
Parameters
in
The UIPickerView being queried.
Return Value
1 (all the time)
-
This simply returns the number of rows in the pickerview. It will switch on which picker is calling it.
Declaration
Swift
func pickerView(_ inPickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int
Parameters
inPickerView
The UIPickerView being queried.
-
This will send the proper height for the picker row. The color picker is small squares.
Declaration
Swift
func pickerView(_ inPickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat
Parameters
inPickerView
The UIPickerView being queried.
-
This generates one row’s content, depending on which picker is being specified.
Declaration
Swift
func pickerView(_ inPickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing inView: UIView?) -> UIView
Parameters
inPickerView
The UIPickerView being queried.
-
This is called when a picker row is selected, and sets the value for that picker.
Declaration
Swift
func pickerView(_ inPickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int)
Parameters
inPickerView
The UIPickerView being queried.
-
This is called when we want to access the music library to make a list of artists and songs.
Declaration
Swift
func loadMediaLibrary(displayWholeScreenThrobber inDisplayWholeScreenThrobber: Bool = false, forceReload inForceReload: Bool = false)
Parameters
displayWholeScreenThrobber
If true (default is false), then the “big” throbber screen will show while this is loading.
forceReload
If true (default is false), then the entire music library will be reloaded, even if we already have it.
-
This loads the music, assuming that we have been authorized.
Declaration
Swift
func loadUpOnMusic()
-
This is called after the music has been loaded. It sets up the Alarm Editor.
Declaration
Swift
func dunLoadin()
-
This reads all the user’s music, and sorts it into a couple of bins for us to reference later.
Declaration
Swift
func loadSongData(_ inSongs: [MPMediaItemCollection])
Parameters
inSongs
The list of songs we read in, as media items.
-
This is called to play a sound, choosing from the various alarms. That alarm’s indexed sound will be used.
Declaration
Swift
func playSound(_ inAlarmIndex: Int)
Parameters
inAlarmIndex
This is the index of the alarm that we want to use to play the sound.
-
This plays any sound, using a given URL.
Declaration
Swift
func playThisSound(_ inSoundURL: URL)
Parameters
inSoundURL
This is the URI to the sound resource.
-
If the audio player is going, this pauses it. Nothing happens if no audio player is going.
Declaration
Swift
func pauseAudioPlayer()
-
This terminates the audio player. Nothing happens if no audio player is going.
Declaration
Swift
func stopAudioPlayer()
-
This opens the editor screen for a selected alarm.
Declaration
Swift
func openAlarmEditorScreen()
-
Declaration
Swift
func showHideItems()
-
Declaration
Swift
func showLookupThrobber()
-
Declaration
Swift
func hideLookupThrobber()
-
Declaration
Swift
func selectSong()
-
Declaration
Swift
func showOnlyThisAlarm(_ inIndex: Int)
-
Declaration
Swift
func refreshAlarm(_ inIndex: Int)
-
Declaration
Swift
func showAllAlarms()
-
Declaration
Swift
func findSongInfo(_ inURL: String = "") -> (artistIndex: Int, songIndex: Int)
-
Declaration
Swift
func findSongURL(artistIndex: Int, songIndex: Int) -> String
-
Declaration
Swift
func setupAlarmEditPickers()
-
Declaration
Swift
@IBAction func soundModeChanged(_ sender: UISegmentedControl)
-
Declaration
Swift
@IBAction func activeSwitchChanged(_ inSwitch: UISwitch)
-
Declaration
Swift
@IBAction func activeButtonHit(_ sender: Any)
-
Declaration
Swift
@IBAction func vibrateSwitchChanged(_ inSwitch: UISwitch)
-
Declaration
Swift
@IBAction func vibrateButtonHit(_ sender: Any)
-
Declaration
Swift
@IBAction func testSoundButtonHit(_ inSender: TheBestClockSpeakerButton)
-
Declaration
Swift
@IBAction func testSongButtonHit(_ inSender: TheBestClockSpeakerButton)
-
Declaration
Swift
@IBAction func alarmTimeDatePickerChanged(_ inDatePicker: UIDatePicker)
-
This closes the alarm editor screen, making sure that everything is put back where it belongs.
Declaration
Swift
@IBAction func closeAlarmEditorScreen(_ sender: Any! = nil)
-
Declaration
Swift
func showLargeLookupThrobber()
-
Declaration
Swift
func hideLargeLookupThrobber()
-
This creates the display, as a gradient-filled font.
Declaration
Swift
func createDisplayView(_ inContainerView: UIView, index inIndex: Int) -> UIView
-
This sets (or clears) the ante meridian label. We use a solid bright text color.
Declaration
Swift
func setAMPMLabel()
-
This sets the date label. We use a solid bright text color.
Declaration
Swift
func setDateDisplayLabel()
-
This creates and links up the row of buttons along the bottom of the screen.
Declaration
Swift
func setUpAlarms()
-
This updates the alarm buttons to reflect the brightness, color and font.
Declaration
Swift
func updateAlarms()
-
This adds a single new alarm button to the bottom strip.
We use this, so the buttons get autolayout constraints.
Declaration
Swift
func addAlarmView(_ inSubView: TheBestClockAlarmView, percentage inPercentage: CGFloat, previousView inPreviousView: TheBestClockAlarmView!)
Parameters
inSubView
The button to add.
percentage
The width, as a percentage (0 -> 1.0) of the total strip width, of the subview.
previousView
If there was a view to the left, this is it.
-
This scans the alarms, and looks for anyone that wants to ring their bell.
Declaration
Swift
func checkAlarmStatus(soundOnly: Bool = false)
Parameters
soundOnly
If true (default is false), then this will not flash the display, and will only trigger the sound.
-
This plays whatever alarm is supposed to be alarming. This will vibrate, if we are set to do that.
Declaration
Swift
func aooGah(_ inIndex: Int)
Parameters
inIndex
This is the index of the alarm to be played.
-
This flashes the display in a fading animation.
Declaration
Swift
func flashDisplay(_ inUIColor: UIColor)
Parameters
inUIColor
This is the color to flash.
-
This starts our regular 1-second ticker.
Declaration
Swift
func startTicker()
-
This stops our regular 1-second ticker.
Declaration
Swift
func stopTicker()
-
This simply redraws the main time and the two adjacent labels.
Declaration
Swift
func updateMainTime()
-
This is called from the timer.
Declaration
Swift
func checkTicker()
-
This is called at load time, to add the various localized accessibility labels and hints to our elements on the main display screen.
Declaration
Swift
func setUpMainScreenAccessibility()
-
This is called at load time, to add the various localized accessibility labels and hints to our elements in the Appearance Editor screen.
Declaration
Swift
func setUpAppearanceEditorAccessibility()
-
This is called at load time, to add the various localized accessibility labels and hints to our elements in the Alarm Editor screen.
Declaration
Swift
func setUpAlarmEditorAccessibility()
-
This is called to update the color of the “info” button in the Appearance Editor.
Declaration
Swift
func setInfoButtonColor()
-
This is called when the app is reactivated.
It resets all the “deactivations” snoozes.
Declaration
Swift
func turnOffDeactivations()
-
This is called when the user taps in an alarm active screen.
Declaration
Swift
@IBAction func hitTheSnooze(_: UITapGestureRecognizer)
-
This is called when the user long-presses in an alarm active screen.
Declaration
Swift
@IBAction func shutUpAlready(_: Any! = nil)
-
This is called when the user taps in an alarm on the main screen, toggling it.
Declaration
Swift
@IBAction func alarmActiveStateChanged(_ inSender: TheBestClockAlarmView)
Parameters
inSender
The alarm button that was hit.
-
This is called when a brightness slider is changed.
Declaration
Swift
@IBAction func brightnessSliderChanged(_ inSlider: TheBestClockVerticalBrightnessSliderView! = nil)
Parameters
inSlider
The brightness slider being manipulated.
-
This is called when a slider opens, so we don’t have the situation where both are open at once.
Declaration
Swift
@IBAction func brightnessSliderOpened(_ inSlider: TheBestClockVerticalBrightnessSliderView)
Parameters
inSlider
The slider object that called this
-
This is called when an open slider closes. We re-enable both sliders.
Declaration
Swift
@IBAction func brightnessSliderClosed(_: Any)
-
This is called when we first open the Appearance (font and color) Editor.
Declaration
Swift
@IBAction func openAppearanceEditor(_: Any)
-
This is called when the user taps in the info button.
Declaration
Swift
@IBAction func openInfo(_: Any)
-
This is called to close the Appearance Editor.
Declaration
Swift
@IBAction func closeAppearanceEditor(_: Any)
-
Declaration
Swift
func setProperScreenBrightness()
-
This is called when the resources and storyboard are all loaded up for the first time. We use this to initialize most of our settings.
Declaration
Swift
override func viewDidLoad()
-
This is called when we are about to layout our views (like when we rotate). We redraw everything, and force a new font size setting by zeroing the “cache.”
Declaration
Swift
override func viewDidLayoutSubviews()
-
This is called when the view is about to appear. We make sure that we redraw everything with a zeroed cache, and start the “don’t sleep” thingy. We also start a one-second timer.
Declaration
Swift
override func viewWillAppear(_ animated: Bool)
-
When the view will disappear, we stop the caffiene drip, and the timer.
Declaration
Swift
override func viewWillDisappear(_ animated: Bool)
-
When the view will disappear, we stop the caffiene drip, and the timer.
Declaration
Swift
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
-
This is called to open the Alarm Editor for an indexed alarm.
Declaration
Swift
func openAlarmEditor(_ inAlarmIndex: Int)
Parameters
inAlarmIndex
0-2. The index of the alarm to be edited.
-
This is the callback that is made by the repeating timer.
Declaration
Swift
func basicGCDTimerCallback(_: RVS_BasicGCDTimer)