Created
June 12, 2025 23:44
-
-
Save IanKeen/460d595f8acaf263d21e858bda6dc51b to your computer and use it in GitHub Desktop.
SwiftUI: Better `refreshable` - Prevent View redraws cancelling `refreshable` by making it stable
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extension View { | |
public func _refreshable(_ action: @escaping () async -> Void) -> some View { | |
modifier(RefreshableTaskModifier(action: action)) | |
} | |
} | |
private struct RefreshId { | |
var value: UUID | |
var continuation: CheckedContinuation<Void, Never> | |
} | |
private struct RefreshableTaskModifier: ViewModifier { | |
@State private var refreshId: RefreshId? | |
var action: () async -> Void | |
func body(content: Content) -> some View { | |
content | |
.refreshable { | |
await withCheckedContinuation { refreshId = .init(value: .init(), continuation: $0) } | |
} | |
.task(id: refreshId?.value) { | |
guard let refreshId else { return } | |
await action() | |
refreshId.continuation.resume() | |
self.refreshId = nil | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment