I have two view controllers, MainViewController and SecondViewController.
In my main view controller, I have data I pass to the second view controller like so:
-(IBAction)shareToSocial:(id)sender {
SecondViewController *view2 = (SecondViewsController *)[storyboard instantiateViewControllerWithIdentifier:#"PushToNext"];
view2.secTitle = self.MainTitle;
[self.navigationController setModalPresentationStyle: UIModalPresentationCurrentContext];
[self setModalPresentationStyle:UIModalPresentationCurrentContext];
}
Where both secTitle and MainTitle are NSStrings for each controller. From what I've read, by setting view2.secTitle to self.MainTitle, when SecondViewController pops in I my view2.secTitle will have the same value as MainTitle. So if MainTitle is "Hello World" then I open secondViewController, secTitle would also be "Hello World". However, I've been getting null with secTitle even though I am setting the data for it.
If I use pushViewController instead of modal, the values are passed between the two controllers fine. So I'm not sure if I'm doing anything wrong here exactly.
I've also tried using [view2 setSecTitle:MainTitle] to no avail.
There's not much code on my SecondViewController but here's how it looks:
-(IBAction)showMessage:id(sender){
NSLog(#"test: %#", self.secTitle);
}
-(IBAction)closeMessage:id(sender){
[self dismissViewControllerAnimated:YES completion:nil];
}
Also, I've noticed that when I used dismissViewControllerAnimated on SecondViewController to close it and go back to the MainViewController, a black empty screen shows for a few seconds before showing the Main View and touch events on MainViewController is not detected anymore.
Please help.
Could you use performSegueWithIdentifier and prepareForSegue? If you've got your views in your storyboard and set up a segue between them, given it an identifier and set the style to modal you should be able to do this:
-(IBAction)shareToSocial:(id)sender {
[self performSegueWithIdentifier:#"modelToNextSegue" sender:self];
}
Then in prepareForSegue method you pass your values:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
SecondViewController *view2 = [segue destinationViewController];
view2.secTitle = self.MainTitle;
}
Try this:
SecondViewController *view2 = (SecondViewsController *)[storyboard instantiateViewControllerWithIdentifier:#"PushToNext"];
view2.secTitle = self.MainTitle;
UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:view2];
[nav setModalPresentationStyle: UIModalPresentationCurrentContext];
[self setModalPresentationStyle:UIModalPresentationCurrentContext];
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;
}
}
So I have a problem when trying to push some Viewcontrollers basically when the app loads it checks if you are already registered and if you are it sends you to a diff vc and if your not registered it sends you to a RegisterVC. It's done in storyboard and the problem is that when I put the code in viewDidLoad the pushes works but I can't see the rootviewcontroller from the storyboard but if I move the code into the init with coder I can see the viewcontroller but the push return's nil in the method that's supposed to push to a new vc, so the transition never happens.
The code looks like follows:
if (emp == nil) {
[self gotoRegisterView];
}
else {
[self gotoSMWView];
}
and :
- (void) gotoRegisterView {
UIViewController* vc = [self.storyboard instantiateViewControllerWithIdentifier:#"RegisterVC"];
[self.navigationController pushViewController:vc animated:YES];
}
- (void) gotoSMWView {
UIViewController* vc = [self.storyboard instantiateViewControllerWithIdentifier:#"SMWVC"];
[self.navigationController pushViewController:vc animated:YES];
}
Any suggestions are much appreciated.
If you're using storyboards, just connect the main scene to any other scene you want to call from there. Then, Ctrl+Drag from the initial VIEW CONTROLLER (not elements on the view controller, but from the controller itself). Then click on the segues you just created and give them good descriptive names. For this example, we'll just say segue1 and segue2.
Now, if segue1 takes you to the RegisterView, and segue2 to SMWView then you can do this:
- (void) gotoRegisterView {
[self performSegueWithIdentifier:#"segue1" sender:self];
}
- (void) gotoSMWView {
[self performSegueWithIdentifier:#"segue2" sender:self];
}
If you need to do any other initialization or set up on these view controllers, you can override this method:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
Within this method, you can check which segue has been called using this template:
if([[segue identifier] isEqualToString:#"segue1"])
And you can get an instance of your destination view controller like this:
YourViewController *vc = [segue destinationViewController];
In the following setup, Button 1 calls First VC and Button 2 calls Second VC
Currently, I use the following code to call SecondVC by tapping Button 2.
MainVC.m
#implementation MainVC()
....
UINavigationController *navController = [self.childViewControllers objectAtIndex:0];
SecondVC *secondVC = [self.storyboard instantiateViewControllerWithIdentifier:#"second"];
[navController pushViewController:secondVC animated:YES];
The code above displays SecondVC just fine. However, in the First VC there are statements that need be executed before "Second VC" is presented, that are being skipped!
I execute these statements in First VC inside -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender. When the Next Button is tapped in the First VC, all the statements execute because it triggers prepareForSegue before presenting SecondVC. This step is skipped when the code above is used.
Extra Info:
A) Though a Navigation Controller, Main VC in my app does not show the navigation bar in my app. I believe this would be against HIG to display two navigation bars on an iPhone. I show it here to identify Main VC.
B) There are textFields in FirstVC that User fills out. If I just copy the code, will it read and save the data from textFields.text?
Question: How can I call prepareForSegue from First VC when Button 2 is tapped in MainVC? or is there another approach to this?
You could try something like the following:
UINavigationController *navController = [[self childViewControllers] objectAtIndex:0];
UIViewController *vc = [navController topViewController]
if ([vc isKindOfClass:[FirstVC class]]) {
FirstVC *firstVC = (FirstVC *)vc;
SecondVC *secondVC = [[self storyboard] instantiateViewControllerWithIdentifier:#"second"];
// Copy and read data from [[firstVC textField] text] to secondVC.
[navController pushViewController:secondVC animated:YES];
}
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 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];