Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

ios - Is there any way to create/extract an array of Views using @ViewBuilder in SwiftUI

I'm trying to create a simple struct that accepts an array of Views and returns an ordinary VStack containing those Views except they all are stacked diagonally.

Code:

struct LeaningTower<Content: View>: View {
    var views: [Content]
    var body: some View {
        VStack {
            ForEach(0..<views.count) { index in
                self.views[index]
                    .offset(x: CGFloat(index * 30))
            }
        }
    }
}

Now this works great but I always get annoyed whenever I have to call it:

LeaningTower(views: [Text("Something 1"), Text("Something 2"), Text("Something 3")])

Listing the views in an array like that seems extremely odd to me so I was wondering if there was a way I could use @ViewBuilder to call my LeaningTower struct like this:

LeaningTower {  // Same way how you would create a regular VStack
    Text("Something 1")
    Text("Something 2")
    Text("Something 3")
    // And then have all of these Text's in my 'views' array
}

If there's a way to use @ViewBuilder to create/extract an array of Views please let me know.

(Even if it isn't possible using @ViewBuilder literally anything that will make it look neater will help out a lot)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

literally anything that will make it look neater will help out a lot

Well, this will get you closer:

Add this init to your LeaningTower:

init(_ views: Content...) {
    self.views = views
}

Then use it like this:

LeaningTower(
    Text("Something 1"),
    Text("Something 2"),
    Text("Something 3")
)

You could add your offset as an optional parameter:

struct LeaningTower<Content: View>: View {
    var views: [Content]
    var offset: CGFloat
    
    init(offset: CGFloat = 30, _ views: Content...) {
        self.views = views
        self.offset = offset
    }
    
    var body: some View {
        VStack {
            ForEach(0..<views.count) { index in
                self.views[index]
                    .offset(x: CGFloat(index) * self.offset)
            }
        }
    }
}

Example usage:

LeaningTower(offset: 20,
    Text("Something 1"),
    Text("Something 2"),
    Text("Something 3")
)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...