0

I'm targeting iOS18 and above, I'm trying to achieve this effect

enter image description here

The app displayed is Revolut, I want to create a similar effect but I can't seem to find a starting point I also need it to be in sync with a ScrollView which I can do once I get those tabs in that place

My problem is getting the tabs in that place (in the navigation stack), I tried with

NavigationStack {
    ScrollView {}
        .toolbar{
            ToolbarItem(placement: .navigation) { // tried a different placements
                ScrollView {
                    // buttons 
                }
            }
        }
}

In my case it actually starts from left to right which should be even easier but I can't seem to get the tabs there.

Any help would be appreciated even a link pointing somewhere that can get me started

1
  • The navigation toolbar is the top row, with the back button and the "Transactions" heading. To show the tab buttons below this toolbar, just use a VStack as the top-level container below NavigationStack. The VStack can then contain the buttons and the outer ScrollView. Commented May 7 at 15:31

1 Answer 1

1

That doesn't look like the built-in navigation bar. I would suggest creating a custom navigation bar using safeAreaInset(edge: .top) { ... }, and hide the built-in one using .toolbarVisibility(.hidden, for: .navigationBar).

Then it's just a matter of controlling the scroll positions using ScrollPositions. Here is a toy example with the vertical scroll view showing three colors:

struct ContentView: View {
    @State private var verticalScrollPosition = ScrollPosition(id: "red")
    @State private var horizontalScrollPosition = ScrollPosition(id: "red")
    
    var body: some View {
        NavigationStack {
            ScrollView {
                VStack(spacing: 0) {
                    Color.red.containerRelativeFrame(.vertical)
                        .id("red")
                    Color.green.containerRelativeFrame(.vertical)
                        .id("green")
                    Color.blue.containerRelativeFrame(.vertical)
                        .id("blue")
                }
                .scrollTargetLayout()
            }
            .scrollPosition($verticalScrollPosition)
            .toolbarVisibility(.hidden, for: .navigationBar)
            .safeAreaInset(edge: .top) {
                VStack {
                    Text("Transactions")
                        .bold()
                        .font(.title)
                    ScrollView(.horizontal) {
                        HStack {
                            ForEach(["red", "green", "blue"], id: \.self) { color in
                                Text(color)
                                    .padding(10)
                                    .background(verticalScrollPosition.viewID(type: String.self) == color ? .black.opacity(0.2) : .clear, in: .capsule)
                                    .onTapGesture {
                                        verticalScrollPosition.scrollTo(id: color)
                                        horizontalScrollPosition.scrollTo(id: color)
                                    }
                            }
                        }
                        .scrollTargetLayout()
                        .onChange(of: verticalScrollPosition.viewID(type: String.self)) { _, newValue in
                            horizontalScrollPosition.scrollTo(id: newValue)
                        }
                    }
                    .scrollPosition($horizontalScrollPosition)
                    .frame(maxWidth: .infinity)
                    .padding(4)
                }
                .background(.bar)
            }
        }
    }
}

Output:

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.