I have a struct called trip
.
struct trip {
var name: String
var description: String
var elements: [Any] = []
mutating func addItemToElements(newValue: Any) {
elements.append(newValue)
}
}
As you can see, there is an array inside. I'm adding some other structs like element_flight
into this array by function addItemtoElements
.
struct element_flight {
var origin: String
var destination: String
var flightno: String
var departure: NSDate
var arrival: NSDate
var seat: String
}
Then I'm trying to create a list using table view:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "elementTrip", for: indexPath) as! CellInElementsOfTripsTableViewCell
let elem = trips[0].elements[indexPath.row]
cell.mainTextLabel.text = elem.origin //it doesn't work
return cell
}
I can't get any of parts of struct (like origin
in code). What am I doing wrong?
I'm creating similar structs to element_flight
and it could be the best way to put it in one array and then show in table view.
A simple, naive solution would be to cast elem
to the correct type:
cell.mainTextLabel.text = (elem as! element_flight).origin
However, since the elements
array can store Any
, what if elem
is some other type? Obviously, it will crash!
I don't understand why you want to store a bunch of Any
in elements
. This is a sign or bad code. Any
is seldom used in Swift.
If you're just going to store some types, but not Any
types, in elements
, create a protocol and make all the types that you want to store conform to it. At least you get a little bit of type safety.
Let's say your array will only contain two structs: element_flight
and SomeOtherStruct
. You should do something like this:
protocol SomeProtocol { // please give this a proper name yourself
// properties/methods that are common among element_flight and SomOtherStruct
}
struct element_flight: SomeProtocol {
// ...
}
struct SomeOtherStruct: SomeProtocol {
// ...
}
And change the array to be of type [SomeProtocol]
.
Now in the cellForRowAtIndexPath
method, you need to test whether elem
is element_flight
or SomeOtherStruct
:
if let flight = elem as? element_flight {
cell.mainTextLabel.text = flight.origin
} else if let someOtherStuff = elem as? SomeOtherStruct {
// do some other stuff
} else {
// something's wrong if this is executed, maybe call fatalError
}
You should cast them to FlightInfo
(use this name instead of element_flight
- type name in Swift should be written in CamelCase).
override func tableView(_ tableView: UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "elementTrip",
for: indexPath) as! CellInElementsOfTripsTableViewCell
if let flightInfo = trips[0].elements[indexPath.row] as? FlightInfo {
cell.mainTextLabel.text = flightInfo.origin //it doesn't work
}
return cell
}
另一种方法是将不同的结构存储在Any
数组中,并在将其复制到变量之前使用is
变量来测试类型。
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.