Reputation: 91
I have AnyObject
var currentObject : AnyObject
its value depends on if statement :
if sender.tag == 1 {
currentObject = object1()
}
else if sender.tag == 2 {
currentObject = object2()
}
.....
etc
numberOfRowsInSection function:
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return(currentObject.count)
}
cellForRowAt function:
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath as IndexPath) as UITableViewCell
let p = currentObject.item[indexPath.row]
cell.textLabel?.text = p.something
return(cell)
}
and I want to use this line at cellForRowAt function to retrieve cell content from different objects
let p = currentObject.item[indexPath.row]
I got an error says: 'AnyObject' is not a subtype of 'NSIndexPath'
I want my AnyObject to be treated as the object that I already assigned to it.
any suggestions ?
Upvotes: 0
Views: 89
Reputation: 11435
AnyObject
can be treated as a "base class" for all objects.
So if you have:
let index: AnyObject = IndexPath(item: 0, section: 0)
You can use it by casting it to the desired type:
if let indexPath = index as? IndexPath {
// indexPath is type of IndexPath
}
Not all AnyObject
can be IndexPath
, thats why the cast can fail.
This is really basic learning here. I Suggest you check out A Swift Tour by Apple.
Upvotes: 2
Reputation: 285260
You are strongly discouraged from using that kind of approach.
Use a protocol based solution.
In your example both types are supposed to respond to item
so declare a protocol
protocol HasItem {
var items : [MyType] { get }
}
I'm using the plural form items
as the type is an array.
Then adopt the protocol in your object classes
struct Object1 : HasItem {
var items = [MyType]()
}
struct Object2 : HasItem {
var items = [MyType]()
}
Now you can declare currentObject
as HasItem
var currentObject : HasItem
Since the compiler knows that an object which conforms to HasItem
has an items
array this will compile flawlessly
let p = currentObject.items[indexPath.row]
The return value in numberOfRowsInSection
is not logical. Most likely this is intended
return currentObject.items.count
And please be aware that return
is not a function, there are no parentheses.
If you want to use other common properties and functions in the protocol type you have to add those to the protocol.
And if MyType
could be also of different types use another protocol with a property something
.
Upvotes: 0
Reputation: 7591
What you are referring to as an Object is actually a Dictionary. Object is not something that exists in Swift in the way that you're thinking about.
That said, what you might want to do is cast your AnyObject as follows:
if let myDict = currentObject.item as? [AnyObject],
let p = myDict[indexPath.row] {
// p is now an AnyObject, cast to whatever you need again
}
Swift is a very strict language so you'll need to make sure that Swift always knows what type something is. Imagine this object:
{
"id": 10,
"label": "hello world"
}
You would extract the id and label in Swift like this:
let myObject: [String: AnyObject] = // import the above object as you please
let label = myObject["label"] as? String // cast to string so Swift knows what the type of the label is
let id = myObject["id"] as? Int // must cast again so Swift knows the type of the id.
Hope this is of some help to you :)
Upvotes: 0