Home > Software design >  Cannot convert value of type 'Binding<Data Struct?>' to expected argument type '
Cannot convert value of type 'Binding<Data Struct?>' to expected argument type '

Time:07-11

I have some code which makes a 'Marketplace'. There are 2 views in the marketplace, 'Shirts' & 'Trousers'. When the user taps on an item (a shirt or a pair of trousers), it takes them to a detailed view of the item. This is where I am facing an issue.

Here is the code for the marketplace:

    @StateObject var MarketplaceModel = MarketplaceViewModel()
    
    @State private var selectedMarketplaceFilter: MarketplaceFilterViewModel = .shirt
    
    @Namespace var animation : Namespace.ID
    
    @State var selectedShirt : Shirt!
    
    // Shared Data...
    @EnvironmentObject var sharedData: SharedDataModel
    
    @Binding var shirtData : Shirt
    @Binding var showDetailShirt: Bool
    
    @Binding var trouserData : Trouser
    @Binding var showDetailTrouser: Bool
    
    var body: some View {
        
        ScrollView(.vertical, showsIndicators: false) {
        
            VStack(spacing: 10){
                
                
                if !showDetailShirt && !showDetailTrouser {
                
                marketplaceFilterBar
                    
                }
                
                if selectedMarketplaceFilter == .shirt {
                    MarketplaceShirtView()
                }
                
                if selectedMarketplaceFilter == .trouser {
                    MarketplaceTrouserView()
                }
            }
        }

Here is the code for Shirt & Trouser (both the same data structure):

import SwiftUI
import FirebaseFirestoreSwift
import Firebase

struct Shirt: Identifiable, Codable {
    
    @DocumentID var id: String?
    var shirt_name: String
    var shirt_type: String
    var shirt_image: String
    var shirt_details: String
    var shirt_uid : String
 
}

My SharedDataModel:

import SwiftUI

class SharedDataModel: ObservableObject {
      
  // Detail Shirt Data...
    @Published var detailShirt : Shirt?
    @Published var showDetailShirt : Bool = false
    
    // Detail Trouser Data...
    @Published var detailTrouser : Business?
    @Published var showDetailTrouser : Bool = false
 
}

Here is the DetailView (same for Shirt & Trouser):

    @Binding var shirtData : Shirt
    @Binding var showDetailShirt: Bool
    
    @Namespace var animation: Namespace.ID
    
    // Shared Data Model...
    @EnvironmentObject var sharedData: SharedDataModel
    
    @EnvironmentObject var marketplaceData: MarketplaceViewModel
       
    
    var body: some View {
        
        VStack{
            
            VStack{
                
                HStack {
                    
                    Button(action: {

                                            withAnimation(.easeOut){showDetailShirt.toggle()}

                                        }) {
                                            Image(systemName: "arrow.backward.circle.fill")
   
                                        }
                    
                    
                        Text(shirtData.shirt_name)
 
                }
  
                GeometryReader { geo in
                    WebImage(url: URL(string: shirtData.shirt_image))
                        .resizable()
                        .scaledToFit()
                        .frame(width: geo.size.width * 1, height: 300)
                }
            }
            
            ScrollView(.vertical, showsIndicators: false) {
                
                VStack(alignment: .leading, spacing: 15) {
                    
                    Text(shirtData.shirt_name)
                    
                    Text(shirtData.shirt_type)
                    
                    Text(shirtData.shirt_details)

                }
            }
        }
    }

This is my MarketplaceShirtView code

    @StateObject var MarketplaceModel = MarketplaceViewModel()
    
    @State private var selectedMarketplaceFilter: MarketplaceFilterViewModel = .shirt
   
    @Namespace var animation : Namespace.ID
    
    @State var showDetailShirt = false
    @State var selectedShirt : Shirt!
    
    // Shared Data...
    @EnvironmentObject var sharedData: SharedDataModel
    
    var body: some View {
        
        var columns = Array(repeating: GridItem(.flexible()), count: 2)
        
        ZStack{
            
            VStack(spacing: 10){
                                
                HStack {
                    
                    Text("Find Shirts To Buy")
                        .font(.headline)
                }
                
                
                HStack(spacing: 5) {
                
                    HStack(spacing: 12){
                    
                    Image(systemName: "magnifyingglass")
                        .font(.subheadline)
                    
                    TextField("Search", text: $MarketplaceModel.search)
                        
                    }
                    .background(Color.white)
                      
                    Button {
                     
                    } label: {
                        Image(systemName: "slider.horizontal.3")
                            .foregroundColor(.gray)

                    }
            }
   
                if MarketplaceModel.shirts.isEmpty{

                    ProgressView()
                }
                else{
                    
                    ScrollView(.vertical, showsIndicators: false, content: {

                        LazyVGrid(columns: Array(repeating: GridItem(.flexible(),spacing: 10), count: 2),spacing: 20){
                            
                            ForEach(MarketplaceModel.filteredShirt){shirt in
                                
                                // This is a grid view of items (Shirts)
                                
                                    ShirtView(shirtData: shirt)

                                        .onTapGesture {

                                                selectedShirt = shirt
                                                showDetailShirt.toggle()
                            }
                        }
                    })
                }
            }
            //ERROR HERE: 'Cannot convert value of type 'Binding<Shirt?>' to expected argument type 'Binding<Shirt>'
            if selectedShirt != nil && showDetailShirt{
                
                ShirtDetailView(shirtData: $selectedShirt, showDetailShirt: $showDetailShirt,animation: _animation)
            }
       }

CodePudding user response:

In this case I think it should be enough just to unwrap binding, like

if selectedShirt != nil && showDetailShirt{
    
    ShirtDetailView(shirtData: Binding($selectedShirt)!, showDetailShirt: $showDetailShirt,animation: _animation)
}
  • Related