Skip to content

Instantly share code, notes, and snippets.

View Amzd's full-sized avatar
🚀

Casper Zandbergen Amzd

🚀
View GitHub Profile
@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()
}
}
@Amzd
Amzd / TextFieldFocusableArea.swift
Last active August 6, 2021 14:48
SwiftUI TextField has a very small tappable area and there is no simple way to make that area bigger. This is a solution using Introspect (https://github.com/siteline/SwiftUI-Introspect/) Stack Overflow question: https://stackoverflow.com/questions/56795712/swiftui-textfield-touchable-area/62089790#62089790
extension View {
public func textFieldFocusableArea() -> some View {
TextFieldButton { self.contentShape(Rectangle()) }
}
}
fileprivate struct TextFieldButton<Label: View>: View {
init(label: @escaping () -> Label) {
self.label = label
}
@Amzd
Amzd / EmptyOrNil.swift
Created November 12, 2021 08:10 — 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 / HierarchyDescription.swift
Last active May 16, 2023 19:48
Description that can be used with any type that has recursive children
public protocol HierarchyDescription {
associatedtype Child: HierarchyDescription
var children: [Child] { get }
var description: String { get }
}
extension HierarchyDescription {
public var hierarchyDescription: String {
var description = self.description
for child in children {
@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 / 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 / Navigation.swift
Last active July 6, 2023 03:34
Fix the back swipe gesture not working correctly in SwiftUI. https://stackoverflow.com/a/58345554/3393964
/// Fixed swipe gesture NavigationLink
struct NavigationLink<Destination: View, Label:View>: View {
var destination: Destination
var label: () -> Label
public init(destination: Destination, @ViewBuilder label: @escaping () -> Label) {
self.destination = destination
self.label = label
}
@Amzd
Amzd / PreferenceUIHostingController.swift
Last active September 8, 2023 12:14
PreferenceUIHostingController. Adds hiding home indicator and deferring system edge gestures to SwiftUI. (Don't work at the same time but I think that's normal?)
extension View {
/// Controls the application's preferred home indicator auto-hiding when this view is shown.
func prefersHomeIndicatorAutoHidden(_ value: Bool) -> some View {
preference(key: PreferenceUIHostingController.PrefersHomeIndicatorAutoHiddenPreferenceKey.self, value: value)
}
/// Controls the application's preferred screen edges deferring system gestures when this view is shown. Default is UIRectEdgeNone.
func edgesDeferringSystemGestures(_ edge: UIRectEdge) -> some View {
preference(key: PreferenceUIHostingController.PreferredScreenEdgesDeferringSystemGesturesPreferenceKey.self, value: edge)
}
@Amzd
Amzd / Binding+didSet.swift
Last active September 20, 2023 05:27
SwiftUI Binding wrappers for willSet and didSet
extension Binding {
/// Wrapper to listen to didSet of Binding
func didSet(_ didSet: @escaping ((newValue: Value, oldValue: Value)) -> Void) -> Binding<Value> {
return .init(get: { self.wrappedValue }, set: { newValue in
let oldValue = self.wrappedValue
self.wrappedValue = newValue
didSet((newValue, oldValue))
})
}