I want to make my code inside a scrollview based on a boolean
Something like this:
ScrollView{
Vstack {
}
Hstack {
}
}.isWrapped(true)
So if the bool is true, the content is wrapped inside a ScrollView, if not, I just get the content as is. (without the scrollView parent)
I tried with multiples way, the only thing I see as possible is 2 blocks of code, not good practice thought.
Because of the nature of SwiftUI, you can't remove the parent without removing children. As you mentioned in your edit, this will require two blocks of code. But, you can make it much more friendly in two different ways.
The first way is a reusable component. It takes a Binding isVisible
variable and the content.
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
}
}
}
To use this new component is to simply replace the use of ScrollView
in the area that you want to manually adjust. IE:
struct ContentView: View {
@State var isVisible = true
var body: some View {
ConditionalScrollView(isVisible: $isVisible) {
Text("Hello, world!")
.padding()
}
}
}
But this is not your only option.
If you want to keep things as simple as possible, you can achieve this using a simple ViewBuilder
. Create the view you don't want to change inside the ViewBuilder
, and then create a condition around the ScrollView
, all the while placing the variable as the content. It would look as follows:
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
}
}
}
As you've probably come to realize, this is one of the limitations of SwiftUI. But it can be considered a strength because you will always know if a view's parent is there or not.
I hope this little tidbit helped, happy coding!
You can also make it even easier:
@State var isWraped : bool = true
var body: some View {
if isWrapped {
ScrollView {
YourView()
}
else {
YourView()
}
One way is to always use a ScrollView
, but tell it not to scroll. If you pass an empty set as the first argument to ScrollView
, it won't scroll.
ScrollView(shouldScroll ? .vertical : []) {
// content here
}
Another way is to extract the content back out of the ScrollView
in your proposed isWrapped
modifier, like this:
extension ScrollView {
@ViewBuilder
func isWrapped(_ flag: Bool) -> some View {
if flag { self }
else { self.content }
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.