What is the View Structure of Notifications in SwiftUI?

I'm wanting to build a similar look n feel as the Notifications view structure. I like the multi-card stack when a category of items stack to a depth of 3 cards.... I'm new in SwiftUI and wonder if an Apple engineer or some smart person could sketch this view structure and the SwiftUI components out for me.

[wish I could include an image - it's worth a 1000 words you know!]

For my app I want the top card (an intro card) ...
then a vertical scroll list of 6 categaries of multi-card stacks.
I want the multi-card stacks to un-stack and scroll horizontally (not vertically as Notifications does). And a last (bottom) category of a single card stack.

Code Block
Graphically:
| _ |
| _ | | |
| _ | | |
| _ | | |
| _ | | |
| _ | | |
| _ | | |
| _ |

Well - I tried...to make a graphic...

all scrolling vertically and then the inner 6 stacks being able to scroll horizontally after a tap to un-stack them.

Thanks for the newbie help!

Accepted Reply

This should give you a sense of where to start. You can probably implement the expansion behavior using a ScrollView with an HStack and then animate between the ZStack and the HStack.

Code Block
struct ContentView: View {
    var body: some View {
        ScrollView {
            CardView()
            CardStack(cards: 3)
            CardStack(cards: 2)
            CardStack(cards: 3)
        }
        .background(Color(white: 0.9).edgesIgnoringSafeArea(.all))
    }
}
struct CardView: View {
    var body: some View {
        RoundedRectangle(cornerRadius: 16, style: .continuous)
            .fill(Color.white)
            .frame(height: 128)
            .overlay(RoundedRectangle(cornerRadius: 16).stroke(Color.gray, lineWidth: 1))
            .padding(.horizontal, 20)
    }
}
struct CardStack: View {
    let cards: Int
    var body: some View {
        ZStack {
            ForEach(0..<cards) { i in
                CardView()
                    .scaleEffect(1 - CGFloat(i) * 0.05, anchor: .center)
                    .offset(x: 0, y: CGFloat(i) * 12)
                    .zIndex(2 - Double(i))
            }
        }
        .padding(.bottom, 12 * CGFloat(cards - 1))
    }
}

Replies

This should give you a sense of where to start. You can probably implement the expansion behavior using a ScrollView with an HStack and then animate between the ZStack and the HStack.

Code Block
struct ContentView: View {
    var body: some View {
        ScrollView {
            CardView()
            CardStack(cards: 3)
            CardStack(cards: 2)
            CardStack(cards: 3)
        }
        .background(Color(white: 0.9).edgesIgnoringSafeArea(.all))
    }
}
struct CardView: View {
    var body: some View {
        RoundedRectangle(cornerRadius: 16, style: .continuous)
            .fill(Color.white)
            .frame(height: 128)
            .overlay(RoundedRectangle(cornerRadius: 16).stroke(Color.gray, lineWidth: 1))
            .padding(.horizontal, 20)
    }
}
struct CardStack: View {
    let cards: Int
    var body: some View {
        ZStack {
            ForEach(0..<cards) { i in
                CardView()
                    .scaleEffect(1 - CGFloat(i) * 0.05, anchor: .center)
                    .offset(x: 0, y: CGFloat(i) * 12)
                    .zIndex(2 - Double(i))
            }
        }
        .padding(.bottom, 12 * CGFloat(cards - 1))
    }
}

Weird in Xcode Version 12.0 beta (12A8158a) I'm getting:

"Unable to prepare a playground execution environment." and no canvas come up to view the running code.... pondering...
I'd love to run this and see its layout - I bet it's very close to what I need. Xcode 12 is not cooperating.
YES! Thanks - that's what I was thinking. I believe I can flesh it out from there. So there's no Swifty Control that's doing this layout - it's just a composite of views and the ZStack. Interesting... Thank you for the HELP!