I created a table view and from there let say a user pressed a cell it will go to the detailItemView , but the only problem right now is that whenever a user is in detailItemView there is no back button even thought I already embed a navigation Controller
Here's the code that will perform a segue once a user pressed a cell:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using [segue destinationViewController].
var nav = segue.destinationViewController as! UINavigationController
var detailScene = nav.topViewController as! DetailViewController
// Pass the selected object to the destination view controller.
if let indexPath = self.tableView.indexPathForSelectedRow() {
let row = Int(indexPath.row)
detailScene.currentObject = objects?[row] as? PFObject
}
}
The screenshot for the storyboard:
edited Screenshot
I tried to do the answer below but there is still no back button
Another screenshot, the detailView controller doesn't have a back button
Embed the TableViewController inside the NavigationController. Not the DetailViewController directly. Check out the screenshot.
Make sure, that the segue, connecting your TableViewController and your DetailViewController is of type Show (e.g. Push). You have to literally push a new View on top of the Navigationstack.
I've had the same issue just now, resolved by deleting segue, adding again and giving it an identifier straight away.
Click on the StoryBoardSegue, the link between the tableviewcontroller and the detailviewcontroller. In the attributes inspector you may need to click on the "Animates" check even if it is checked. Do this after selecting "Show(e.g.Push)" located in the "Kind" drop down menu. Then run your app and then reselect the same "Animates" option after stopping your app. I think this is a bug and it took my an hour to figure out how to solve this. Additionally, you can use the deprecated "Push" but this will illicit a warning. Deprecated "Push" is under "Kind" in the StoryBoardSegue attributes inspector.
I was struggling with this also, and I named the Identifier of the segue, and now it works. Just select the segue (the arrow) from the Table View to the View , then go to the right top side, where the options are, and select Show the attributes inspector. There is a field for the Identifier.
Just make uinavigation with UItableview then connect the Cell as ( show )
If your current view controller is embedded in a navigation controller, you don't need to embed the detail view controller in a navigation controller. Just connect a button to the detail view controller and the back navigation will come automatically.
change "Interface style" to "Inferred" of detailView in Attributes inspector
Related
Well, I'm faced with misunderstanding.
I want my UITabBar to stay displayed when I make a segue from my History button (see picture).
My segue is on Show.
My view is embed in a UINavigationController that is root controller at my UITabBarController.
"Show navigation bar" is turned off on my UINavigationController.
And with all that, I have a grey screen on my segue and no UITabBar...
Thank you in advance!
Try creating a popup view.
In the storyboard remember to set the identifier for the view controller that you are going to. Then delete the segue.
let customAlert = self.storyboard?.instantiateViewController(withIdentifier: "view") as! yourViewController
self.addChild(customAlert)
self.view.addSubview(customAlert.view)
customAlert.view.backgroundColor = UIColor.white
Please make Segue kind as "Show". When select as "Show Detail", the ViewController is present over the Tabbar and hides it.
I have a viewController related to a Tab Bar Controller: the first one.
Clicking on a cell of its tableview, I'll show programmatically another viewController that's not linked to the first viewController with no segue (because of right reasons).
Now, my goal is to present/instantiate the second viewController related to the tab bar mentioned at the beginning of this question.
If I'll use this:
let vc=storyboard?.instantiateViewController(withIdentifier: "offerteView") as! SecondViewController
It'll be presented the mentioned viewController without the tab bar of course.
How can I solve it?
Embed the first view controller in a navigation controller and use its pushViewController function to show the second view controller.
let vc = storyboard?.instantiateViewController(withIdentifier: "offerteView") as! SecondViewController
navigationController?.pushViewController(vc, animated: true)
when using tab bars the view controllers are called on the basis of their Index and because of this the tab bars are still maintained and this can be done like this.
self.tabBarController!.selectedViewController! = self.tabBarController!.viewControllers[3]
where [3] is the index position of the View Controller.
or
self.tabBarController.selectedIndex = 1;
//Hope it was helpful. Happy Coding.
I currently have a storyboard that has a tableview with my data, and I believe I correctly pass that data using the didSelectRowAtIndexPath and the prepareForSegue functions.My problem is that when I select a certain cell my cast becomes incorrect because I have a tab bar controller holding my views to be displayed with this segued information.I want my cast to be:
let destination = segue.destinationViewController as! DownloadViewController
But I am getting an error because the segue is going to the tab bar controller first. This error makes perfect sense to me but I am unsure how to get around it without getting rid of the tab bar controller completely. Here is a picture of my story board to help show the overall flow.
http://imgur.com/7gFKKIZ
Any help is appreciated.
The UITabBarController has an array that contains its connnected viewController, to access e.g. the first one try
let destination = (segue.destinationViewController as! UITabBarController).viewControllers?.first as! DownloadViewController
Instead of using segue, you can use a modal presentation of your desired first tab for display if it works for you.
let displayFirstVC = storyboard.instantiateViewControllerWithIdentifier("newVC") as! UIViewController
self.presentViewController(displayFirstVC , animated: true, completion: nil)
When you instantiateViewControllerWithIdentifier, you have to create a storyboard name for your FirstViewController with name newVC.
You would also need to replace UIViewController with the name you gave your view controller.
More details here.
Instantiate and Present a viewController in Swift
I had a UINavigationController set as initial view controller. The root view controller for that navigation controller shows a menu where users can see product categories (In case that's interesting for anyone :)). The root view controller loads JSON data from an URL, so it takes a little while until the view shows up (which is fine). That data will be use in all the app, so it's an important step.
Well, since the data load takes a while, I added a new UIViewController where I show an image with an UIActivityIndicator. Of course, the data load takes place in this UIViewController now instead of the root view controller.
So, the idea is that after the data is loaded, the root view controller takes the place. To accomplish this I put an "invisible" UIButton on the new view controller and added a UIStoryboardSegue to the navigation controller, so I trigger that segue programmatically after the data is loaded.
After the data gets loaded, the navigation controller actually appears and shows (of course) the root view controller. The problem is when I click any button on the root view controller, the segue performs correctly, but from the "second" view controller (UITableViewController) if I press any cell, it takes me back to the new view controller (the one that shows an image and loads the data). Well not actually any cell, because sometimes it takes me actually forwards to the "third" view controller (also UITableViewController), but the same problem occurs in this view controller. If I click the back button on the navigation bar in any view controller, it takes me back to the new view controller and not really back in the navigation stack.
Here is ViewDidLoad:
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
load.loadAllProducts()
load.loadCategories()
self.performSegueWithIdentifier("mainStoryboardSegue", sender: self)
}
And PrepareForSegue:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let destination = segue.destinationViewController as? UINavigationController
let homeViewController = destination!.viewControllers.first as? HomeViewController
homeViewController!.categories = load.categories
homeViewController!.products = load.products
}
I really appreciate any help, thanks a lot!
The solution that worked for me was to change the current active view controller by setting this:
let newController = storyboard.instantiateViewControllerWithIdentifier(storyboardId) as? UINavigationController
UIApplication.sharedApplication().keyWindow!.rootViewController = newController
Im using StoryBoard and i am not so sure how to instantiate a ViewController or how to reference one.
The thing is i have two view controllers and i have one with a button. I want to go to the other view controller when i pressed the button from the first view controller.
I have tried something like that:
let secondViewController:UIViewController = UIViewController()
self.presentViewController(secondViewController, animated: true, completion: nil)
Does anyone knows how to explain it to me? Thanks!
There are couple of ways of navigating between view controllers. Here's how you do it in code without segues if you're going that way.
Presenting a view controller modally.
Say you have 2 view controller scenes in the storyboard, FirstViewController and SecondViewController. You want to transit from FirstViewController to SecondViewController and there is no segue between them.
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let secondViewController = storyboard.instantiateViewControllerWithIdentifier("SecondVC") as UIViewController
presentViewController(secondViewController, animated: true, completion: nil)
The important part is the that you have to assign an identifier to the view controller you want to go. In this case its the SecondViewController. The way you assign an identifier is you select the view controller, open up the right panel and in it, go to the Identity Inspector (the third one from the left) and under the Identity, assign an identifier to the Storyboard ID field. I put mine as SecondVC as you can see from the code snippet above.
Push to another view controller.
If you want to push on to another view controller instead of presenting it, all you have to do is embed the FirstViewController in a UINavigationController and change the code to this.
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let secondViewController = storyboard.instantiateViewControllerWithIdentifier("SecondVC") as UIViewController
navigationController?.pushViewController(secondViewController, animated: true)
In a comment of yours I saw you want to go to the next view controller based on a condition. Well all you have to do is check your condition in a if else statement and execute either of those above code.
Using Segues.
If you're going to use segues instead of code, here's how you do it.
In the storyboard first you select the button and Ctrl drag to the other view controller. You'll be prompted to choose between different segues. Select show for push or show detail for modal transition (I've explained what these are below). And that's it! If you run it and tap the button, you'd be taken to the other view controller.
But if you want more control over this, you have to do a little more work.. Instead of creating a segue directly from the button, select your view controller and select that little yellow icon on top (This is in Xcode 6. In older Xcode versions its under the view controller scene). Ctrl drag from that icon to the other view controller you want to transit to. You can see a connection appears between those two controllers. Select the segue and open up the right panel and go to the Attributes Inspector (The forth one from the left). Give a name to the field identifier. I gave ToSecond.
Now create a normal action from the button. And you have to call a method called performSegueWithIdentifier passing that identifier. What it does is basically execute a segue with the identifier we give.
#IBAction func segueButtonPressed(sender: UIButton) {
performSegueWithIdentifier("ToSecond", sender: nil)
}
And this would work. You can do the conditions checking here inside a if else and if the conditions are met, call performSegueWithIdentifier.
One other thing you're likely to face is having multiple buttons in a view controller and segueing to different view controller when you tap each of them. A method called prepareForSegue fires each time a segue happens. And inside it, you can check for current segue identifier and execute it. The below code snippet will make this clearer.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "ToSecond" {
let secondViewController = segue.destinationViewController as SecondViewController
}
}
Another thing I'd like to mention is that presentViewController and pushViewController are deprecated from iOS8. Instead you can use showDetailViewController for modal and showViewController to push.
showDetailViewController(secondViewController, sender: nil)
navigationController?.showViewController(secondViewController, sender: nil)
I'm not sure if these are backwards compatible. Meaning using show and show detail will work if you're developing for iOS 7 as well. If you are then just stick with the older methods.
First set seques of uistoryboardviewcontroller and try this
self.performSegueWithIdentifier("push", sender: self)
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
if segue.identifier == "push" {
}
In the storyboard, select VC1 and then select the button and press control and while holding down the left button or touchpad drag across to your VC2. Then a menu should pop up. Select modal.
Run and Test. It should now perform a transition.
To transition back, the easiest way is to embed VC1 in a Navigation Controller. To do this, zoom out, select VC1 and go to the top of the screen and select:
Editor > Embed > Navigation View Controller.
Now test and run. You should have the option to go back.
If you are binding view controller programmatically you need to follow this step if you are creating storyboard based application.
It is similar what we don in Objective-c just the syntax has changed.
According to your question what you need to do is go to Main.storyboard and need to select identity inspector.
There you will be able to view identity which contains two fields
1.) Storyboard ID
2.) Restoration ID
Give them the name of view controller you have binded with class in storyboard id and select check box below restoration id. It will automatically copy storyboard ID in restoration ID.
You need to do same for all your view controllers.
let secondView = self.storyboard?.instantiateViewControllerWithIdentifier("SecondViewController") as SecondViewController
self.presentViewController(secondView, animated: true, completion: nil)
you need to write the name you have entered in Storyboard ID for self.storyboard?.instantiateViewControllerWithIdentifier("/* Storyboard ID */")
You can also visit the link:
Instantiate and Present a viewController in Swift
okay,
in interface builder control click on your button and drag the blue line that appears to the second view controller. The second view controller will highlight blue. You can release and the button is connected. In the popup menu select "modal segue". No code necessary. XCODE handles it.
Watch this video for a demo.