Skip to content

Instantly share code, notes, and snippets.

@oconnelltoby
oconnelltoby / AutomaticBuilder.swift
Created January 1, 2022 19:31
Automatic builder
@dynamicMemberLookup
struct Configurator<T> {
var configure: (inout T) -> Void = { _ in }
subscript<V>(dynamicMember keyPath: WritableKeyPath<T, V>) -> Builder<V> {
.init(configure: configure, keyPath: keyPath)
}
static subscript<V>(dynamicMember keyPath: WritableKeyPath<T, V>) -> Builder<V> {
.init(configure: { _ in }, keyPath: keyPath)
@oconnelltoby
oconnelltoby / KeyboardLayoutGuide.swift
Last active December 23, 2021 14:13
KeyboardLayoutGuide
import UIKit
import Combine
extension NSLayoutConstraint {
@discardableResult
func withPriority(_ priority: UILayoutPriority) -> Self {
self.priority = priority
return self
}
}
@oconnelltoby
oconnelltoby / UIScrollView+UIStackView.swift
Last active September 26, 2021 21:55
UIStackView in a UIScrollView
import UIKit
public extension UIScrollView {
convenience init(stackView: UIStackView) {
self.init(frame: .zero)
stackView.translatesAutoresizingMaskIntoConstraints = false
addSubview(stackView)
NSLayoutConstraint.activate([
@oconnelltoby
oconnelltoby / Timing.swift
Created September 12, 2021 12:26
Demonstration of a mocked Timer
import Foundation
protocol Timing {
associatedtype TimerType: Timing
static func scheduledTimer(withTimeInterval: TimeInterval, repeats: Bool, block: @escaping (TimerType) -> Void) -> TimerType
func invalidate()
func fire()
}
extension Timer: Timing {}
@oconnelltoby
oconnelltoby / OptionallyDecodable.swift
Created August 10, 2021 17:05
A wrapper for potentially malformed JSON objects
struct OptionallyDecodable<Value: Decodable>: Decodable {
let value: Value?
init(from decoder: Decoder) throws {
do {
let container = try decoder.singleValueContainer()
self.value = try container.decode(Value.self)
} catch {
self.value = nil
}
@oconnelltoby
oconnelltoby / BinarySearch.swift
Created March 27, 2021 08:56
Iterative binary search
extension RandomAccessCollection where Element: Comparable {
func binarySearch(target: Element) -> Index? {
guard !isEmpty else {
return nil
}
var start = startIndex
var end = endIndex
while start <= end {
@oconnelltoby
oconnelltoby / Passthrough.swift
Created March 25, 2021 00:01
@dynamicMemberCallable with KeyPath
@dynamicMemberLookup
protocol Passthrough {
associatedtype Previous
var previous: Previous { get }
subscript<T>(dynamicMember keyPath: KeyPath<Previous, T>) -> T { get }
}
extension Passthrough {
subscript<T>(dynamicMember keyPath: KeyPath<Previous, T>) -> T {
return previous[keyPath: keyPath]
import UIKit
class PageViewController: UIPageViewController {
private let firstItem: UIViewController
private var pages: [UIViewController]
private let pageChanged: (_ index: Int) -> Void
let strongDelegate: UIPageViewControllerDelegate
let strongDataSource: UIPageViewControllerDataSource
@oconnelltoby
oconnelltoby / Buildable.swift
Created December 13, 2020 11:21
Buildable protocol Swift
protocol Buildable {}
extension Buildable {
func with(transform: (inout Self) throws -> Void) rethrows -> Self {
var mutableSelf = self
try transform(&mutableSelf)
return mutableSelf
}
}
func mutating<Type>(_ type: Type, transform: (inout Type) throws -> Void) rethrows -> Type {