Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I pass 2 content parameters to a SwiftUI View?

Tags:

ios

swift

swiftui

I have a Card view that takes in a content parameter to display in the bordered view.

public struct Card<Content: View>: View {
    private let content: Content

    public init(@ViewBuilder content: () -> Content) {
            self.content = content()
    }
    
    public var body: some View {
       content
          .padding(16)
          .frame(maxWidth: .infinity)
          .background(TileShape(cornerRadius: 8, backgroundColor: backgroundColor))
          .clipShape(RoundedRectangle(cornerRadius: 8))
   }
}

What I would like to do is introduce a stacked Card. Maybe something like this:

public struct Card<Content: View>: View {
    private let content: Content
    private let stackedContent: Content

    public init(@ViewBuilder content: () -> Content, @ViewBuilder stackedContent: () -> Content) {
            self.content = content()
            self.stackedContent = stackedContent()
    }
    
    public var body: some View {
        ZStack {
           content
              .padding(16)
              .frame(maxWidth: .infinity)
              .background(TileShape(cornerRadius: 8, backgroundColor: backgroundColor))
              .clipShape(RoundedRectangle(cornerRadius: 8))
              
            stackedContent
                /// put stuff here to align it correctly
        }
   }
}

While I can create this initializer, the problem comes in trying to give it content.

in my calling code I have

   Tile {
      Text("Card contents")
   }

When I try to introduce the 2nd card, I get segment faults during compilation.

   Tile(stackedContent: stackedCard) {
      Text("Base Card Contents")
   }


    @ViewBuilder
    var stackedCard: Card<some View> {
        Card {
            Text("Stacked Card Here")
        }
    }

Is my goal possible with SwiftUI? I'm limited to using iOS 14 as the target os version.

You might be tempted to ask, "Why not just use 2 Cards at the point of use and align them there?". The answer is, I am trying to replicate something in UIKit in a transition to SwiftUI.

like image 611
Aaron Bratcher Avatar asked Oct 29 '25 21:10

Aaron Bratcher


1 Answers

You need to give different content types for generics (because in general they can differ)

So a fix would be

public struct Card<Content1: View, Content2: View>: View {
    private let content: Content1
    private let stackedContent: Content2

    public init(@ViewBuilder content: () -> Content1, @ViewBuilder stackedContent: () -> Content2) {
            self.content = content()
            self.stackedContent = stackedContent()
    }

// ...
}
like image 147
Asperi Avatar answered Nov 01 '25 10:11

Asperi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!