Skip to content

Instantly share code, notes, and snippets.

let redView = UIView()
redView.backgroundColor = .red
addSubview(redView) {
$0.edges(20).equalToSuperview()
}
let redView = UIView()
redView.backgroundColor = .red
addSubview(redView)
redView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
redView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 20),
redView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -20),
redView.topAnchor.constraint(equalTo: topAnchor, constant: 20),
redView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -20)
])
final class LoginViewController: UIViewController {
@EmailStyle private var emailTextField
@PasswordStyle private var passwordTextField
@SubmitStyle private var submitButton
}
class FormTextField: UITextField {
var isValid: Bool = false {
didSet { layer.borderColor = isValid ? validColor.cgColor : invalidColor.cgColor }
}
var validColor: UIColor = .black
var invalidColor: UIColor = .black
}
@propertyWrapper
struct EmailStyle {
@propertyWrapper
struct EmailStyle {
var wrappedValue: UITextField
init(_ textField: UITextField = .init()) {
wrappedValue = textField
textField.autocapitalizationType = .none
textField.autocorrectionType = .no
textField.placeholder = "Email"
textField.keyboardType = .emailAddress
}
final class LoginViewController: UIViewController {
private lazy var emailTextField = UITextField()
private lazy var passwordTextField = UITextField()
private lazy var submitButton = UIButton()
override func viewDidLoad() {
super.viewDidLoad()
emailTextField.keyboardType = .emailAddress
emailTextField.autocapitalizationType = .none
emailTextField.autocorrectionType = .no
import UIKit
@resultBuilder
enum AutoLayoutBuilder {
/// Required by every result builder to build combined results from statement blocks.
static func buildBlock(_ components: ConstraintProvider...) -> [NSLayoutConstraint] {
components.flatMap(\.constraints)
}
/// Provides support for `for..in` loops.
extension Sequence where Element: Hashable {
func removingDuplicates() -> [Element] {
var uniques = Set<Element>()
return filter { uniques.insert($0).inserted }
}
mutating func removeDuplicates() {
self = removingDuplicates()
}
}
@cjnevin
cjnevin / AsyncAwaitCleanArchitecture.swift
Last active November 1, 2022 06:20
Example of how one might implement Clean Architecture with async/await and VIP cycle
import UIKit
// Domain layer should be platform agnostic rules that
// can be fully tested against stubs and spies. This gives
// us confidence our business logic is working even when
// we may have issues with particular platforms integration
// layers.
//
// Integration layer could be split out per platform.
// For example on macOS you could check a MySQL database
@cjnevin
cjnevin / Publishers+CaseMap.swift
Last active April 8, 2022 01:43
Map each case in an enum to a corresponding publisher. All publishers must adhere to same response type.
import Combine
public extension Publishers {
/// Map each case in an enum to a corresponding `Publisher`.
/// All `Publishers` must adhere to same response type.
/// Order of `Publishers` must match `CaseIterable` order.
struct CaseMap<A: Publisher, B: Publisher>: Publisher where A.Output: CaseIterable, A.Output: Equatable, A.Failure == B.Failure {
public typealias Output = B.Output
public typealias Failure = B.Failure