Skip to content

Instantly share code, notes, and snippets.

@mehdi-S
Created February 24, 2024 12:53
Show Gist options
  • Save mehdi-S/e58cf7d33f178a757db41639fc4dbdaf to your computer and use it in GitHub Desktop.
Save mehdi-S/e58cf7d33f178a757db41639fc4dbdaf to your computer and use it in GitHub Desktop.
Implementation of a button that shows the loading state of an async function passed in param
//
// AsyncButton.swift
// WeaMap
//
// Created by msilini on 24/02/2024.
//
import SwiftUI
struct AsyncButton<Label: View>: View {
var action: () async -> Void
var actionOptions = Set(ActionOption.allCases)
@ViewBuilder var label: () -> Label
@State private var isDisabled = false
@State private var showProgressView = false
var body: some View {
Button(
action: {
if actionOptions.contains(.disableButton) {
isDisabled = true
}
Task {
if actionOptions.contains(.showProgressView) {
showProgressView = true
}
await action()
isDisabled = false
showProgressView = false
}
},
label: {
ZStack {
label().opacity(showProgressView ? 0 : 1)
if showProgressView {
ProgressView()
}
}
}
)
.disabled(isDisabled)
}
}
extension AsyncButton {
enum ActionOption: CaseIterable {
case disableButton
case showProgressView
}
}
#Preview {
AsyncButton(action: {
try? await Task.sleep(nanoseconds: 4_000_000_000)
}, label: {
Text("Async")
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment