繁体   English   中英

有条件地在视图 SwiftUI 内包装代码

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM