Skip to content

Instantly share code, notes, and snippets.

View BrentMifsud's full-sized avatar

Brent Mifsud BrentMifsud

View GitHub Profile
@BrentMifsud
BrentMifsud / Flow.swift
Last active December 18, 2023 22:19
A view that renders its children in a flow layout
import SwiftUI
/// A layout that presents its children in a flow layout
/// Thanks to [objc.io](https://talk.objc.io/episodes/S01E308-the-layout-protocol?t=489) for the starting point
/// Added some additional changes here to support view spacing and resizing of subviews that are larger than the container.
@available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, *)
public struct FlowLayout: Layout {
private let spacing: CGFloat
public init(spacing: CGFloat = 8) {
@BrentMifsud
BrentMifsud / AsyncSequence+AsyncStreamInitializer.swift
Last active July 24, 2023 20:34
Convenience methods for converting any async sequence into an async stream
fileprivate extension AsyncStream {
init<Base: AsyncSequence>(from sequence: Base, file: StaticString = #filePath, line: UInt = #line) where Element == Base.Element {
var iterator = sequence.makeAsyncIterator()
// FIXME: In later swift versions, AsyncSequence protocol will likely have an associated error type.
// FIXME: For now, produce an assertionFailure to let developer know to use an AsyncThrowingStream instead.
self.init {
do {
return try await iterator.next()
} catch {
assertionFailure("warning: Base AsyncSequence threw an error. Use AsyncThrowingStream instead", file: file, line: line)
@BrentMifsud
BrentMifsud / UITestHelpers.swift
Last active February 16, 2023 02:17
Xcode UI Testing Helpers
import XCTest
/// Bundle identifiers for apples native apps. Used to open other apps during UI testing.
///
/// More can be found here: https://support.apple.com/en-ca/guide/deployment/depece748c41/web
enum AppleBundleIdentifiers: String {
case safari = "com.apple.mobilesafari"
case springboard = "com.apple.springboard"
}
@BrentMifsud
BrentMifsud / SafeAreaReader.swift
Last active February 16, 2023 01:38
View Modifier that will fetch a SwiftUI view's safe area inset and expose it via the preferences system.
import SwiftUI
public extension View {
func onSafeAreaChange(onChange: @escaping (EdgeInsets) -> Void) -> some View {
modifier(SafeAreaReader(onChange: onChange))
}
}
internal struct SafeAreaReader: ViewModifier {
var onChange: (EdgeInsets) -> Void
@BrentMifsud
BrentMifsud / SizeReader.swift
Last active February 16, 2023 01:38
A SwiftUI ViewModifier that reads a view's size
import SwiftUI
public extension View {
/// Exposes the size of the specified view
/// - Parameter onChange: This function will be called when the size of a view changes.
/// - Returns: some View
func onSizeChange(onChange: @escaping (CGSize) -> Void) -> some View {
modifier(SizeReader(onChange: onChange))
}
}
@BrentMifsud
BrentMifsud / PreviewDevice+Devices.swift
Last active October 31, 2022 18:50
Extension on PreviewDevice that includes all available devices
import SwiftUI
/// Static properties for all preview devices.
///
/// Usage:
///
/// ```swift
/// struct TestView_Previews: PreviewProvider {
/// static var previews: some View {
/// Group {
@BrentMifsud
BrentMifsud / HTTPMethod.swift
Created November 5, 2021 21:16
Standard HTTPMethods that can be used with URLRequests
import Foundation
/// Standard HTTP Methods
enum HTTPMethod: String {
case options = "OPTIONS"
case get = "GET"
case head = "HEAD"
case post = "POST"
case put = "PUT"
case patch = "PATCH"
@BrentMifsud
BrentMifsud / ContentResizingTableView.swift
Created November 3, 2021 02:45
UITableView that resizes to fit content
/// Resizes to fit its content. Or until size reaches provided constraints.
final class ContentResizingTableView: UITableView {
override var contentSize: CGSize {
didSet {
invalidateIntrinsicContentSize()
}
}
override var intrinsicContentSize: CGSize {
layoutIfNeeded()
@BrentMifsud
BrentMifsud / NilCodable.swift
Last active June 16, 2021 22:40
Allows more control over encoding or omitting nil values in JSON.
/// Property wrapper that provides control over whether to explicitly encode nil values to json or not.
/// - Parameters:
/// - wrappedValue: the value to be encoded.
/// - encodeNil: Should the value be explicitly encoded as "null" in json if nil.
/// - Note:
/// Usage:
///
/// ```swift
/// struct MyStruct: Codable {
/// @NilCodable var myNullable: String? // defaults to omitting null (codable default behavior)
@BrentMifsud
BrentMifsud / MKCoordinateRegion+OffsetZoomHelpers.swift
Last active February 24, 2021 23:25
Helper Extensions for zooming Annotations and Overlays with an offset from the center of the map.
extension MKCoordinateRegion {
/// Initialize a `MKCoordinateRegion` from a set of `MKAnnotations`
/// - Parameter annotations: Annotations
init(for annotations: [MKAnnotation]) {
var minLat: CLLocationDegrees = 90.0
var maxLat: CLLocationDegrees = -90.0
var minLon: CLLocationDegrees = 180.0
var maxLon: CLLocationDegrees = -180.0
for annotation in annotations {