SwiftUI most used extensions

Two of the most useful and frequently used extensions in SwiftUI:

  1. Layout debug border with modifier .debugBorder()
bug preview
// MARK: - Layout debug border

extension View {
    func debugBorder(_ color: Color = Color.gray.opacity(0.5)) -> some View {
        modifier(DebugBorder(color))
    }
}

struct DebugBorder: ViewModifier {
    let color: Color
    init(_ color: Color) {
        self.color = color
    }
    func body(content: Content) -> some View {
        content
            .border(color)
    }
}

How to use:

var body: some View {
    VStack {
        SomeView()
            .debugBorder() /// <- place modifier while implementing/debugging
        AnotherView()
            .debugBorder(.blue) /// use Color for clarity
    }
}
  1. Call setup code once at View opening

Often necessary to run some code at the start of your view. Usage .onAppear is not good solution because it can be called multiple times during the view’s lifecicle.View .init is not a good place either because iSwiftUI can call .init many times, this is how SwiftUI works, there is no guarantee that init will be called just once, unlike UIKit, if you are familiar with it.

// MARK: - viewDidLoad

public extension View {
    func viewDidLoad(_ action: @escaping () -> ()) -> some View {
        modifier(ViewDidLoad(action: action))
    }
}

private struct ViewDidLoad: ViewModifier {
    let action: () -> ()
    @State private var isLoaded = false
    func body(content: Content) -> some View {
        content.onAppear {
            guard !isLoaded else { return }
            isLoaded = true
            action()
        }
    }
}

How to use:

var body: some View {
    VStack {
        SomeView()
        AnotherView()
    }
        .viewDidLoad {
            viewModel.fetchData() // <- this will be called just once
        }
}

practice test:

bug preview

Place them to the SwiftUI+Extension.swift file in your project.