Created
October 29, 2025 15:47
-
-
Save raulriera/16dd0b9d049103515f2423757d0921e9 to your computer and use it in GitHub Desktop.
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
| 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