Cannot convert value of type 'int' to expected argument type 'string'?

Hello everyone. I was a building a test app when I encountered this error:

I'm new to indices and am a bit confused by them. Can someone please explain the error to me and show me a possible solution to it? Many thanks!

Here is my code:

import SwiftUI

struct GameView: View { @StateObject var viewModel = GameViewModel()

var body: some View {
    ZStack {
        GameColor.main.ignoresSafeArea()
        VStack {
            Text(viewModel.progressText)
                .padding()
            Spacer()
            Text(viewModel.questionText)
                .font(.title)
                .multilineTextAlignment(.center)
                .padding()
            Spacer()
            Spacer()
            HStack {
                
                 ForEach(0..<viewModel.answerIndices.count, id: \.self) { index in
                     AnswerButton(text: viewModel.answerIndices[index]) {
              //  ForEach(viewModel.answerIndices) { index in
                 //   AnswerButton(text: viewModel.answerText(for: index)) {
                        viewModel.makeSelectionForCurrentQuestion(at: index)
                    }
                    .background(viewModel.colorForButton(at: index))
                    .disabled(viewModel.selectionWasMade)
                }
            }
            if viewModel.selectionWasMade {
                Button(action: viewModel.advanceGameState,
                       label: {
                        BottomText(str: "Next")
                })
            }
        }.padding(.bottom)
    }
    .navigationBarHidden(true)
    .background(resultsNavigationLink)
}
private var resultsNavigationLink: some View {
    NavigationLink(
        destination: ResultsView(viewModel: ResultsViewModel(selectionCount: viewModel.selectionCount, gameStartTime: viewModel.gameStartTime, gameEndTime: Date())),
        isActive: .constant(viewModel.gameIsOver),
        label: { EmptyView() })
}

}

struct AnswerButton: View { let text: String let onClick: () -> Void var body: some View { Button(action: { onClick() }) { Text(text) } .padding() .border(Color.blue, width: 4) } }

struct ContentView_Previews: PreviewProvider { static var previews: some View { NavigationView { GameView() } } }

(Above is the view; this is the model:

import SwiftUI

class GameViewModel: ObservableObject { @Published var game = Game()

var questionText: String {
    game.currentQuestion.questionText
}

var answerIndices: Range<Int> {
    game.currentQuestion.possibleAnswers.indices
}

var correctAnswerIndex: Int {
    game.currentQuestion.correctAnswerIndex
}

var progressText: String {
    "Question \(game.currentQuestionIndex + 1) / \(game.questionCount)"
}

var selectionWasMade: Bool {
    game.selections[game.currentQuestion] != nil
}

var selectionCount: (Int, Int) {
    game.selectionCount
}

var gameIsOver: Bool {
    game.gameIsOver
}

var gameStartTime: Date {
    game.startTime
}

func answerText(for index: Int) -> String {
    game.currentQuestion.possibleAnswers[index]
}

func advanceGameState() {
    game.advanceGameState()
}

func makeSelectionForCurrentQuestion(at index: Int) {
    game.makeSelection(at: index)
}

func colorForButton(at buttonIndex: Int) -> Color {
    guard let selectedIndex = game.selections[game.currentQuestion], selectedIndex == buttonIndex else { return .clear }
    if selectedIndex == correctAnswerIndex {
        return .green
    } else {
        return .red
    }
}

}

Thanks for the help in advance!

Answered by Claude31 in 759549022

You should use the viewModel as follows:

                    ForEach(0..<viewModel.answerIndices.count, id: \.self) { index in
                        AnswerButton(text: viewModel.answerText(for: index) ) {

Welcome to the forum.

You call:

                     AnswerButton(text: viewModel.answerIndices[index]) {

So viewModel.answerIndices[index] should be a string, as required by text parameter

struct AnswerButton: View {
  let text: String 
  let onClick: () -> Void 

  var body: some View {
    Button(action: { onClick() }) { Text(text) } .padding() .border(Color.blue, width: 4)
  }
}

But it is an Int (an element in the Range<Int> collection) as per declaration

var answerIndices: Range<Int> {
    game.currentQuestion.possibleAnswers.indices
}

Which text do you want to show in button ?

Is it answerText(for index: Int) ?

If so, you should call

                     AnswerButton(text: answerText(for: index)) {

So the cause of error is clear, but what you should do is hard to be sure with information you provided.

If that does not answer your question, please provide more details. Otherwise, don't forget to close the thread by marking the correct answer.

import Foundation struct Question: Hashable { let questionText: String let possibleAnswers: [String] let correctAnswerIndex: Int

static let allQuestions: [Question] = [
    Question(questionText: "What was the first computer bug?",
             possibleAnswers: [
                "Fly",
                "Moth",
                "Ant",
                "Beetle",
             ],

So you have

struct Question: Hashable {
  let questionText: String 
  let possibleAnswers: [String]
  let correctAnswerIndex: Int

  static let allQuestions: [Question] = [
    Question(questionText: "What was the first computer bug?",
             possibleAnswers: [
                "Fly",
                "Moth",
                "Ant",
                "Beetle",
             ],

And you want to display all the possible answers for a single question, viewModel.questionText ?

What do you get when you try ? What doesn't work ?

                 ForEach(0..<viewModel.answerIndices.count, id: \.self) { index in
                     AnswerButton(text: answerText(for: index)) {

It would help to have the complete code to be able to answer more precisely.

Test

Accepted Answer

You should use the viewModel as follows:

                    ForEach(0..<viewModel.answerIndices.count, id: \.self) { index in
                        AnswerButton(text: viewModel.answerText(for: index) ) {
Cannot convert value of type 'int' to expected argument type 'string'?
 
 
Q