简体   繁体   中英

Inject a view into a view in SwiftUI

I'm trying to inject a view into another view to avoid code duplication.

I came up with the idea of this:

struct WrapperView: View {
    
    var injectedView: some View
    
    var body: some View {
        VStack {
            injectedView
        }
    }
}

But I get an error: Property declares an opaque return type, but has no initializer expression from which to infer an underlying type

How can I achieve something like this in SwiftUI?

You can use generics. Here, the type Content conforms to View , so we can pass in something like Text .

Something like:

struct WrapperView<Content: View>: View {
    let injectedView: Content
    
    var body: some View {
        VStack {
            injectedView
        }
    }
}

Usage:

WrapperView(injectedView: Text("Hello"))

If you want to call it similar to when creating the VStack like this:

WrapperView {
    Text("Hello")
}

You can change WrapperView to this:

struct WrapperView<Content: View>: View {
    private let injectedView: () -> Content
    
    init(@ViewBuilder injectedView: @escaping () -> Content) {
        self.injectedView = injectedView
    }
    
    var body: some View {
        VStack(content: injectedView)
    }
}

We use @ViewBuilder so we can build view content in the closure, allow us to do the following:

WrapperView {
    Text("Hello")
    
    Text("world!")
}

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.

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