I am looking to call two variables but the method I am trying to implement does not work.
Unfortunately, Xcode says Extra argument in call.
I am a newbie, can someone help me to understand what is going wrong ?
Thank you !!
struct Card {
let content : [String]
let names:[String]
static let allCards:[Card] =
[
Card(content: ["content1","content2"], names: ["name1","name2"]),
Card(content: ["content3","content4"], names: ["name3","name4"])
]
}
struct Play {
let cards = Card.allCards.shuffled()
var currentCardIndex = 0
var currentCard:Card {
cards[currentCardIndex]
}
}
class GameViewModel {
@Published var play = Play()
var cardContent:[String] {
play.currentCard.content
}
var cardnames:[String] {
play.currentCard.names
}
}
struct CardView:View {
let contentString:String
let nameString:String
var body: some View{
HStack{
Text(contentString)
Text(nameString)
}
}
}
struct ContentView: View {
var viewModel = GameViewModel()
var body: some View {
HStack{
/ Warning: Extra argument in call
ForEach(viewModel.cardContent, viewModel.cardnames,id:\.self, content:{ card in
CardView(contentString: card, nameString: card).frame(minWidth: 135, idealWidth: 250, maxWidth: 135, minHeight: 135, idealHeight: 250, maxHeight: 135, alignment: .center).aspectRatio(2/2, contentMode:.fit)
})
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
CodePudding user response:
The root cause:
In ForEach(viewModel.cardContent, viewModel.cardnames either viewModel.cardContent or viewModel.cardnames is an extra argument, as ForEach can iterate only one array, and you are passing 2 arrays.
The simplest fix: pass only one array (viewModel.play.cards) in
ForEach(viewModel.play.cards, id:\.self, content: { card in
CardView(contentString: card.content, nameString: card.names).frame(minWidth: 135, idealWidth: 250, maxWidth: 135, minHeight: 135, idealHeight: 250, maxHeight: 135, alignment: .center).aspectRatio(2/2, contentMode:.fit)
})
The example above still may not compile because of CardView(contentString: card constructor, but that's another problem :)
CodePudding user response:
Yes, it throws an error because you are passing more than the available arguments to constructor of ForEach
You can see the below available constructor of ForEach, then you come to know which argument you are passing it as extra to the constructor
init(_ data: Data, @AccessibilityRotorContentBuilder content: @escaping (Data.Element) -> Content)
init(_ data: Data, id: KeyPath<Data.Element, ID>, @AccessibilityRotorContentBuilder content: @escaping (Data.Element) -> Content)
init(_ data: Data, @ViewBuilder content: @escaping (Data.Element) -> Content)
init(_ data: Data, id: KeyPath<Data.Element, ID>, @ViewBuilder content: @escaping (Data.Element) -> Content)
init<C>(_ data: Binding<C>, @ViewBuilder content: @escaping (Binding<C.Element>) -> Content) where Data == LazyMapSequence<C.Indices, (C.Index, ID)>, ID == C.Element.ID, C : MutableCollection, C : RandomAccessCollection, C.Element : Identifiable, C.Index : Hashable
init<C>(_ data: Binding<C>, id: KeyPath<C.Element, ID>, @ViewBuilder content: @escaping (Binding<C.Element>) -> Content) where Data == LazyMapSequence<C.Indices, (C.Index, ID)>, C : MutableCollection, C : RandomAccessCollection, C.Index : Hashable
And in your code
//viewModel.cardnames is the extra argument you are passing to ForEach
ForEach(viewModel.cardContent, viewModel.cardnames,id:\.self, content:{ card in
CardView(contentString: card, nameString: card).frame(minWidth: 135, idealWidth: 250, maxWidth: 135, minHeight: 135, idealHeight: 250, maxHeight: 135, alignment: .center).aspectRatio(2/2, contentMode:.fit)
})
