This repo collects in one place references to all my open-source contributions to development in Swift and for Apple platforms.
SwiftUI (top)
(2020)-(SwiftUI) TimingCurves (top)
TimingCurves is a complete app (iOS 13 and above) useful to developers and designers alike who want to explore different animation timing curves. It supports both iPhones (in portrait mode only) and iPads (in any interface orientation) and works in both light and dark color schemes.
SwiftUI (top)
(2020)-(SwiftUI) Animated Tab Bar and Animated Tab Bar 2 (top)
I came across a YouTube video of someone explaining how to create an animated tab bar. The final result is really nice but the code is... well, hacky as hacky can be. It lacks structure, it's full of duplicated code, has lots of index-juggling, and calls to DispatchQueue.main.async()
to avoid changing the view's state while it's being rendered by SwiftUI. In summary, it's the sort of hack that is unacceptable in a professional setting.
So, I decided to give it a go and try to replicate the effect using well-written code that is easy to read and reasonably easy to understand and maintain.
My first goal was to get a simple animation of tab selection. The result (Animated Tab Bar) is shown in the first animation below.
I then wanted to do something a bit fancier, and that's the second animation (Animated Tab Bar 2). It doesn't replicate the YouTube video's result exactly but the differences are minor and easily fixable. Basically, I would have to use a shape other than a Circle
and animate its motion vertically as well as horizontally.
General-purpose libraries (top)
(2024)-(Foundation / Graphics) SwiftCMasher (top)
SwiftCMasher is an SPM library for any platform that supports Swift, providing a port of the excellent CMasher color maps. Those are color maps particularly suitable for conveying scientific data in an accurate and visually pleasing fashion.
dark mode | light mode |
---|---|
(2020)-(Graphics / SwiftUI) AcceleratedCGPoints (top)
AcceleratedCGPoints is a Swift Package Manager library for iOS/tvOS (13.0 and above), watchOS (6.0 and above), and macOS (10.15 and above), under Swift 5.2 and above, providing
-
a conformance of
CGPoint
toAdditiveArithmetic
, to support direct arithmetic operations on points -
a conformance of
CGPoint
toVectorArithmetic
, to support multiplication of points by scalars -
an extension of
CGPoint
, adding some convenience functions to go along with the conformance toVectorArithmetic
-
another extension of
CGPoint
, adding support for creating uniformly-distributed pseudo-random points -
extensions to
Array
, to support accelerated arithmetic on largeCGPoint
arrays, using Apple'sAccelerate
framework
(2020)-(Math) CubicLookupTable (top)
CubicLookupTable is a Swift Package Manager package for iOS/tvOS (10.0 and above), watchOS (4.0 and above), and macOS (10.14 and above), under Swift 5.0 and above, that efficiently implements a generic (in the Swift sense) cubic-interpolated and dynamically-sampled look-up table: given a function f(x)
and its derivative f'(x)
, a table is built that stores values of x
, f(x)
, and f'(x)
at specific points in some interval [a,b]
provided by the client code. The derivative is necessary to dynamically determine where to sample f(x)
for maximum efficiency and accuracy.
For a linearly-interpolated version of this package, head to LinearLookupTable.
Which one should you choose to use? That depends entirely on your needs. The main advantage of a linearly-interpolated table is that it's cheaper, both computationally and memory-wise, than a cubic-interpolated table but it's also less accurate for the same table size. Also, linear interpolation does not preserve the continuity of the interpolated function's derivative. If that's important to you, you should use a cubic-interpolated table.
As a useful example in itself, the package also provides the CubicTrigTable
type, which implements look-up tables for both sin(x)
and cos(x)
.
Lastly, for a mathematical description of the details involved in building these tables, you may want to take a look at Designing and building efficient look-up tables.
(2020)-(Math) LinearLookupTable (top)
LinearLookupTable is a Swift Package Manager package for iOS/tvOS (10.0 and above), watchOS (4.0 and above), and macOS (10.14 and above), under Swift 5.0 and above, that efficiently implements a generic (in the Swift sense) linearly-interpolated and dynamically-sampled look-up table: given a function f(x)
and its derivative f'(x)
, a table is built that stores values of x
and f(x)
at specific points in some interval [a,b]
provided by the client code. The derivative is necessary to dynamically determine where to sample f(x)
for maximum efficiency and accuracy.
For a cubic-interpolated version of this package, head to CubicLookupTable.
Which one should you choose to use? That depends entirely on your needs. The main advantage of a linearly-interpolated table is that it's cheaper, both computationally and memory-wise, than a cubic-interpolated table but it's also less accurate for the same table size. Also, linear interpolation does not preserve the continuity of the interpolated function's derivative. If that's important to you, you should use a cubic-interpolated table.
As a useful example in itself, the package also provides the LinearTrigTable
type, which implements look-up tables for both sin(x)
and cos(x)
.
Lastly, for a mathematical description of the details involved in building these tables, you may want to take a look at Designing and building efficient look-up tables.
(2020)-(Foundation) RandomAccessCollectionBinarySearch (top)
RandomAccessCollectionBinarySearch is a Swift Package Manager package for iOS/tvOS (10.0 and above), watchOS (4.0 and above), and macOS (10.14 and above), under Swift 5.0 and above, implementing an extension to RandomAccessCollection
to add support for performing binary searches on sorted collections.
In particular, in addition to the "normal" binary search, the package provides a version that also returns the indices of the values "bracketing" the value being searched for, with sensible results in all possible situations.
(2020)-(UI) TabularView and TabularViewDemo (top)
TabularView is a Swift package for iOS/iPadOS (13.0 and above) to display tabular data in a view, in a manner similar to how UICollectionView
can display unidimensional data in a grid.
The package supports multiple columns, each with their own optional header and optional footer, indexed by an enumeration type, that you define, rather than an integer, so your code is clearer about which column or columns it refers to. There's also built-in support for sorting rows by a selected column.
The design philosophy is inspired heavily by how UICollectionView
works. There are separate data source and delegate protocols (in fact, two delegate protocols, one for layout and another for sorting), and the data source is managed using the new (as of 2019) UICollectionView
Diffable Data Source API.
BiasedDie is a Swift package for iOS/tvOS (10.0 and above), watchOS (4.0 and above), and macOS (10.14 and above), under Swift 5.0 and above, defining a generator of pseudo-random numbers based on a discrete distribution of probabilities.
In less formal terms, imagine that you have a die with N
faces and that each face has a potentially different probability of being landed on than other faces. In other words, the k
-th face has a probablity pk
of being landed on, for 1 ≤ k ≤ N
. Of course, the sum of all of these probabilities must equal 1. This is referred to as a biased die. Now imagine that you throw this biased die many times, recording each time the number of the face the die lands on. This package lets you generate a sequence of such numbers as if you had actually thrown such a die, and does so as efficiently as possible, using a method known as the alias method. An excellent exposition of this method can be found here.
The package lets you initialise the biased die in multiple ways, depending on the kind of data you have or want to produce.
(2019)-(Math) Combinatorics (top)
Combinatorics is a Swift package for iOS/tvOS (10.0 and above), watchOS (4.0 and above), and macOS (10.14 and above), under Swift 5.0 and above, defining functions to efficiently compute permutations and combinations of given elements, as well as factorials and binomial coefficients.
(2024) Please note that some of the functionality provided by this library is now available in Apple's Swift Algorithms package.
(2019)-(Math) NumberTheory (top)
NumberTheory is a Swift package for iOS/tvOS (10.0 and above), watchOS (4.0 and above), and macOS (10.14 and above), under Swift 5.0 and above, defining a few simple functions to perform common number-theoretic operations, such as gcd and lcm.
(2024) Please note that some of the functionality provided by this library is now available in Apple's Swift Numerics package.
(2019)-(Foundation / Math) ArrayTransposition (top)
ArrayTransposition is a Swift package for iOS/tvOS (10.0 and above), watchOS (4.0 and above), and macOS (10.14 and above), under Swift 5.0 and above, adding an extension to Array
to allow the computation of matrix transpositions.
(2019)-(Foundation) StringFormatting (top)
StringFormatting is a Swift package for iOS/tvOS (10.0 and above), watchOS (4.0 and above), and macOS (10.14 and above), under Swift 5.0 and above, defining some useful functions for formatting strings.
(2019)-(Foundation) BinaryIntegerFormatting (top)
BinaryIntegerFormatting is a Swift package for iOS/tvOS (10.0 and above), watchOS (4.0 and above), and macOS (10.14 and above), under Swift 5.0 and above, defining some useful functions for formatting integers.
Ordinarily, one should use NumberFormatter
to format numbers but I've found use cases where this package has been more useful, especially when localisation isn't an issue.
(2019)-(Foundation | Experimental) NumericScalar (top)
NumericScalar is a Swift package for iOS/tvOS (10.0 and above), watchOS (4.0 and above), and macOS (10.14 and above), under Swift 5.0 and above, defining two protocols, NumericScalar
and ValueConvertibleNumericScalar
.
NumericScalar
adds a number of useful static computed properties that allow for the identification of a numeric type in terms of its explicit type. This is useful in generic algorithms that, nonetheless, sometimes need to behave differently depending on the specific numeric type at hand.
ValueConvertibleNumericScalar
adds a function to convert an instance of a type conforming to NumericScalar
into another. This is easier to use and more uniform than trying to figure out which initialiser to use in any particular case.
Note: This is an experimental package.
(2019)-(Foundation) CollectionSplitting (top)
CollectionSplitting is a Swift package for iOS/tvOS (10.0 and above), watchOS (4.0 and above), and macOS (10.14 and above), under Swift 5.0 and above, adding an extension to Collection
in order to define a function that splits the collection into an array of sub-sequences of equal length.
(2019)-(Foundation) CollectionDuplicateRemoval (top)
CollectionDuplicateRemoval is a Swift package for iOS/tvOS (10.0 and above), watchOS (4.0 and above), and macOS (10.14 and above), under Swift 5.0 and above, adding protocol extensions to Collection
in order to define a function that returns an array of the elements of the collection, with duplicates removed.
(2019)-(Foundation) CollectionComparable (top)
CollectionComparable is a Swift package for iOS/tvOS (10.0 and above), watchOS (4.0 and above), and macOS (10.14 and above), under Swift 5.0 and above, adding a protocol extension to Collection
so that it's Comparable
when its Element
type is Comparable
.
(2019)-(Foundation) CollectionConvenience (top)
CollectionConvenience is a Swift package for iOS/tvOS (10.0 and above), watchOS (4.0 and above), and macOS (10.14 and above), under Swift 5.0 and above, adding a protocol extension to Collection
to define the computed property isNotEmpty
. It may seem redundant but it sometimes does make for cleaner code.
(2019)-(Foundation) BoolConvenience (top)
BoolConvenience is a Swift package for iOS/tvOS (10.0 and above), watchOS (4.0 and above), and macOS (10.14 and above), under Swift 5.0 and above, adding an extension to Bool
to define two computed properties, isTrue
and isFalse
. These may seem redundant but they sometimes do make for cleaner code.
(2019)-(Foundation) DictionarySorting (top)
DictionarySorting is a Swift package for iOS/tvOS (10.0 and above), watchOS (4.0 and above), and macOS (10.14 and above), under Swift 5.0 and above, implementing an extension to Dictionary
that provides an easy-to-use and ergonomic "swifty" way to sort a dictionary, as easy as:
let data = /* ... */ // a dictionary of some kind
let sorted = data.sorted(by: .keys(.ascending)) // returns an array of the elements stored in the
// dictionary, sorted in ascending order of their keys
The package provides several such sorted(by:)
functions, depending on whether one or both the dictionary's Key
and Value
types conform to Comparable
.
(2019)-(Foundation) DictionarySlicing (top)
DictionarySlicing is a Swift package for iOS/tvOS (10.0 and above), watchOS (4.0 and above), and macOS (10.14 and above), under Swift 5.0 and above, implementing an extension to Dictionary
to convert a dictionary into its slice or into an array of its key-value pairs.
SortOrder is a Swift package for iOS/tvOS (10.0 and above), watchOS (4.0 and above), and macOS (10.14 and above), under Swift 5.0 and above, implementing a simple SortOrder
type.
(2019)-(Other) JsonSupport (top)
JsonSupport is a Swift package for iOS/tvOS (10.0 and above), watchOS (4.0 and above), and macOS (10.14 and above), under Swift 5.0 and above, defining a few simple functions to perform common operations associated with encoding and decoding local JSON files.
(2019)-(Other) ValueRestriction (top)
ValueRestriction is a Swift package for iOS/tvOS (10.0 and above), watchOS (4.0 and above), and macOS (10.14 and above), under Swift 5.0 and above, defining an enumeration to easily test a numerical value against some condition.
(2019)-(Other) OperationResult (top)
OperationResult is a Swift package for iOS/tvOS (10.0 and above), watchOS (4.0 and above), and macOS (10.14 and above), under Swift 5.0 and above, defining an enumeration similar to Result
but with Array<String>
in place of an error type.
One neat use for this type is when considering a long sequence of numerical operations, some of which may fail. For example, division by zero, logarithm of a non-positive number, arc-sine or arc-cosine of a number with a magnitude larger than 1, and so on. Rather than stop the execution with throw-catches or risk runtime errors, the OperationResult<A>
type allows a clean progression to the end, accumulating error messages along the way.
Counter is a Swift package for iOS/tvOS (10.0 and above), watchOS (4.0 and above), and macOS (10.14 and above), under Swift 5.0 and above, defining a model type to represent an integer counter.
Either is a Swift package for iOS/tvOS (11.0 and above), watchOS (5.0 and above), and macOS (10.14 and above), under Swift 5.0 and above, implementing a simple Either
type, with a few built-in and useful properties and protocol conformances.
(2019)-(UI) UIViewPreview (top)
UIViewPreview
is a Swift package enabling UIKit
development on macOS Catalina to take advantage of SwiftUI
previews in Xcode 11 and above. It's entirely not my idea but, rather, just a wrapper for the code written by matt, of NSHipster fame.
(2019)-(UI) ColorExtensions (top)
ColorExtensions
is a Swift package for iOS/tvOS (10.0 and above) and watchOS (5.0 and above) providing a variety of useful extensions to UIColor
.
(2019)-(UI) Assets and AssetsPre13 (top)
Assets
is an iOS framework that makes concrete use of AssetCatalogAware to provide a self-contained collection of assets and easy access to them. UIKit and SwiftUI example projects are included. The pre13 variant supports legacy systems with iOS versions from 11.0 up to but not including 13.0.
(2019)-(UI) AssetCatalogAware and AssetCatalogAwarePre13 (top)
AssetCatalogAware
is a Swift package for iOS defining a collection of protocols and associated protocol extensions to access various kinds of assets, such as colors, images, strings, and fonts, in a type-safe manner. The pre13 variant supports legacy systems with iOS/tvOS versions from 11.0 up to but not including 13.0 and watchOS versions from 4.0 up to but not including 6.0.
DrawerKit
lets an arbitrary view controller modally present another arbitrary view controller in a manner similar to the way the Maps app works. I wrote this
as part of a much bigger project we're working on at Babylon.
(2019) Please note that I am no longer actively involved with this project.
(2017)-(UI) WTAutoLayoutExtensions (top)
Extensions to UIView
and UILayoutGuide
to make it simpler and more natural to use layout guides, layout anchors, and the rest of the auto-layout machinery, with a consistent API and very little code.
(2016) Typed Notifications (top)
Not really a library on its own but merely an idea or suggestion on how to handle notifications, especially custom ones, in a more type-safe way.
(2016)-(Math) WTOnlineLinearRegression (top)
WTOnlineLinearRegression
lets you perform linear regression on one-dimensional data, with or without
variances in the dependent quantity, with the option to maintain a history of all observations as full
snapshots of the results of the regression at the time the items were added to, or removed from, the data set.
(2016)-(UI) WTCoreGraphicsExtensions (top)
A collection of useful additions to CGGradient
, CGPoint
and, especially, CGVector
. If you write 2d games
using CGVector
, you'll definitely love this library.
iOS demo apps (top)
(2016) WTOnlineLinearRegression demo app (top)
An app showing the WTOnlineLinearRegression
library.
(2016) Kaleidoscope (top)
A simulation of a kaleidoscope, using UIKit Dynamics
. Something I wrote in a few days when I was bored.
Deprecated projects (top)
(2019)-(Other) BinaryChoice - DEPRECATED (top)
BinaryChoice is a Swift package for iOS/tvOS (10.0 and above), watchOS (4.0 and above), and macOS (10.14 and above), under Swift 5.0 and above, defining protocols for types that can be initialised from a boolean value and/or can be represented by a boolean value.
(2017) WTUniquePrimitiveType - DEPRECATED (top)
A library to allow you to create distinct types based on the same primitive value so the compiler will warn you if, for example, you accidentally confuse the user name with the user password or the user email address, since they're all based on the same primitive type, namely, String
.
(2019.11.30) Please note that I've deprecated this project. A much better approach - Tagged - was devised by Brandon Williams and Stephen Celis, the folks at pointfree. You can watch the episode on it here.
(2016-2017) WTUIColorExtensions - DEPRECATED (top)
An extension to UIColor
adding the ability to generate pseudo-random color instances plus some other goodies. New in 1.1.0 is the support for:
- finding the hexadecimal representation of an RGB color
- finding the approximate luminance of a color
- finding the most contrasting color to a given color
As of 2020.02.21, this project is deprecated and is replaced by ColorExtensions.
(2016) WTBinaryFloatingPointExtensions - DEPRECATED (top)
An extension to all types conforming to the BinaryFloatingPoint
protocol, adding the ability to generate pseudo-random values and to convert between degrees and radians.
2019.11.30: This project has been deprecated since the Swift Standard Library now has (part of) the functionality that this library provides. The remaining functionality - the trigonometry-associated one - isn't so hard to implement on a case-by-case basis.
(2016) WTIntExtensions - DEPRECATED (top)
An extension to Int
to generate uniformly-distributed pseudo-random integers.
2019.11.30: This project has been deprecated since the Swift Standard Library now has precisely the functionality that this library provides.
(2016) WTBoolExtensions - DEPRECATED (top)
An extension to Bool
adding a method to generate uniformly-distributed pseudo-random booleans.
2019.11.30: This project has been deprecated since the Swift Standard Library now has precisely the functionality that this library provides.
(2015) Circular Progress View - DEPRECATED (top)
A fully customisable Swift
class for a progress view similar to what the Apple Watch has.
This is probably still useful as a learning reference but not for actual use in an app.
(2014) CGExtensions - DEPRECATED (top)
A Swift
collection of useful extensions to CGFloat
, CGPoint
, and CGVector
, plus test suites. If you need 2-dimensional vectors then you'll want this.
This library has been deprecated and replaced by separate libraries compatible with Swift 3.0. Please refer to the more recent ones listed above.