(NOTE: Here is a link to a fairly simple page of direct documentation links)
- The RVS_Spinner Popup Spinner Control
- The Bluetooth Abstraction SDK
- The Gradient Mask Button
- The “Booking Calendar” Widget
- The Autofill Text Field Widget
- Persistent Preferences Utility
- The Customizable Checkbox Control
- The “Retro” LED Display Widget
- Basic Grand Central Dispatch Timer
- General-Purpose Observer Infrastructure
- The RVS_Generic_Swift_Toolbox Utilities
- The RVS_UIKit_Toolbox UIKit Tools
- Rift Valley Timer Source Code (Opens a New Tab)
- Blue Van Clef Source Code Documentation (Opens a New Tab)
THE RVS_Spinner POPUP SPINNER CONTROL
This is a special control class that implements a pop-up spinner control.
You can associate an array of values with a Spinner, and they will be presented to the user when they tap the center of the control.
The control will pop up either a fan of values that can be scrolled like a knob, or a UIPickerView.
It is completely self-contained. You only need to instantiate the control, give it a place in the view (just like any other control), and associate a set of values with it.
The values should be accompanied by images.
The operation and appearance of the Spinner are highly customizable, either at runtime, or through IB Inspectable properties.
What Problem Does This Solve?
Mobile devices present difficulties for things like shuttles and pickers. Apple’s UIPickerView is an excellent approach to the problem of dynamic selection, but there are issues.
For one thing, UIPickerViews are BIG. They hog up a lot of precious screen real estate. This is necessary.
Also, they use the DataSource pattern, in which you supply the data at runtime, in a JIT manner. This is an excellent method, but it is rather complex. You sacrifice simplicity for power.
RVS_Spinner is a small icon, until it is touched and expanded. It is also designed to be operated by a thumb.
To make matters easier, it uses a fairly simple Array data provider. Simply associate an Array of structs to the control, and it’s sorted.
Radial Spinner
The way it works, is that the quiescent control is small. By default, it is an oval or circle; possibly with an image or text in it, or just an image.
Tapping on the circle pops up a surrounding ring of images, which can be rotated about the center, like a prize wheel or a knob.
One of the best things about the spinner, is that it does the “deceleration” spinning, where you can get it going quickly, and it decelerates until finally coming to a stop.
This is all incredibly easy to use. Simply drag in the view, using the Storyboard Editor, or create the class programmatically, and associate an Array of values with the control.
The control automatically resizes, based on its container, and takes care of all the basic trig and whatnot that you need to manage the radial display.
This popup is a UIView that is opened in the superview of the center, so the superview must be able to support having a larger view added.
You can prescribe the radius of the popup or UIPickerView at runtime, or in the Interface Builder/Storyboard Editor. The sizes of the images will adjust to fit the circle.
You can control the open Spinner with gestures. It was designed to be thumb-controlled; including a prize wheel spinner, where you can send the control spinning in a decelerating rotation. The top (most visible) value is the one that will be selected. Tapping in a spinning control will stop it. You can also single-tap on either side of the open control to advance (decrement) the control by one.
Picker View Variant
You can also have a standard UIPickerView come up, which may be better for larger numbers of values, or for developers that prefer a more standard Apple User Experience.
Here are the docs for the project. (Opens a New Tab). It, too, is MIT-licensed open source.
It’s ready to be integrated into a project, and the test harness should help to show how its used. It’s really, really easy to use.
Demo Projects
We have prepared two simple demonstration projects:
- This is the Swift Package Manager Demo. It will download a .zip file that will expand into a simple project directory. Read the README.md file.
- This is the Direct Integration Demo. It will download a .zip file that will expand into a simple project directory. Read the README.md file.
The main repo project will also run the test harness, but is a lot more complex.
Also, there are quite a few examples, given in the test harness apps supplied with the library.
The Bluetooth Abstraction SDK
RVS_BlueThoth is a low-level, native Swift Bluetooth SDK for “Central” (Client) Core Bluetooth (BLE) implementation.
It abstracts some of the more “tedious” aspects of using Core Bluetooth; allowing the app to easily implement a Bluetooth Client functionality.
This is the GitHub repo for this project.
This is the project technical documentation
What Problem Does This Solve?
Implementing the Apple Core Bluetooth SDK can be a rather tedious process. For example, discovery of Services, Characteristics, and Descriptors can be intricate and time-consuming. RVS_BlueThoth takes care of that in the “background,” allowing you to concentrate on providing a richer experience to the users of your application or SDK.
Works On All Apple Platforms
RVS_BlueThoth will work on all of the Apple operating systems (iOS/iPadOS, MacOS, tvOS, and WatchOS). It can be incorporated into projects that target any of these environments.
Very Powerful test harnesses have been provided to demonstrate its use on each platform (iOS/iPadOS, MacOS, tvOS, and WatchOS). In fact, the iOS test harness has actually been converted into a released app on the iOS App Store (here is the source code).
The “Booking Calendar” Widget
RVS_CalendarInput is a customized UIView implementation, that will display a basic month/grid calendar, with active buttons, on selected dates.
The workflow may be familiar to people that have used Web-based “booking” systems. A date grid is presented, in calendar form, with certain dates highlighted as toggle buttons. The user can select these dates.
What Problem Does This Solve?
Unlike some of the other open-source widgets that we’ve produced, this widget is being designed for a single application and workflow, so it will be less “general purpose” than other Great Rift Valley Software Company widgets.
In our application, we are adding a workflow, that allows the user of the app to declare that they will be attending events on certain dates. This widget is how they will do that.
Here are the docs for that project (Opens a New Tab). It, too, is MIT-licensed open source.
Here is the GitHub repo for the project.
The Gradient Mask Button
A Special UIButton Variant That Allows “See-Through” Masking.
This class implements an extremely basic UIButton
-subclassed button (so it can be used in place of UIButton) that provides a gradient background, and the ability to either mask it inside of text (you can use whetever font you want), or inside of a template image, or, alternatively, to fill the button with the gradient, and “punch out” the text and/or image. The gradient is a basic linear gradient between two colors, and the angle of the gradient can be changed. If just one color is defined, then the fill is a solid color.
What Problem Does This Solve?
This class was designed for a specific use case, in a larger application. We wanted to have a large, banner-style button, using a particular font, that was filled with a gradient.
The text in the button would change, to reflect an application status, so an image was out of the question. This makes it absurdly simple to have a gradient-based text or template image display, with a transparent background.
Here are the docs for the project. (Opens a New Tab). It, too, is MIT-licensed open source.
Here is the GitHub repo for the project.
The Autofill Text Field Widget
This is a standard UITextField that has been extended, to allow an “autocomplete” menu to appear, under it.
What Problem Does This Solve?
Entering text on phones isn’t easy. This helps to reduce the amount of text we actually need to enter.
Additionally, this can help us to “explore” datasets, by entering partial specifications. For example, if we are searching for users in a certain area, we might do a “triage” search, and create a subset of the main database of users, for the locality. These can be used as autofill suggestions, when looking for a user.
This is, by default, a simple, “one-way,” “greedy” match. It starts from the beginning, then moves forward, matching the characters entered into the text field. They must all match, but the match can be case/diacritical-independent (by default).
We can choose several modes of matching, so we can “wildcard” text before and/or after the string (or insist on an exact match).
The widget has been designed to allow a lot of customization, as well as a very simple way to provide the data to be searched. It also has the ability to be modified for more advanced data searching.
The user must actually select a table row. There is no “tab” autofill. This is for things like phones, where that doesn’t really make sense, and the application may have other plans for the return function.
Here are the docs for that project (Opens a New Tab). It, too, is MIT-licensed open source.
Here is the GitHub repo for the project.
Persistent Preferences Utility
This is a very useful utility class for keeping a persistent state in place for any Apple app.
What Problem Does This Solve?
Storing persistent data (data that survives an app being started and stopped, or even, in some cases, transfers between apps) has always been a somewhat fraught process in app development.
Luckily, Apple has provided an excellent mechanism for this, called UserDefaults
, which is part of the Foundation framework; meaning that it is supported by ALL Apple operating systems.
Saving and retrieving from UserDefaults
is quite simple. You save and retrieve values in the same manner as you would a String
-keyed Dictionary
.
In fact, the project includes multiple full-quality (but small) test harnesses for iOS, macOS, tvOS and watchOS (combined with the iOS test harness).
This class allows you to have an implicit global state that is accessed by simply instantiating a subclass, and you can associate top-level keys to instances, to maintain multiple sets of persistent preferences.
Here are the docs for that project (Opens a New Tab). It, too, is MIT-licensed open source.
This is the GitHub repo for the project.
The Customizable Checkbox Control
This is a simple, robust, and powerful “drop-in” replacement for the classic iOS UISwitch.
What Problem Does This Solve?
The UISwitch user interface element is an excellent tool, but has some limitations. It is big, has limited customizability, is horizontally-oriented, and affords a “swipe” gesture, even though it actually wants a “tap” gesture.
It is also strictly “two-state.” There’s no “indeterminate” state, like on the Mac.
This class brings in a fundamental “tappable” checkbox, like the Mac, but with the ability to customize.
It also allows a “three-state” operation.
Here are the docs for that project (Opens a New Tab). It, too, is MIT-licensed open source.
This is the GitHub repo for the project.
The “Retro” LED Display Widget
What Problem Does This Solve?
This widget was designed specifically for the rewrite of The Rift Valley Timer App. That app presents a classic “Vacuum Fluorescent”-style display.
This is similar to the RVS_MaskButton Project, but is designed to display ONLY an “LED Display.” It is more customizable than RVS_MaskButton, but not in the font being used.
Here are the docs for that project (Opens a New Tab). It, too, is MIT-licensed open source.
This is the GitHub repo for the project.
Basic Grand Central Dispatch Timer
This is a fundamental tool: A simple Grand Central Dispatch timer that either fires repeatedly, or only once.
What Problem Does This Solve?
Timers are necessary for many different reasons. They could be the driving engine of a clock app, or a UI tool to refresh a display or close a screen. This will allow leeway, which Apple suggests as a way to help reduce energy usage, and is thread-independent. You can instantiate it on any queue that you want. It’s incredibly simple. Just a set and forget, if you are firing just once, or a simple repeating callback.
Here are the docs for that project (Opens a New Tab). It, too, is MIT-licensed open source.
This is the GitHub repo for the project.
General-Purpose Observer Infrastructure
This is a simple protocol-based tool that provides a very fundamental infrastructure for implementing OBSERVER pattern functionality in your project.
What Problem Does This Solve?
At its heart, any observer implementation is really just a relationship graph. Observers subscribe to Observables. Observables use the subscription as a one-way broadcast medium.
Managing the subscriptions and relationships is absolutely fundamental to the pattern. If we can’t trust our subscription list, then everything built upon it is at risk.
Here is the GitHub repo for the project.
The RVS_Generic_Swift_Toolbox Utilities
This is a set of various and sundry tools that are designed to work with all Apple platforms (iOS, iPadOS, WatchOS, MacOS, and TVOS).
What Problem Does This Solve?
Every project is built on a set of fundamental, simple, tools that are usually reused.
These tools were factored out of multiple projects, and added to a single repo, in order to ensure that they can be tested, documented, and subjected to version control.
Here are the docs for that project (Opens a New Tab). It, too, is MIT-licensed open source.
Here is the GitHub Repo for the Tools.
The RVS_UIKit_Toolbox Utilities
This is a set of various extensions to basic UIKit fundamental classes. These extensions make it easier to develop robust, usable, and accessible iOS/iPadOS applications.
What Problem Does This Solve?
This allows us to have a number of flags, and “quick utility” methods at our disposal, obviating various repetitive and/or complicated tasks.
Here are the docs for that project (Opens a New Tab). It, too, is MIT-licensed open source.