Skip to content

Instantly share code, notes, and snippets.

Avatar

Jaden Geller JadenGeller

View GitHub Profile
View SubscriberView.swift
import Combine
import SwiftUI
struct SubscriberView<Publisher: Combine.Publisher>: View where Publisher.Output: View, Publisher.Failure == Never {
@State var view: Publisher.Output
let publisher: Publisher
var body: some View {
view.onReceive(publisher) { newView in
self.view = newView
@JadenGeller
JadenGeller / VirtualScrollView.swift
Last active Feb 16, 2021
Virtual Scrolling in SwiftUI
View VirtualScrollView.swift
struct VirtualScrollView<Content: View>: View {
var axes: Axis.Set = .vertical
var showsIndicators: Bool = true
var alignment: Alignment = .topLeading
var width: CGFloat? = nil
var height: CGFloat? = nil
var content: (CGRect) -> Content
var body: some View {
GeometryReader { outerGeometry in
View segment.swift
extension Array {
func segment(atJunction shouldSegment: (Element, Element) throws -> Bool) rethrows -> [ArraySlice<Element>] {
var result: [ArraySlice<Element>] = []
var previousValue: Element?
for (index, value) in enumerated() {
defer { previousValue = value }
if let previousValue = previousValue, try shouldSegment(previousValue, value) {
result.append(self[(result.last?.endIndex ?? startIndex)..<index])
}
}
View Cadence.swift
struct CadenceViewModifier: ViewModifier {
let timeInternal: Double
let action: () -> Void
@State var lastFire: Date?
func body(content: Content) -> some View {
content
.onAppear() // https://stackoverflow.com/questions/61190398/swiftui-viewmodifier-doesnt-listen-to-onreceive-events
.onReceive(Timer.publish(every: timeInternal + (lastFire?.timeIntervalSinceNow ?? 0), on: .main, in: .default).autoconnect()) { _ in
self.lastFire = Date()
View SelectableTextField.swift
struct SelectableTextField: UIViewRepresentable {
let titleKey: String
@RangeReplaceableBinding var text: String
@Binding var selectedRange: Range<String.Index>?
let onCommit: () -> Void
init(_ titleKey: String, text: Binding<String>, selectedRange: Binding<Range<String.Index>?>, onCommit: @escaping () -> Void = {}) {
self.init(titleKey, text: RangeReplaceableBinding(text), selectedRange: selectedRange, onCommit: onCommit)
}
@JadenGeller
JadenGeller / TemporaryState.swift
Last active Jul 4, 2020
TemporaryStateBinding
View TemporaryState.swift
@propertyWrapper
struct TemporaryState<Value>: DynamicProperty {
@State var modifiedValue: Value? = nil
let currentValue: Value
init(_ value: Value) {
self.currentValue = value
}
var wrappedValue: Value {
modifiedValue ?? currentValue
View DebouncedBinding.swift
@propertyWrapper
struct DebouncedBinding<Value>: DynamicProperty {
@Binding var remote: Value
@State var local: Value? = nil
init(_ remote: Binding<Value>) {
self._remote = remote
}
var wrappedValue: Value {
View KeyboardPaddingModifier.swift
import SwiftUI
import Combine
struct KeyboardPaddingModifier: ViewModifier {
@State private var keyboardMinY: CGFloat? = nil
private var keyboardNotificationPublisher: AnyPublisher<Notification, Never> {
Publishers.Merge(
NotificationCenter.default
.publisher(for: UIResponder.keyboardWillShowNotification),
@JadenGeller
JadenGeller / Editing.swift
Last active Aug 22, 2020
SwiftUI editing Binding for UIControl firstResponder
View Editing.swift
import SwiftUI
import Dispatch
extension View {
// Warning: This will affect the layout of the view that's wrapped! :(
public func editing(_ isEditing: Binding<Bool>) -> some View {
EditingProxy(rootView: self, isEditing: isEditing)
}
}
@JadenGeller
JadenGeller / Grid4x4.swift
Created Apr 9, 2020
Grid4x4 SwiftUI View
View Grid4x4.swift
struct Grid4x4<TopLeft: View, TopRight: View, BottomLeft: View, BottomRight: View>: View {
let topLeft: TopLeft
let topRight: TopRight
let bottomLeft: BottomLeft
let bottomRight: BottomRight
init(@ViewBuilder content: () -> TupleView<(TopLeft, TopRight, BottomLeft, BottomRight)>) {
(topLeft, topRight, bottomLeft, bottomRight) = content().value
}