Skip to content

Instantly share code, notes, and snippets.

View laevandus's full-sized avatar

Toomas Vahter laevandus

View GitHub Profile
let text = "The quick <color_1> <animal_1> jumps over the lazy <animal_2>"
let replacementMap = ["<animal_1>": "fox", "<animal_2>": "dog", "<color_1>": "brown"]
extension String {
func replacingOccurrences(matchingPattern pattern: String, replacementProvider: (String) -> String?) -> String {
let expression = try! NSRegularExpression(pattern: pattern, options: [])
let matches = expression.matches(in: self, options: [], range: NSRange(startIndex..<endIndex, in: self))
return matches.reversed().reduce(into: self) { (current, result) in
let range = Range(result.range, in: current)!
let token = String(current[range])
@laevandus
laevandus / ColorContrastRatio.swift
Last active August 12, 2023 01:16
Calculation color contrast ratio useful for making apps more accessible and easy to read.
import UIKit
/*
Contrast ratio is calculated using the proceedure here:
https://www.w3.org/TR/WCAG20-TECHS/G17.html#G17-procedure
*/
public extension UIColor {
/// Relative luminance of the color.
var relativeLuminance: CGFloat {
// This API is available in iOS 16, macOS 13.0, tvOS 16.0, watchOS 9.0.
// Using backDeployed we can make it available in old OSes, like iOS 15 etc
extension Font {
@backDeployed(before: iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0)
@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
public static func system(size: CGFloat, weight: Font.Weight? = nil, design: Font.Design? = nil) -> Font {
fatalError("Implement")
}
}
struct Circle {
let centre: CGPoint
let radius: Double
}
extension Circle {
init(diameter: Double) {
centre = .zero
radius = diameter / 2
}
}
extension RangeReplaceableCollection where Element: Equatable {
@discardableResult mutating func remove(_ element: Element) -> Bool {
guard let index = self.firstIndex(of: element) else { return false }
remove(at: index)
// Remove other duplicate elements by recursivly calling it again
remove(element)
return true
}
}
struct SubtitledButton: View {
let title: LocalizedStringKey
let subtitle: LocalizedStringKey
let action: () -> Void
var body: some View {
Button(action: action, label: {
VStack(spacing: 4) {
Text(title)
Text(subtitle)
.font(.footnote)
import Foundation
import CommonCrypto
extension Data {
enum Algorithm {
case md5
case sha1
case sha224
case sha256
case sha384
let first = ["a": 1, "b": 2]
let second = ["a": 9, "c": 3]
// value in `first` wins if the same key in both
let merged1 = first.merging(second, uniquingKeysWith: { current, _ in current })
// value in `second` wins if the same key in both
let merged2 = first.merging(second, uniquingKeysWith: { _, new in new })
extension Dictionary {
func mergingUniqueKeys(from other: [Key: Value]) -> [Key: Value] {
override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let item = content[indexPath.item]
switch item {
case .iconAction:
let action = UIContextualAction(style: .normal, title: item.rawValue, handler: { [weak self] (action, view, block) in
self?.showAlert(item.rawValue)
})
action.backgroundColor = UIColor(hue: 0.11, saturation: 0.56, brightness: 0.48, alpha: 1.0)
action.image = UIImage(named: "Icon")
return UISwipeActionsConfiguration(actions: [action])
import UIKit
final class FittingHeightCollectionViewController: UICollectionViewController {
private let items: [[String]]
init(items: [[String]]) {
self.items = items
let layout = UICollectionViewFlowLayout()
layout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
layout.itemSize = UICollectionViewFlowLayout.automaticSize