Two of the most useful and frequently used extensions in SwiftUI:
// 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
}
}
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:
Place them to the SwiftUI+Extension.swift file in your project.