pushViewController not working in swift 3 - ios

I am using storyboard and xib in swift 3 (iOS 10 and XCode 8). And when i load any View Controller with xib, application is crashing.
Here is the code, i am using to load View Controller on Button Action:
let serverViewController = ServerViewController(nibName: "ServerViewController", bundle: nil)
self.navigationController?.pushViewController(serverViewController, animated: true)

If the ServerViewController nibName is correct, then the problem would be that you are trying to push a navigation controller. I mean ServerViewController should be a UINavigationController subclass in which case, you can't push the navigation controller.

Related

Unwind segues with programmatically created view controllers

I have a view controller (PhotoViewController) which has a child view controller (CameraViewController). In CameraViewController, there is a button that sets off a chain of segueing through other programmatically created view controllers. On the last of these view controllers, I want to unwind to the original PhotoViewController. All examples I have found require you to have view controllers in the storyboard, which I don't have. How can I do this?
You have not understood what an unwind segue is. It is merely a way of reversing the calls that created the current view controller and got it into the view controller hierarchy, in the special case where you want to trigger this through a segue in a storyboard.
For example, if you (or the storyboard) called pushViewController (for a pushed view controller), an unwind segue is just a way of calling popViewController.
Or, if you called (or the storyboard) called present (for a modally presented view controller), an unwind segue is just a way of calling dismiss.
If you don't have your view controllers in a storyboard, you don't need an unwind segue; you just do one of those two things, directly, in code.
Remember, we all got along for years just fine without unwind segues. In fact, we all got along for years without storyboards! And so can you.
If your original PhotoViewController is created on a storyboard and you want to segue back to it from a programmatically made VC you have present it rather than unwinding because unwindSegues are for storyboards only.
To present your PhotoViewController here is one of the ways to do so.
func presentPhotoViewController() {
let storyboard = UIStoryboard(name: "YourStoryBoardName", bundle: nil)
if let photoViewController = storyboard.instantiateViewController(withIdentifier: "PhotoViewControllerUniqueId") as? PhotoViewController {
// Pass any data you have (Optional)
self.present(photoViewController, animated: true, completion: nil)
// If your PhotoViewController is embeded in a navigation Controller do the following.
//let navController = UINavigationController(rootViewController: photoViewController)
//self.present(navController, animated: true, completion: nil)
}
}

TabBar embedded NavigationController bar disappears when segue to another ViewController

I have a UITabBarController which is connected to 3 UINavigationControllers. Each of these have a UIViewController as a root view controller. When I click on a button in one of these ViewControllers (VC1), I want it to segue to new ViewController (VC2). Simple enough.
During runtime, when the segue takes place and VC2 appears, the navigation bar disappears.
The navigation bar is present in the storyBoard / interface builder, and the segue is the type: present (Push).
Code in VC1:
#IBAction func create_clicked(_ sender: Any) {
performSegue(withIdentifier: "segueIdentifier", sender: self)
}
It might help to know how the UITabBarController tabBar is instantiated:
func login() {
let storyBoard = UIStoryBoard(name: "Main", bundle: nil)
let tabBar = storyBoard.instantiateViewController(withIdentifier: "tabBar")
window?.rootViewController = tabBar
}
Please help.
After a great deal of experimentation, we determined that even though Interface Builder said this was a Show (Push) segue, and even though we were in a Navigation Controller to start with,
it was behaving as a Present Modally segue.
So we changed the segue type, using the pop-up menu in Interface Builder, from Show (Push) to plain Push, even though that's deprecated — and the interface worked correctly.
And then we changed it back to Show (Push) and the interface continued to work correctly. Problem solved!
I suspect the storyboard was corrupted in some way. Obviously Interface Builder should not lie to you about what kind of segue this is, but basically, that is what it seems to have been doing.
EDIT The problem was caused, apparently, by making a Show Detail segue and changing it to Show. When you do that, it's still a Show Detail segue, which in this context behaves as a modal presentation. That's an Xcode bug! I reported it, and Apple now says this will be fixed in Xcode 9.3.

How To addSubViews To Storyboard, Then Displaying It Using A Segue

I have a view controller reference to a storyboard of a given identifier. I'm adding a bunch of buttons to it, then trying to display it via a segue.
My problem is that when the segue fires, it creates a difference instance of the view controller with the same segue identifier, and thus it's blank.
What's the best practice to addSubView() to a storyboard, then getting that SAME storyboard object to display?
CLARIFICATION
Here's the flow I'm using:
Central VC -> Create SubVC using centralized Storyboard Object -> Adding SubViews to that SubVC in a factory class -> Queue Segue from SubVC back to the Central VC for segue using its identifier -> [it creates a NEW VC without my additions]
If you're using segues, then the Storyboard creates the destination viewController. If you want to customize the destination viewController, then you do that in prepareForSegue.
You can instantiate a view by code, and pushing in to you navigation controller, it's a clean approach and dont mess the Storyboard with unnecessary segues.
Just instantiate the next view (you must first give this view an StoryBoard ID), call it by code, and push it in the navigation controller.
Objective-C
UIStoryboard* storyboard = [UIStoryboard storyboardWithName:#"storyBoard_Name" bundle:nil];
UIViewController* controller = [storyboard instantiateViewControllerWithIdentifier:#"ViewController_ID"];
[self.navigationController pushViewController:viewControllerName animated:YES];
Swift
let storyboard = UIStoryboard(name: "storyBoard_Name", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("ViewController_ID") as! UIViewController
self.presentViewController(vc, animated: true, completion: nil)

Back button to another storyboard

I am creating an iOS app which consists of 2 storyboards.
This is the second one:
I am targeting iOS 7 so I cant use storyboard references. Switch between storyboards is handled programmatically
Using this code:
let viewController:UIViewController = UIStoryboard(name: "Warnings", bundle: nil).instantiateViewControllerWithIdentifier("WarningsInitialView") as UIViewController
self.presentViewController(viewController, animated: true, completion: nil)
I can get to the second storyboard using this. However as you can see second storyboard consists of Tab Controller and I want (on both tabs) back button which will point to the main (previous) storyboard. How should I achieve this?
I have tried using this code:
AvalanchesBackButton.leftBarButtonItem = UIBarButtonItem (title: "< Spät", style: UIBarButtonItemStyle.Plain, target: self, action: "backButtonClicked")
I will be able to achieve what I want by using different view controllers for both views and hardcoding it. But is there a way to do it more cleanly? Like implement a back button on container Tab Controller which will point to previous storyboard?
Thanks in advance
Is your previous ViewController embedded into a Navigation controller? because "pushing" the view controller automatically adds the back button.
self.navigationController?.pushViewController(viewController: UIViewController, animated: Bool)

Reuse a ViewController in Swift on iOS 8

I have a side menu with different navigation points. The first point is the Home nav. This should send the user back to the main view.
If I start the app, the main view will be generated by the storyboard. Now if a user taps on "Home", I would like to reuse this instance. Is this possible? (With Swift)
Thanks
You can instantiate a view from a storyboard like so:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let homeViewController = storyboard.instantiateViewControllerWithIdentifier("Home")
Then do as you will :)

Resources