I want to run some code in the prepareForSegue. The problem is that I am changing views programmatically, so the prepareForSegue function is not being run. I also don't know how to run it because I can't give it an identifier.
prepareForSegue:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
NSLog(#"hi");
}
Code I was trying to use to call the function manually:
[self performSegueWithIdentifier:#"test" sender:self];
Code I'm using to change between views:
UIViewController *second = [self.storyboard instantiateViewControllerWithIdentifier:#"gameOverPage"];
[self presentViewController:second animated:YES completion:nil];
I guess if I can just set an identifier for the segue, my problem would be solved, but I don't know how to do that.
If you're not using Storyboard, you can't use the segue related methods.
Instead, just configure your controller before you present it.
UIViewController *second = [self.storyboard instantiateViewControllerWithIdentifier:#"gameOverPage"];
// configure your controller
second.propertyA = value;
[self presentViewController:second animated:YES completion:nil];
You can set the Identifier for a segue in Storyboard: Just click on the segue and choose the attribute inspector (right side of Xcode), there you find a textfield "Identifier". Hier you can put your individual name of a identifier.
Related
I write code in IB action to check condition to switch view controller in same story board but if I touch button it go to black screen
this is my code
-(IBAction)Buyvoyage{
if (ck==1) {
NSLog(#"brought IAP");
VoyageplayViewController *voy = [[VoyageplayViewController alloc]init];
[self presentViewController:voy animated:YES completion:NULL];
}
}
try replacing
[self presentViewController:voy animated:YES completion:NULL];
with
** [self presentViewController:voy animated:YES completion:nil];**
However, i would prefer you to use seuge by following below steps.
1. Create segue from each UIButton to the corresponding UIViewControllers, set Segue identifier in IB by selecting the segue(s) you just created e.g. if you have 2 button then set identifier of the Segue "TestSegue1" and "TestSegue2" respectively.
2. Now create an IBaction for UIButton from which you want to navigate, and put below code in that IBAction
3. Remember to set Tag property in IB of all the UIButton(s) you want to perform navigation on as per your requirement
// When any of my buttons is pressed, push the next UIViewController using performSeugeWithIdentifier method
- (IBAction)buttonPressed:(UIButton*)sender
{
if (sender.tag==1) {
[self performSegueWithIdentifier:#"TestSegue1" sender:sender];
}
else if(sender.tag==2)
[self performSegueWithIdentifier:#"TestSegue2" sender:sender];
}
Or Use storyboard identifier to present your viewcontroller using below code
- (IBAction)buttonPressed:(UIButton*)sender
{
//Get StoryBoard Identifier using
UIStoryboard *storyboard = [self storyboard];
if(ck==1) {
VoyageplayViewController *voyVC = [storyboard instantiateViewControllerWithIdentifier:#"Voyage"];
[voyVC setModalPresentationStyle:UIModalPresentationFullScreen];
[self presentModalViewController:voyVC animated:YES];
}
}
don't forget to set ViewController StoryBoard Id in StoryBoard -> identity inspector
I have three classes :
1.TyphoonViewController
2.WaterTableNaviController
3.WaterTableViewController
I am trying to pass a string from the first one to the last. But I only pass the string from the first to the second. It will be a black screen when I present the third ViewController.
I've tried to make the WaterTableViewController be the root of WaterTableNaviController in storyboard.
It did present screen, but the string wasn't passed.
From TyphoonViewController
- (IBAction)ParseBut:(id)sender {
WaterTableNaviViewController *vc = (WaterTableNaviViewController *)[self.storyboard instantiateViewControllerWithIdentifier:#"WaterTableNavi"];
[vc setUrl:#"My String"];
[self presentViewController:vc animated:YES completion:nil];
}
From WaterTableNaviController
- (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:YES];
WaterTableViewController* vc = (WaterTableViewController*)[self.storyboard instantiateViewControllerWithIdentifier:#"WaterTable"];
[vc setParseUrl:m_url];
[self.navigationController pushViewController:vc animated:YES];
}
The code you have in the navigation controller is wrong - if the WaterTableVC is the root view controller of the navigation controller, it's already been instantiated, so you shouldn't do it again. Also, you don't push to the root view controller. You don't need to subclass the navigation controller at all to do what you are trying to do here. You should make a modal segue from the button in TyphoonViewController to the navigation controller, and make WaterTableViewController the root view controller of that navigation controller. The button should not have any action method, because it triggers the segue directly. Instead, you should have the following code in prepareForSegue,
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
UINavigationController *nav = segue.destinationViewController;
WaterTableViewController *waterTableVC = (WaterTableViewController *)nav.topViewController;
[waterTableVC setURL:#"My String"];
}
You can simply make another singleton class and put a property that can contain that string, so wherever you are, you can read that property
I got first ViewController with out navigation controller, I go from it to second ViewController via
if (!self.mapViewController)
{
self.mapViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"MapViewController"];
}
[self presentViewController:self.mapViewController animated:YES completion:nil];
I send some data with prepareForSegue to it, but I need that it also be with navigation controller.
I embed in a navigation controller in storyboard but my code still called second ViewController with out navigation.
I am not a professional with the way of the storyboard, however i believe that instead of presentViewController
you should be using the following function to present a storyboard VC based on segues.
[self performSegueWithIdentifier:#"SegueIdentifierHere" sender:nil];
Make sure that in your storyboard you have incorporated a UINavigationControllerVC as well.
Give an identifier to the navigation controller in storyboard. Instantiate and present that.
UINavigationController *navVC = [self.storyboard
instantiateViewControllerWithIdentifier:#"TheNavVCWhoseRootIsMyMapViewController"];
self.mapViewController = navVC.viewControllers[0]; // your map vc is at the root
[self presentViewController:navVC animated:YES completion:nil];
You are using presentViewController:animated:completion which will indeed display a UIViewController without the UINavigationController the previous UIViewController was embedded in.
Try using the following:
[self.navigationController pushViewController:self.mapViewController animated:YES]
In Xcode 4.5 you can change views from a segue, But I want to programatically change views in Mainstoryboard. I Know in Xib. we use this method:
SecondViewController *Second = [[SecondViewController alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:Second animated:YES];
I want to change the view when the user clicks done in the textfield (This code detects if user clicks done):
-(IBAction)hidekeyboard {
[sender resignFirstResponder];
}
You create a segue in your storyboard that goes from the view that has the text field in question and goes to your SecondViewController. You have to assign an identifier to it (also in the storyboard, click on the line connecting the two view controllers), let's call it "segueToSecondViewController". Then, you can manually call the segue using:
[self.storyboard performSegueWithIdentifier:#"segueToSecondViewController" sender:self];
An alternative to segueing is to instantiate the viewController from the storyboard.
First you assign a Storyboard ID to the viewController in the storyboard.
Then you instantiate that viewController, and present it.
MBTagEditorViewController *tagEditor = [self.storyboard instantiateViewControllerWithIdentifier:#"TagEditor"];
[self presentModalViewController:tagEditor animated:YES];
I am trying to segue to a ABPersonViewController from a button in the Storyboard.
But if I do that the screen is completely black.
If I use a IBAction for the button and use the following code it works:
ABPersonViewController *person = [[ABPersonViewController alloc]init];
[self.navigationController pushViewController:person animated:YES];
Why is that? am I doing wrong?
EDIT: I found a work around but I don't think this is a proper way to do it. I subclassed ABPersonViewController and overrode the initWithCoder method with the following:
-(id)initWithCoder:(NSCoder *)aDecoder{
self = [self initWithNibName:nil bundle:nil];
return self;
}
Since you are using storyboards you should should name the segue you are using and then this in your IBAction:
[self performSegueWithIdentifier:#"abPersonViewControllerSegue" sender:self];
This way you do not even need to manually call alloc/init. Then in your prepareForSegue you could set any attributes:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"abPersonViewControllerSegue"])
{
[segue.destinationViewController setAttribute:#"whatever you want"];
...
}
}
If this is not what you are looking for please let me know.
You don't set the displayedPerson property ...
#property(nonatomic, readwrite) ABRecordRef displayedPerson
Since you are using Storyboard, why do you still call [[ABPersonViewController alloc]init]?The Storyboard will handle the creation and pushing of the ABPersonViewController(if you specified Push action for the segue). As long as you control dragged from the Button to the ABPersonViewController in story board, you do not need to write a single line of code. If you control dragged from the view controller that contains the button, then you should be calling performSegue to trigger the segue(you need to set the identifier for the segue in this case) that adds the ABPersonViewController to the navigation controller.