Skip to content

Instantly share code, notes, and snippets.

View mdb1's full-sized avatar
🎯
Focusing

Manu mdb1

🎯
Focusing
View GitHub Profile
@mdb1
mdb1 / DelayAppearanceModifier.swift
Last active March 11, 2023 20:11
DelayAppearanceModifier
struct DelayAppearanceModifier: ViewModifier {
var animation: Animation
var delay: TimeInterval
var offset: CGSize
@State private var isShown: Bool = false
func body(content: Content) -> some View {
content
.opacity(isShown ? 1 : 0)
.offset(x: isShown ? 0 : offset.width, y: isShown ? 0 : offset.height)
@mdb1
mdb1 / XCTest+AsyncAssert.swift
Last active July 6, 2023 22:45
asyncAssert
import XCTest
public extension XCTestCase {
/// Runs the assertions provided in the main thread in an async way.
/// Useful for testing objects that make async requests (using mocked protocols for the responses)
/// - Parameters:
/// - expectation: The string representation of what we expect.
/// - asyncWaitDuration: Duration in seconds to wait before trying to assert the assertions. Default: 0.05.
/// - assertions: escaping method containing all the assertions.
func asyncAssert(
@mdb1
mdb1 / AssertState.swift
Created February 3, 2023 19:45
assertState
import Combine
import XCTest
/// Runs the assertions provided for the publisher variable.
public class AssertState {
private var subscribers: Set<AnyCancellable> = []
/// Initializes AssertState object.
public init() {}
}
@mdb1
mdb1 / XCTestCase+MemoryDeallocation.swift
Created February 3, 2023 19:44
assertMemoryDeallocation
import XCTest
public extension XCTestCase {
/// This is a method to determine that an instance gets deallocated from memory correctly; ie: no memory leaks 😄.
/// It leverages the `addTeardownBlock` method on `XCTest`:
/// `* Teardown blocks are executed after the current test method has returned but before tearDown is invoked.`
func assertMemoryDeallocation(
in instance: AnyObject,
file: StaticString = #filePath,
line: UInt = #line
@mdb1
mdb1 / CancelCircularButton.swift
Created February 2, 2023 19:05
Cancel button with long press animation
import SwiftUI
public struct CancelCircularButton: View {
@GestureState private var isHighlighted = false
@Environment(\.isEnabled) private var isEnabled
private let size: CGFloat
private let longPressDuration: CGFloat
private let action: () -> Void
public init(
@mdb1
mdb1 / SpinnerProgressView.swift
Created February 1, 2023 18:05
Custom Progress View
import SwiftUI
public struct SpinnerProgressView: View {
@State private var isLoading = false
private let color: Color
private let size: CGFloat
private let lineWidth: CGFloat
public init(
color: Color = .accentColor,
@mdb1
mdb1 / PrimaryTextField.swift
Created January 31, 2023 15:06
A TextField with an error state.
//
// PrimaryTextField.swift
//
//
// Created by Manu on 31/01/2023.
//
import SwiftUI
struct PrimaryTextField: View {
@mdb1
mdb1 / TemplateInfo.plist
Created January 27, 2023 15:03
Xcode Template - TemplateInfo
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SupportsSwiftPackage</key>
<true/>
<key>Kind</key>
<string>Xcode.IDEFoundation.TextSubstitutionFileTemplateKind</string>
<key>Description</key>
<string>A SwiftUI View with it&apos;s ViewModel and the Mocks</string>
@mdb1
mdb1 / ___FILEBASENAME___Model.swift
Last active September 12, 2023 20:39
Xcode Template - ViewModel
//___FILEHEADER___
import Foundation
extension ___VARIABLE_ViewName___ {
final class ViewModel: ObservableObject {
private let dependencies: Dependencies
init(dependencies: Dependencies = .default) {
self.dependencies = dependencies
@mdb1
mdb1 / ___FILEBASENAME____Mocks.swift
Last active September 12, 2023 20:38
Xcode Template - Mocks
//___FILEHEADER___
import Foundation
extension ___VARIABLE_ViewName___.ViewModel.Dependencies {
static var mock: Self {
.init {
// TODO: Replace me
return
}