英文:
Custom Scrollview in SwiftUI
问题
我在我的 `ContentView` 中有一段代码,看起来像这样,我希望不必要地重复 `ScrollView` 的修饰符。
```swift
if variable == false {
    ScrollView {
        // 这里是代码
    }
    .navigationBarTitleDisplayMode(.inline)
    .toolbar() {
        // 这里是代码
    }
} else {
    ScrollView(.horizontal, showsIndicators: false) {
        // 这里是代码
    }
    .navigationBarTitleDisplayMode(.inline)
    .toolbar() {
        // 这里是代码
    }
所以我尝试了这样做:
ScrollView(variable ? .horizontal : nil, showsIndicators: false) {
    // 这里是代码
}
.navigationBarTitleDisplayMode(.inline)
.toolbar() {
    // 这里是代码
}
但是它不起作用。你们是如何做到这种事情的?
也许,我应该创建自己的定制滚动视图,但是怎么做?
struct ScrollViewCustom /* 在这里写什么? */: View {
    @AppStorage("variable") private var variable = false
    @ViewBuilder /* 在这里写什么? */
    var body: some View {
        if variable == false {
            ScrollView()
        } else {
            ScrollView(.horizontal, showsIndicators: false)
        }
    }
}
提前感谢!
<details>
<summary>英文:</summary>
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!
</details>
# 答案1
**得分**: 2
```plaintext
三元操作符 `?` 总是需要两个选项(对于真/假)。所以你可以这样做:
`ScrollView(variable ? .horizontal : .vertical, showsIndicators: false)`
但请记住,在 `ScrollView` 内部,你需要根据滚动方向切换到 `VStack` 或 `HStack`。
所以实际上你的自定义方法可能更有用。它的用法如下:
```swift
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()
                }
            }
        }
    }
}
它的使用方式如下:
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() }
            }
        }
    }
}
<details>
<summary>英文:</summary>
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() }
        }
    }
}
}
</details>
				通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论