Skip to content

Instantly share code, notes, and snippets.

@raulriera
Created October 29, 2025 15:47
Show Gist options
  • Save raulriera/16dd0b9d049103515f2423757d0921e9 to your computer and use it in GitHub Desktop.
Save raulriera/16dd0b9d049103515f2423757d0921e9 to your computer and use it in GitHub Desktop.
import SwiftUI
extension ContainerValues {
@Entry var taskCompleted: Bool = false
}
struct TaskContainer<Content: View>: View {
var content: Content
init(@ViewBuilder content: () -> Content) {
self.content = content()
}
var body: some View {
ZStack {
Group(sections: content) { sections in
ForEach(sections) { section in
Group(subviews: section.content) { subviews in
if let firstIncomplete = subviews.first(where: { !$0.containerValues.taskCompleted }) {
firstIncomplete
}
}
}
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.ignoresSafeArea()
}
}
struct TaskView<Content: View>: View {
@State private var completed = false
let content: (_ complete: @escaping () -> Void) -> Content
init(@ViewBuilder content: @escaping (_ complete: @escaping () -> Void) -> Content) {
self.content = content
}
var body: some View {
content { completed = true }
.containerValue(\.taskCompleted, completed)
}
}
// MARK: - Example tasks, using TaskView directly would be annoying. Would be nice to protocol constrain tho
struct SleepTaskView: View {
let seconds: Double
var body: some View {
TaskView { complete in
Color.clear
.task {
try? await Task.sleep(nanoseconds: UInt64(seconds * 1_000_000_000))
complete()
}
}
}
}
struct TapToContinueTask: View {
let label: String
var body: some View {
TaskView { complete in
Button(label) { complete() }
.buttonStyle(.borderedProminent)
}
}
}
struct ContentView: View {
var body: some View {
TaskContainer {
Section {
SleepTaskView(seconds: 0.5)
TapToContinueTask(label: "Tap to Continue")
}
Section {
SleepTaskView(seconds: 5)
TapToContinueTask(label: "Tap to Continue (again)")
}
}
}
}
#Preview { ContentView() }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment