Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

SwiftUI: Unable to pass View into CustomView using Parameters

i’m currently having issues with sending a custom view through into another view as a parameter. All the other parameters work perfectly, it’s just the view.

I’ve setup everything within a single swift file to encapsulate the enviroment to trouble shoot but i just get:
Cannot convert value of type ‘Text’ to expected argument type ‘some View’

I’m most likely just missing something obvious, but i’ve tried with both any/some View, as well as variants with and without the @ViewBuilder but can’t seem to find a solution.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Here’s my code:

//
//  ProductsTabButton.swift
//  RM Product Guide
//
//  Created by Matthew Hardiman on 04/07/2023.
//

import SwiftUI

struct ProductsTabButton: View {
    
    @State var sheetActiveBool: Bool = false
    var dismissFunction: () -> Void
    var buttonColor: String = "rmWhite"
    var buttonText: String = "Button Text"
    var buttonIcon: String = "list.dash"
    var buttonView: some View = BackgroundView()
    
    
    var body: some View {
        
        // BUTTON STYLING
        Button(action: {
            sheetActiveBool.toggle()
        },label:{
            VStack(spacing: 0){
                Image(systemName: buttonIcon).productLinkBlockImage()
                Text(buttonText).productLinkBlockText()
            }
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .background(Color(buttonColor))
        })
        .sheet(isPresented: $sheetActiveBool, onDismiss: dismissFunction) {
            fetchView()
        }
        
    }
    
    
    @ViewBuilder
    func fetchView() -> some View {
         buttonView
    }
}

struct ProductsTabButton_Previews: PreviewProvider {
    static var previews: some View {
        ProductsTabButton(
            dismissFunction: {
                print("Test")
            },
            buttonColor: "rmYellow",
            buttonText: "Yellow",
            buttonIcon: "list.star",
            //buttonView: SearchView()
            buttonView: Text("Test")
        )
    }
}

Any help with this would be greatly appreciated.

Thank you!

>Solution :

You should not have Views as properties of Views. If it’s a customisable part of a bigger view, store a closure that returns a view instead.

struct ProductsTabButton<ButtonView: View>: View {
    
    @State var sheetActiveBool: Bool = false
    var dismissFunction: () -> Void
    var buttonColor: String
    var buttonText: String
    var buttonIcon: String
    var buttonView: () -> ButtonView

    // ...
}

You can pass this closure to sheet directly:

.sheet(isPresented: $sheetActiveBool, onDismiss: dismissFunction, content: buttonView)

If you want a default value for this property, write an initialiser in an extension:

struct ProductsTabButton<ButtonView: View>: View {
    
    // ...

    init(buttonColor: String = "rmWhite", buttonText: String = "Button Text", buttonIcon: String = "list.dash", @ViewBuilder buttonView: @escaping () -> ButtonView, dismiss: @escaping () -> Void) {
        self.buttonColor = buttonColor
        self.buttonIcon = buttonIcon
        self.dismissFunction = dismiss
        self.buttonText = buttonText
        self.buttonView = buttonView
    }

    // ...
}

extension ProductsTabButton where ButtonView == BackgroundView {
    init(buttonColor: String = "rmWhite", buttonText: String = "Button Text", buttonIcon: String = "list.dash", dismiss: @escaping () -> Void) {
        self.init(buttonColor: buttonColor, buttonText: buttonText, buttonIcon: buttonIcon, buttonView: { BackgroundView() }, dismiss: dismiss)
    }
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading