Home > front end >  Custom Scrollview in SwiftUI
Custom Scrollview in SwiftUI

Time:01-11

I have a piece of code that looks like this in my ContentView and I'd like to not repeat the ScrollView's modifiers unnecessarily.

if variable == false {
    ScrollView {
        // Code here
    }
    .navigationBarTitleDisplayMode(.inline)
    .toolbar() {
        // Code here
    }
} else {
    ScrollView(.horizontal, showsIndicators: false) {
        // Code here
    }
    .navigationBarTitleDisplayMode(.inline)
    .toolbar() {
        // Code here
    }

So I tried to do this instead:

ScrollView(variable ? .horizontal, showsIndicators: false : nil) {
    // Code here
}
.navigationBarTitleDisplayMode(.inline)
.toolbar() {
    // Code here
}

But it doesn't work. How do you guys do this kind of thing?

Maybe, I should create my own custom scrollview, but how ?

struct ScrollViewCustom /* What to write here? */ View {

    @AppStorage("variable") private var variable = false
    @ViewBuilder /* What to write here? */

    var body: some View {

        if variable == false {
            ScrollView()
        } else {
            ScrollView(.horizontal, showsIndicators: false)
        }
    }
}

Thanks in advance!

CodePudding user response:

The ternary operator ? always needs two options (for true/false). So you can do:

ScrollView(variable ? .horizontal : .vertical, showsIndicators: false)

But keep in mind that inside the ScrollView you'll then need to switch between a VStack or HStack depending on Scroll direction.

So actually your custom approach might be more useful. It goes like this:

struct ScrollViewCustom<V: View>: View {

    @AppStorage("variable") private var variable = false
    @ViewBuilder var content: () -> V

    var body: some View {

        if variable == false {
            ScrollView(.vertical) {
                VStack {
                    content()
                }
            }
        } else {
            ScrollView(.horizontal, showsIndicators: false) {
                HStack {
                    content()
                }
            }
        }
    }
}

and it would be used like this:

struct ContentView: View {
    
    @AppStorage("variable") private var variable = false
    
    var body: some View {
        NavigationStack {
            ScrollViewCustom {
                ForEach(0..<6) { item in
                    Text("Item \(item)")
                }
            }
            .navigationBarTitleDisplayMode(.inline)
            .toolbar() {
                Button("Switch") { variable.toggle() }
            }
        }
    }
}
  • Related