This is my first question so please, be gentle!
I've been debugging my code and searching stackexchange.com for a while, and as best as I can tell, my problem has to do with return an array from a function. I can assure you that this is not a homework question, and I've tried going through Stackoverflow for solutions, and I'm at my wits end!
The ActiveModelResponseList
is used to display a list of acceptable responses to the user, arranged in a List
form:
struct ActiveModelResponseList: View {
var activeModel: ActiveModel
var body: some View {
List(activeModel.validResponses()) { /* XCode error: "Cannot convert value of type
'[ValidResponse]' to expected
argument type 'Range<Int>'" */
HStack { /* XCode error: "Contextual closure type '() -> TupleView<(Text, Text, Spacer)>'
expects 0 arguments, but 1 was used in closure body" */
Text($0.response)
Text($0.narrative)
Spacer()
}.padding(10)
}
}
}
I have tried a number of different ways to restructure the above body
, and it's specifically that activeModel.validResponses()
that causes the errors. If I delete it and populate the list with hard coded values, it works just fine.
That function, activeModel.validResponses()
comes from the ActiveModel
class, as follows:
class ActiveModel {
var baseModel: ModelData
private var responses: [Int]
private var activeElement: Int
// Although forThisElement is unused in the base function, ActiveModel still has
// such an element, used for other purposes
public func validResponses() -> [ValidResponse] {
return (baseModel.validResponses(forThisElement: activeElement))
}
}
This, in turn, comes from a base class, ModelData
. Note that forThisElement
is not actually required for this function, but is included to maintain polymorphism (i.e. other models will use it). As you can see, ModelData.validResponses
returns a [ValidResponse]
class ModelData: Hashable, Codable, Identifiable {
var id: Int
var valid_response: [String]
var valid_response_narrative: [String]
public func validResponses(forThisElement: Int) -> [ValidResponse] {
// forThisElement is currently an unused input variable,
// but is required for compatibility with other classes
var thisResult: [ValidResponse] = []
for thisResponse in 0..<valid_response.count {
thisResult[thisResponse].id = thisResponse
thisResult[thisResponse].response = valid_response[thisResponse]
thisResult[thisResponse].narrative = valid_response_narrative[thisResponse]
}
return thisResult
}
}
The ValidResponse
is just an ordinary struct, defined as follows:
struct ValidResponse: Identifiable, Hashable {
var id: Int = 0
var response: String = "0"
var narrative: String = "Default"
}
The preview is being generated for an iPod touch (7th generation), I'm using Xcode Version 13.1 (13A1030d), and am compiling using MacOS 12.0.1, on a mid-2015 MacBook Pro.
I found the following answers on stackexchange, but I feel none the wiser after having read them (and, as these answers are quite dated, I wonder if they're still relevant):
- returning an array from a function in Swift
- Return Array from Function in Swift
- Square every element in an Int of arrays. (Swift)
Can anyone provide any guidance?
CodePudding user response:
The first error message is nonsense. Fix the second and it will disappear.
The title of your question is unrelated to your actual problem, which is that you're trying to use a positional parameter from an outer closure. That doesn't work; they can't propagate that way. Every new closure scope gets its own set of positional parameters, and HStack.init
doesn't use any, as the error tells you.
Fix: name the argument.
List(activeModel.validResponses()) { response in
HStack {
Text(response.response)
Text(response.narrative)
CodePudding user response:
@Jessy, to clarify, I tried making the following change, but it too didn't work:
struct ActiveModelResponseList: View {
var activeModel: ActiveModel
var validResponses: [ValidResponse] = []
var body: some View {
let someResp = activeModel.validResponses()
List {
Text("\(someResp.count)")
}
}
}
But, alas, it still doesn't work! It crashes on that let
line.