skip to Main Content

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

2

Answers


  1. 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 🙂

    Login or Signup to reply.
  2. 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)
                })
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search