[英]Conditionally wrap code inside view SwiftUI
我想在基于 boolean 的滚动视图中制作我的代码
像这样的东西:
ScrollView{
Vstack {
}
Hstack {
}
}.isWrapped(true)
因此,如果 bool 为真,则内容将包装在 ScrollView 中,如果不是,我将按原样获取内容。 (没有 scrollView 父级)
我尝试了多种方式,我看到的唯一可能是 2 块代码,不是很好的实践思想。
由于 SwiftUI 的性质,您无法在不移除子项的情况下移除父项。 正如您在编辑中提到的,这将需要两个代码块。 但是,您可以通过两种不同的方式使其更加友好。
第一种方式是可重用组件。 它需要一个 Binding isVisible
变量和内容。
struct ConditionalScrollView<Content: View>: View {
@Binding private var isVisible: Bool
private var builtContent: Content
init(isVisible: Binding<Bool>, content: () -> Content) {
self._isVisible = isVisible
builtContent = content()
}
var body: some View {
if isVisible {
ScrollView { builtContent }
} else {
builtContent
}
}
}
使用这个新组件,就是简单的在想要手动调整的区域替换使用ScrollView
。 IE:
struct ContentView: View {
@State var isVisible = true
var body: some View {
ConditionalScrollView(isVisible: $isVisible) {
Text("Hello, world!")
.padding()
}
}
}
但这不是您唯一的选择。
如果您想让事情尽可能简单,您可以使用简单的ViewBuilder
来实现。 在ViewBuilder
中创建您不想更改的视图,然后在ScrollView
周围创建一个条件,同时将变量作为内容。 它看起来如下:
struct ContentView: View {
@State private var isVisible = true
@ViewBuilder private var mainContent: some View {
Text("Hello, world!")
.padding()
}
var body: some View {
if isVisible {
ScrollView { mainContent }
} else {
mainContent
}
}
}
您可能已经意识到,这是 SwiftUI 的限制之一。 但这可以被认为是一种优势,因为您将始终知道视图的父级是否存在。
我希望这个小花絮有所帮助,快乐的编码!
您还可以使它更容易:
@State var isWraped : bool = true
var body: some View {
if isWrapped {
ScrollView {
YourView()
}
else {
YourView()
}
一种方法是始终使用ScrollView
,但告诉它不要滚动。 如果您将空集作为第一个参数传递给ScrollView
,它将不会滚动。
ScrollView(shouldScroll ? .vertical : []) {
// content here
}
另一种方法是在您建议的isWrapped
修饰符中从ScrollView
中提取内容,如下所示:
extension ScrollView {
@ViewBuilder
func isWrapped(_ flag: Bool) -> some View {
if flag { self }
else { self.content }
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.