Skip to content

Instantly share code, notes, and snippets.

View Amzd's full-sized avatar
🚀

Casper Zandbergen Amzd

🚀
View GitHub Profile
extension Image {
/// This helps achieving what `UIView.ContentMode.scaleAspectFit` and `.scaleAspectFill` do in UIImageView.contentMode
///
/// The difference between Image.containerAspectRatio (this) and SwiftUIs View.aspectRatio is that the first applies the
/// aspect ratio to the view that contains the image, rather than to the image itself.
///
/// So in the following example:
/// - The first image will scale to a square but the contentMode does not do anything to prevent stretching and wether you use .fit or .fill does not matter.
/// - The second image will resize to fit inside a square while maintaining its aspect ratio, similar to how a UIImageView with contentMode set to scaleAspectFit behaves.
/// - The third image will resize to fill inside a square while maintaining its aspect ratio similar to how a UIImageView with contentMode set to scaleAspectFill behaves.
@Amzd
Amzd / EmptyOrNil.swift
Last active June 10, 2024 13:48 — forked from casperzandbergenyaacomm/EmptyOrNil.swift
Adding readability for an if statement I often use.
protocol EmptyOrNil {
var isEmpty: Bool { get }
}
extension Optional where Wrapped: EmptyOrNil {
var isEmptyOrNil: Bool {
return self?.isEmpty ?? true
}
}
import SwiftUI
/// Reads the width of the selection box next to a List row when editing mode is .active
///
/// Note: On iOS 15 the listRowInsets do not respond to updates so if you want to offset
/// the cell you should use negative leading padding.
public struct ListSelectionBoxWidthReader<Content: View>: View {
@State private var boxWidth: CGFloat = 0
private var content: (CGFloat) -> Content
@Amzd
Amzd / DictionaryKeyPath.swift
Last active November 5, 2023 04:46 — forked from casperzandbergenyaacomm/DictionaryKeyPath.swift
Reading and writing to (possible) nested dictionaries for a given key path, using a recursive approach
// Inspired by: https://gist.github.com/dfrib/d7419038f7e680d3f268750d63f0dfae
import Foundation
public extension Dictionary {
subscript(keyPath string: Key, separator: String) -> Value? where Key == String {
get { return self[keyPath: string.components(separatedBy: separator)] }
set { self[keyPath: string.components(separatedBy: separator)] = newValue }
}
@Amzd
Amzd / StateObject.swift
Last active March 27, 2024 20:14
StateObject that works in iOS 13
import Combine
import PublishedObject // https://github.com/Amzd/PublishedObject
import SwiftUI
/// A property wrapper type that instantiates an observable object.
@propertyWrapper
public struct StateObject<ObjectType: ObservableObject>: DynamicProperty
where ObjectType.ObjectWillChangePublisher == ObservableObjectPublisher {
/// Wrapper that helps with initialising without actually having an ObservableObject yet
@Amzd
Amzd / DateRounding.swift
Created June 2, 2021 08:58 — forked from casperzandbergenyaacomm/DateRounding.swift
Rounding of date and time
import Foundation
extension Date {
/// Returns date where **-component** is rounded to its closest
/// multiple of **-amount**. Warning: month and day start at 1
/// so round(to: 6, .month) will either return month 1 or 7!
func round(to amount: Int, _ component: Calendar.Component) -> Date {
let cal = Calendar.current
var value = cal.component(component, from: self)
@Amzd
Amzd / AppendingClosures.swift
Last active May 16, 2023 19:50
Appending Closures, eg a shorthand to create one new closure that calls two closures.
// MARK: Appending closures `a + b`
/// Append closures, lhs first.
public func + <I>(lhs: @escaping (I) -> Void, rhs: @escaping (I) -> Void) -> ((I) -> Void) {
return {
lhs($0)
rhs($0)
}
}
@Amzd
Amzd / ColorPicker.swift
Last active September 29, 2024 00:36
What SwiftUI's ColorPicker should have been.
import SwiftUI
@available(iOS 14.0, *)
public struct ColorPickerWithoutLabel: UIViewRepresentable {
@Binding var selection: Color
var supportsAlpha: Bool = true
public init(selection: Binding<Color>, supportsAlpha: Bool = true) {
self._selection = selection
self.supportsAlpha = supportsAlpha
@Amzd
Amzd / Publisher+void.swift
Last active January 16, 2021 22:35
Void publisher result
extension Publisher {
func void() -> Publishers.Map<Self, Void> {
self.map { _ in () }
}
}
@Amzd
Amzd / AnyPublisher.swift
Created December 7, 2020 11:26
Empty and constant AnyPublisher extensions
@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
extension AnyPublisher {
static var empty: Self {
Empty(completeImmediately: false).eraseToAnyPublisher()
}
static func constant(_ value: Output) -> Self where Failure == Never {
Just(value).eraseToAnyPublisher()
}
}