bobster
bobster

Reputation: 311

Swift popToViewController

Good day guys, I'm learning Swift, needed some help here.

The user are signing up and selected their image. Upon dismissing the image picker, I would like to have the ComposeViewController appear.

Here is the code:

func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: NSDictionary!) {
    let pickedImage:UIImage = info.objectForKey(UIImagePickerControllerOriginalImage) as UIImage

    //Scale Down Image
    let scaledImage = self.scaleImageWith(pickedImage, and: CGSizeMake(100,100))

    let imageData = UIImagePNGRepresentation(scaledImage)

    let imageFile:PFFile = PFFile(data: imageData)

    PFUser.currentUser().setObject(imageFile, forKey: "profileImage")
    PFUser.currentUser().saveInBackgroundWithTarget(nil, selector: nil)

    picker.dismissViewControllerAnimated(true, completion: nil)

    //this is the line seems to have problem.
    self.navigationController?.popToViewController(ComposeViewController, animated: true)
}

Then I got these error: ComposeViewController.Type' is not convertible to 'UIViewController Expected member name or constructor call after type name

It has suggestion to fix by putting () after ComposeViewController but then it gives out more errors after fixing.

Hope someone could help. Thanks! :-)

Upvotes: 15

Views: 21255

Answers (10)

Mehsam Saeed
Mehsam Saeed

Reputation: 275

For Swift 4.0 and above Using Filter

guard let VC = self.navigationController?.viewControllers.filter({$0.isKind(of: YourViewController.self)}).first else {return}
self.navigationController?.popToViewController(VC, animated: true)

Upvotes: 2

Alejandro
Alejandro

Reputation: 99

What I found more useful was to do a first lookup with viewControllers, that way you get the first instance you find in the stack, without having to guess the actual index.

e.g.

    let mainViewControllerVC = self.navigationController?.viewControllers.first(where: { (viewcontroller) -> Bool in
        return viewcontroller is ComposeViewController
    })
    if let mainViewControllerVC = mainViewControllerVC {
        navigationController?.popToViewController(mainViewControllerVC, animated: true)
    }

Upvotes: 3

Naresh
Naresh

Reputation: 17902

In Swift 4.1 and Xcode 9.4.1

Suppose if you moved from 1st ViewController to 2nd, then 2nd to 3rd. Now if you want to come back from 3rd to 1st directly this code is enough.

if let composeViewController = self.navigationController?.viewControllers[1] {//Here you mention your view controllers index, because navigation controller can store all VC'c in an array.
    print(composeViewController)
    self.navigationController?.popToViewController(composeViewController, animated: true)
}

Upvotes: 0

Toqir Ahmad
Toqir Ahmad

Reputation: 281

let controllers = self.navigationController?.viewControllers
              for vc in controllers! {
                if vc is YourVC {
                  _ = self.navigationController?.popToViewController(vc as! YourVC, animated: true)
                }
             }

Upvotes: 12

DJ1
DJ1

Reputation: 944

for (var i = 0; i < self.navigationController?.viewControllers.count; i++) 
{
    if(self.navigationController?.viewControllers[i].isKindOfClass(DestinationViewController) == true) 
    {
        self.navigationController?.popToViewController(self.navigationController!.viewControllers[i] as! DestinationViewController, animated: true)

     break;
     }
}

Upvotes: 1

Hanny
Hanny

Reputation: 1330

I know this is old, but it's like what Saqib said, you can't pop to a viewcontroller that doesn't exist yet.

A lot of the answers here seem to be from people that didn't read your question, just the title. I'll leave this code here in case it helps anyone.

let vcIndex = self.navigationController?.viewControllers.indexOf({ (viewController) -> Bool in

    if let _ = viewController as? ComposeViewController {
        return true
    }
    return false
})

let composeVC = self.navigationController?.viewControllers[vcIndex!] as! ComposeViewController

self.navigationController?.popToViewController(composeVC, animated: true)

Upvotes: 7

Zuhair Hussain
Zuhair Hussain

Reputation: 813

if let composeViewController = self.navigationController?.viewControllers[1] {
            self.navigationController?.popToViewController(composeViewController, animated: true)
}

Upvotes: 4

bobster
bobster

Reputation: 311

I ended up replaceing the following code inside the main view and it works. I'm not sure if this is the right way, would you mind giving me some comments?

//self.navigationController?.popToViewController(ComposeViewController, animated: true)    
let switchViewController = self.storyboard?.instantiateViewControllerWithIdentifier("view2") as ComposeViewController

    self.navigationController?.pushViewController(switchViewController, animated: true)

I defined "view2" as the destination storyboard ID.

Upvotes: 3

rabdulsal
rabdulsal

Reputation: 96

There's a method that lets you get access to an array of all the ViewControllers on the current stack, and you can capture the one you want by using its index, for instance:

let switchViewController = self.navigationController?.viewControllers[1] as! ComposeViewController

self.navigationController?.popToViewController(switchViewController, animated: true)

Upvotes: 4

Saqib Saud
Saqib Saud

Reputation: 2795

navigation controller maintains the stack of views you are pushing. Its like a Last in first out queue.

In order to pop to ComposeViewController, that view must already exist in the queue and you should have reference to it.

You will need to pass the instance of ComposeViewController. for simplicity you might save that reference in appdelegate. (this approach is not recommended)

Upvotes: 0

Related Questions