Search code examples
swiftswiftuivstackhstackswiftui-scrollview

How to build scrollable side menu using text rotation (or something similar) in SwiftUI?


I want to build a menu like the image bellow where I can scroll between menus. I did try multiple combinations with HStack/VStack in ScrollView and rotation modifier on Text and/or stacks. However, none of my attempts really works as intended.

enter image description here

Attempt 1

Code

struct ContentView: View {

    let sections = ["Exclusives", "Apple", "Android", "Videos", "Got a leak ?"].reversed()

    var body: some View {
        VStack(spacing: 0) {
        
            // Header
            Rectangle()
                .fill(Color(UIColor.quaternaryLabel))
                .frame(height: UIScreen.main.bounds.width * 0.2)
        
            // Vertical Menu + Content
            HStack(spacing: 0) {
            
                // Menu using VStack and rotation on Text
                ScrollView(.vertical) {
                    VStack(spacing: 32) {
                        ForEach(sections, id: \.self) { section in
                            Text(section)
                                // padding added on workingdog suggestion.
                                // But steal not producing exactly what I'm looking for. 🙁
                                .padding()
                                .rotationEffect(.degrees(-90), anchor: .center)
                        }
                    }
                }
            
                // Content Placeholder
                Rectangle()
                    .fill(Color(UIColor.tertiarySystemFill))
                    .frame(maxWidth: .infinity, maxHeight: .infinity)
            }
            .ignoresSafeArea(.all, edges: .bottom)
        }
    }
}

Result

enter image description here

Attempt 2

Code

struct ContentView: View {

    let sections = ["Exclusives", "Apple", "Android", "Videos", "Got a leak ?"].reversed()

    var body: some View {
        VStack(spacing: 0) {
        
            // Header
            Rectangle()
                .fill(Color(UIColor.quaternaryLabel))
                .frame(height: UIScreen.main.bounds.width * 0.2)
        
            // Vertical Menu + Content
            HStack(spacing: 0) {
            
                // Menu using rotation on HStack
                ScrollView(.vertical) {
                    HStack(spacing: 32) {
                        ForEach(sections, id: \.self) { section in
                            Text(section)
                        }
                    }
                    .rotationEffect(.degrees(-90), anchor: .center)
                }
            
                // Content Placeholder
                Rectangle()
                    .fill(Color(UIColor.tertiarySystemFill))
                    .frame(maxWidth: .infinity, maxHeight: .infinity)
            }
            .ignoresSafeArea(.all, edges: .bottom)
        }
    }
}

Result

enter image description here

Issue

I did try other methods with minor changes derived from these two 2 concepts. But as I understand it, the problem comes from using the rotation modifier, which rotate the content, not the view itself (causing unwanted behaviour).

Thank you for your help !


Solution

  • I did found a good solution using Attempt 2 and rotating the entire Text view using @robniper detailed answer here : https://stackoverflow.com/a/59802487/5541378