2

I am trying to iterate over an array of ViewControllers in Swift, but unfortunately I am getting compilation errors that I don't understand. Here is my relevant code:

let alertController = UIAlertController(title: "Error", message: "You have an error.", preferredStyle: .Alert)

let OKAction = UIAlertAction(title: "OK", style: .Default) { (action:UIAlertAction!) in
    print("you have pressed OK button");
    //below is my loop causing me trouble
    for (i in 0..< self.navigationController?.viewControllers.count) {
        if (self.navigationController?.viewControllers[i].isKindOfClass(MyViewController) == true) {
            self.navigationController?.popToViewController(self.navigationController!.viewControllers[i] as! MyViewController, animated: true)

            break;
        }
    }
}
alertController.addAction(OKAction)

self.presentViewController(alertController, animated: true, completion:nil)

However, I keep getting errors from Xcode asking me to insert "," as a separator in my for loop statement. Can anyone see what it is I'm doing wrong?

1
  • 1
    @EricAya == true actually makes some sense with optional booleans, however it's still probably better to use ?? but that's just a matter of opinion. Commented Aug 26, 2016 at 16:11

4 Answers 4

3

Rather than using a numeric for loop, why don't you use for... in syntax?

if let navController = self.navigationController {
  for aVC in navController.viewControllers {
    if aVC..isKindOfClass(MyViewController) {
      navController.popToViewController(aVC, animated: true)
      break
    }
  }
}

I used optional binding to collapse the self.navigationController? into navController, and for...in syntax.

Also, I don't think you need to cast your view controller to your MyViewController class since all you are doing with it is sending it to the popToViewController function, which takes ANY UIViewController.

EDIT:

If you need the index for the items in your array, you can use the enumerate function on your array, which returns a set of tuples:

for (index, aVC) in navController.viewControllers.enumerate() {
  //Do stuff
}
Sign up to request clarification or add additional context in comments.

2 Comments

This is the most straight-forward and correct way to go about it unless you actually need access to the index variable itself.
And if you want the index index as well you can use for (index, aVC) in navController.viewControllers.enumerate()
2

Just remove the brackets from your for loop and add proper spacing between 0 and self:-

for i in 0 ..< self.navigationController?.viewControllers.count {
                    if(self.navigationController?.viewControllers[i].isKindOfClass(MyViewController) == true) {

                        self.navigationController?.popToViewController(self.navigationController!.viewControllers[i] as! MyViewController, animated: true)

                        break;
                    }
                }

Comments

1

Inconsistent spacing around ..<.

You have to choose either 0 ..< self. or 0..<self., otherwise the operator will be considered a prefix/postfix operator and not an infix one.

Also, the for-in is composed from two expressions:

for expr1 in expr2

therefore you cannot wrap the keyword in into parenthesis with them:

for i in (0 ..< self.navigationController?.viewControllers.count) {

1 Comment

That still outputs an error to insert a comma., you need to remove the brackets.
0

Remove the brackets from your for-in loop, the extra space in 0..< self.. and consider unwrap the value of optional count in the chain.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.