自定义 SwiftUI 中的滚动视图

huangapple go评论65阅读模式
英文:

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&#39;d like to not repeat the `ScrollView`&#39;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&#39;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(&quot;variable&quot;) 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&#39;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(&quot;variable&quot;) private var variable = false
@ViewBuilder var content: () -&gt; 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(&quot;variable&quot;) private var variable = false

var body: some View {
    NavigationStack {
        ScrollViewCustom {
            ForEach(0..&lt;6) { item in
                Text(&quot;Item \(item)&quot;)
            }
        }
        .navigationBarTitleDisplayMode(.inline)
        .toolbar() {
            Button(&quot;Switch&quot;) { variable.toggle() }
        }
    }
}

}


</details>



huangapple
  • 本文由 发表于 2023年1月9日 04:28:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/75051046.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定