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)
}