January 6, 2013
I recently saw a post on Twitter from @chpwn that described the alogorithm that Apple uses for its “rubber band” or “bungee” scrolling.
b = (1.0 – (1.0 / ((x * c / d) + 1.0))) * d
| extension View { | |
| // https://www.avanderlee.com/swiftui/conditional-view-modifier/ | |
| /// Applies the given transform if the given condition evaluates to `true`. | |
| /// - Parameters: | |
| /// - condition: The condition to evaluate. | |
| /// - transform: The transform to apply to the source `View`. | |
| /// - Returns: Either the original `View` or the modified `View` if the condition is `true`. | |
| @ViewBuilder func `if`<Content: View>(_ condition: Bool, transform: (Self) -> Content) -> some View { | |
| if condition { | |
| transform(self) | 
| // | |
| // SwiftUICollectionView.swift | |
| // Sentry | |
| // | |
| // Created by Simon Westerlund on 2019-12-29. | |
| // Copyright © 2019 Simon Westerlund. All rights reserved. | |
| // | |
| import SwiftUI | 
| let json = """ | |
| { | |
| "foo": "bar", | |
| "baz": null | |
| } | |
| """ | |
| struct Type: Decodable { | |
| let type: String | |
| let value: String? | 
| struct FontSizesHelper { | |
| static func dynamicSize(for originalSize: CGFloat, category: UIContentSizeCategory = UIApplication.shared.preferredContentSizeCategory) -> CGFloat { | |
| let modifyBy: CGFloat = { | |
| switch category { | |
| case .extraSmall: return -3 | |
| case .small: return -2 | |
| case .medium: return -1 | |
| case .large: return 0 | |
| case .extraLarge: return 2 | |
| case .extraExtraLarge: return 4 | 
| func orThrow<E: Error>(_ errorClosure: @autoclosure () -> E) throws -> Wrapped { | |
| guard let value = self else { | |
| throw errorClosure() | |
| } | |
| return value | |
| } | |
| // usage | |
| orThrow(UnboxError.invalidData) | 
| // based on this answer 'http://stackoverflow.com/a/36016798' | |
| class LeftAlignedCollectionViewFlowLayout: UICollectionViewFlowLayout { | |
| override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { | |
| let attributes = super.layoutAttributesForElements(in: rect) | |
| var leftMargin = sectionInset.left | |
| var maxY: CGFloat = -1.0 | |
| attributes?.forEach { layoutAttribute in | |
| if layoutAttribute.frame.origin.y >= maxY { | 
| // A boiler plate operation to be used as a subclass | |
| // | |
| // Created by Simon Westerlund on 2016-11-07. | |
| // Copyright © 2016 Simon Westerlund. All rights reserved. | |
| // | |
| import Foundation | |
| final class BaseOperation: Operation { | |
| private var _isFinished = false { | |
| willSet { willChangeValue(forKey: "isFinished") } | 
| // A boiler plate operation to be used as a subclass | |
| // | |
| // Created by Simon Westerlund on 2016-11-07. | |
| // Copyright © 2016 Simon Westerlund. All rights reserved. | |
| // | |
| import Foundation | |
| final class BaseOperation: Operation { | |
| private var _isFinished = false { | |
| willSet { willChangeValue(forKey: "isFinished") } | 
| extension String { | |
| func pirated() -> String { | |
| let consonants = "bcdfghjklmnpqrstvwxyz" | |
| return characters.map({ char -> String in | |
| let character = String(char) | |
| if consonants.contains(character.lowercased()) { | |
| return "\(char)o\(character.lowercased())" | |
| } | |
| return character |