2

I'm trying to check if the back button on my view controller was pressed but I'm having a hard time detecting this in Swift.

With this code:

    if (contains(self.navigationController?.viewControllers, self)) {
        println("Back button not pressed")
    } else {
        self.updateSearchQueryModel()
    }

I am getting the error:

Could not find an overload for contains that accepts the supplied arguments.

I did get the result that I wanted in another fashion but I am still confused as to why this error is happening.

Why is this happening? Can I not check if self exists in an array?

Source of original code in Objective C that I couldn't translate to Swift: Setting action for back button in navigation controller

-(void) viewWillDisappear:(BOOL)animated {
    if ([self.navigationController.viewControllers indexOfObject:self]==NSNotFound) {
       // back button was pressed.  We know this is true because self is no longer
       // in the navigation stack.  
    }
    [super viewWillDisappear:animated];
}

Please do not tell me how to detect that the back button was pressed. I already figured that out here.

Source of solution to objective: Detecting when the 'back' button is pressed on a navbar

Community
  • 1
  • 1
ovatsug25
  • 7,786
  • 7
  • 34
  • 48

2 Answers2

3

If you look at the declaration of the viewControllers property, you notice that it's [AnyObject]! and not [UIViewController]!.

The contains function requires that the sequence element implements the Equatable protocol, which AnyObject doesn't.

The solution is to make an explicit downcast of that array, using optional binding:

if let viewControllers = self.navigationController?.viewControllers as? [UIViewController] {
    if (contains(viewControllers, self)) {
        println("Back button not pressed")
    } else {
        self.updateSearchQueryModel()
    }
}
Antonio
  • 71,651
  • 11
  • 148
  • 165
0

I'm new in Swift but try this:

if let controllers = self.navigationController?.viewControllers as? [UIViewController] {
    if contains(controllers, self) {
        DLog("!")
    }
}

You're getting error because you're passing optional as contains()'s first argument

Kubba
  • 3,390
  • 19
  • 34
  • You're correct that its being optional is a issue, but if that was it, we could solve it by simply unwrapping the optional. The more serious problem is that `contains` requires the object to conform to `Equatable`. In your optional binding process, you coincidentally addressed this second, more fundamental problem. – Rob Apr 30 '15 at 00:13