Reputation: 2277
Trying to get the index of an array ([AnyObject]
). What's the part that I'm missing?
extension PageViewController : UIPageViewControllerDelegate {
func pageViewController(pageViewController: UIPageViewController, willTransitionToViewControllers pendingViewControllers: [AnyObject]) {
let controller: AnyObject? = pendingViewControllers.first as AnyObject?
self.nextIndex = self.viewControllers.indexOf(controller) as Int?
}
}
I have tried with Swift 1.2 this approach:
func indexOf<U: Equatable>(object: U) -> Int? {
for (idx, objectToCompare) in enumerate(self) {
if let to = objectToCompare as? U {
if object == to {
return idx
}
}
}
return nil
}
Upvotes: 4
Views: 2129
Reputation: 62062
We need to cast the object we're testing to a UIViewController
, since we know that are array of controllers
is holding UIViewController
s (and we know that UIViewController
s conform to Equatable
.
extension PageViewController : UIPageViewControllerDelegate {
func pageViewController(pageViewController: UIPageViewController, willTransitionToViewControllers pendingViewControllers: [AnyObject]) {
if let controller = pendingViewControllers.first as? UIViewController {
self.nextIndex = self.viewControllers.indexOf(controller)
}
}
}
The logic behind the error is that in order for the indexOf
method to compare the object you pass in, it must compare them using the ==
operator. The Equatable
protocol specifies that the class has implemented this function, so this is what indexOf
requires its arguments conform to.
Objective-C doesn't have this same requirement, but the actual Objective-C implementation ends up meaning that the argument is compared with objects in the array using the isEqual:
method (which NSObject
and therefore all Objective-C classes implement).
Upvotes: 5
Reputation: 3218
You have to cast the viewController property to an Array object:
if let controllers = self.viewControllers as? [UIViewController] {
self.nextIndex = controllers.indexOf(controller)
}
Upvotes: 0