sorry for my bad English
i need to pass data from my First View Controller to Front View Controller of SWRevealViewController
in my First View Controller i do this code
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"menu"]) {
SWRevealViewController *sw = (SWRevealViewController *) segue.destinationViewController;
// error is here i get nav with nil
UINavigationController *nav = (UINavigationController *)sw.frontViewController;
FrontViewController *home = (FrontViewController *) nav.topViewController;
home.passed_student = selected_student;
}
}
In storyBord no object(view controller) is created untill it is presented using segue or accessed some other way so here in your code your are presenting the SWRevealViewController but try to access the object of FrontViewController which is not in memory.
So first you should pass your selected_student to your SWRevealViewController then from here to FrontViewController because you can access the object of FrontViewController from here during presenting it using segue. This is the simplest way of doing it.
Related
I want to pass the variable " uid " between the FirstViewController and SecondViewController, so I used the following code to pass it. It successfully pass it, but the problem it hides the NavigationBar and the TabBar !
How can I solve it?
SecondViewController *vc2 = [self.storyboard instantiateViewControllerWithIdentifier:#"SecondViewController"];
vc2.uid = uid;
[self.navigationController pushViewController:vc2 animated:YES];
Why dont you use storyboard segues to solve this? Just embed you view controller on a Navigation View controller and call performSegueWithIdentifier function.
Just add prepareForSegue function to your class and set uid there:
- (void) prepareForSegue: (UIStoryboardSegue *) segue sender: (id) sender
{
if([segue.identifier isEqualToString:#"secondViewSegue"])
{
//**OPTION A**: If you are using Push segue
SecondViewController *secondVC = (SecondViewController
*)segue.destinationViewController;
//**OPTION B**: ***ELSE, If you are using a Modal segue
UINavigationController *navController = (UINavigationController*)segue.destinationViewController;
SecondViewController *secondVC = (SessionViewController *)navController.topViewController;
//END OF OPTION B
secondVc.uid = uidValue;
}
}
I have a SplitViewController App with 2 initial controllers:
leftViewController (master)
rightViewController (detail)
my rightViewController (detail) has the delegate of the splitViewController for presenting a button which shows/hides my menu (master)
my leftViewController (master) is a menu application, when I select any element of the menĂº I trigger a segue connected to my master and it replaces my detailViewController for the selected element of menu
when I do that and if I try to rotate my iPhone for hide menu my app crashes and says:
*** -[rightViewController respondsToSelector:]: message sent to deallocated instance
I guess it is because my splitViewController wants to communicate with its delegate, its old rightViewController, but it is gone, it has been replaced on my view,
maybe I need whether:
reasign my delegate to my new viewController (detail)
or
remove delegate of my rightViewController and assign it then to my newViewController
also tried this in my new viewController:
#interface newViewController ()<UISplitViewControllerDelegate>
#end
#implementation newViewController
- (void)viewDidLoad
{
UISplitViewController *splitViewController = (UISplitViewController *)self.view.window.rootViewController;
UINavigationController *navigationController = [splitViewController.viewControllers lastObject];
splitViewController.delegate = (id)navigationController.topViewController;
}
...
#end
but still not working... I get the same message
how do I fix this???
thanks in advance
EDIT: add my segue code for helping to answer my question
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([segue.identifier isEqualToString:#"viewSceneAgenda"]) {
[segue.destinationViewController setTitle:#"Citas"];
[segue.destinationViewController setUserIDElement:UID_CUS];
[segue.destinationViewController setOverallAppointments:overallDates];
}
}
Maybe you have to pass your delegate as you said to your newViewController... why don't you add this in your leftViewController (master)...
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([segue.identifier isEqualToString:#"showNewViewControllerScene"]) {
UISplitViewController *splitViewController = (UISplitViewController *)self.view.window.rootViewController;
splitViewController.delegate = segue.destinationViewController;
}
}
just replace the segue identifier (showNewViewControllerScene) to match with yours on your storyboard
Gonna complement Jesus Answer
Since I'm working with several segues, all of them must have the delegate of my UISplitView, also since iPhone doesn't support splitviews, I added a condition for assigning the delegate just if the user is running this app on any iPad
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([[UIDevice currentDevice].model hasPrefix:#"iPad"]) {
UISplitViewController *splitViewController = (UISplitViewController *)self.view.window.rootViewController;
splitViewController.delegate = segue.destinationViewController;
}
if ([segue.identifier isEqualToString:#"viewSceneAgenda"]) {
[segue.destinationViewController setTitle:#"Citas"];
[segue.destinationViewController setUserIDElement:UID_CUS];
[segue.destinationViewController setOverallAppointments:overallDates];
}
}
Basically, i'm using the prepareForSegue method to transition to another view within my storyboard, my view had to be embedded in a navigation controller in order to display the navigation bar so I am passing variables in such a way:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:#"exploreAddSelected"]){
UINavigationController *navController = (UINavigationController *)segue.destinationViewController;
AddTableViewController *controller = (AddTableViewController *)navController.topViewController;
controller.tagName = tagName;
}
}
My issue is I need to be able to set some method values in the actual view controller when using the prepareForSegue method, as you can do when using pushViewController as below:
DetailViewController *detailViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"DetailViewController"];
detailViewController.tagName = tagName;
[detailViewController setCurrentHashtag:nil];
[navigationController pushViewController:self.detailViewController animated:YES];
I need to be able to set the "setCurrentHashtag" method, that is declared in the view controller that the segue "exploreAddSelected" goes to. How would I do this?
The answer to this is actually extremely obvious, but it takes me to ask the question to realise the answer myself.
You can simply set:
controller.currentHashtag = nil;
Where currentHashtag is a newly declared instance in the view controller.
Then in the actual view controller set:
[self setCurrentHashtag:currentHashtag];
Just add the currentHashtag to the method.
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:#"exploreAddSelected"]){
UINavigationController *navController = (UINavigationController *)segue.destinationViewController;
AddTableViewController *controller = (AddTableViewController *)navController.topViewController;
controller.tagName = tagName;
[controller setCurrentHashTag:nil]; //add this line
}
}
I'm not sure what you are doing here. If the segue points to a view controller directly (and nor via another navigation controller), you do not need the mapping to topviewcontroller, but use the destinationcontroller directly.
I have a viewController that is usually (most often) accessed by using a push segue. This viewController needs to be embedded in a UINavigationController. So typically, this is no problem. The push segue manages pushing the viewController, and therefore the viewController has it's UINavigationController.
My issue is that in a few cases, I'd like to present this same exact viewController using a modal segue. When I do this, the viewController is not embedded in a navigationController. Is there a way to do this using segues?
I know this can be done purely in code without segues by creating a UINavigationController, setting the rootView as the viewController and then presenting that modally. That can be done using code like this :
MyViewController *viewController = [[MyViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:viewController];
[self presentModalViewController:navController animated:YES];
But how do I do this same thing but using Segues?
Update
For further clarity, here is some code to supplement how I used the accepted answer in the prepareForSegue method.
When Using Modal Segue
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue destinationViewController] isEqualToString:#"Modal to MyVC"])
{
UINavigationController *nav = [segue destinationViewController];
MyViewController *vc = [nav topViewController];
//setup vc
}
}
When Using Push Segue
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue destinationViewController] isEqualToString:#"Push to MyVC"])
{
MyViewController *vc = [segue destinationViewController];
//setup vc
}
}
In your Storyboard, you can embed a ViewController in a Navigation Controller by selecting the View Controller and then picking from the menu at the top Editor->Embed In->Navigation Controller. From another view controller, you control drag to this Navigation controller to set up the modal segue. You can also control drag to the original View Controller to set up segues to it without the Navigation Controller.
I have a storyboard with a UINavigationController. The root view controller of the navigation controllers is called rootViewController.
I am trying to programmatically change the view controller (depending on other conditions) to another view controller called loginViewController.
I am trying to do this in the viewDidLoad from the rootViewController like this:
- (void)viewDidLoad
{
[super viewDidLoad];
loginViewController *viewController = [[loginViewController alloc] init];
[self.navigationController pushViewController:viewController animated:YES];
}
I am not getting any errors but it's not working.
It just loads the navigation controller with the top nav back button but the rest of the screen is black. It's like it's not loading any view controller.
I am trying to figure out what I am doing wrong.
Any help with this would be great.
Thanks
First add loginViewController class in storyboard and and connect ViewController class to loginViewController class and give identifier name as "identifier_Name".
- (void)viewDidLoad
{
[super viewDidLoad];
[self performSegueWithIdentifier:#"identifier_Name" sender:nil];
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([[segue identifier] isEqualToString:#"identifier_Name"])
{
loginViewController *viewController = [segue destinationViewController];
}
}
If you're using storyboard, create your login view in the storyboard, link your rootVC to the loginVC with a segue, choose an identifier (for example: "goToLogin"). and then to go in the login view, and use:
[self performSegueWithIdentifier:#"goToLogin" sender:self];