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
Related
I'm trying to move from one UIViewController to another using -pushViewController:animated using the below snipped :
SomeController *tabBar = [self.storyboard instantiateViewControllerWithIdentifier:#"mycus"];
[self.navigationController pushViewController:tabBar animated:YES];
Moving from one UIViewController (which has no UIViews or images) has a 3 second delay before moving. What is causing this issue and how would I solve it?
For storyboard, click on the segue you have created, give it an identifier like "someSegue".
Next you will want to trigger the prepareForSegue delegate in your viewcontroller doing the following...
[self performSegueWithIdentifier:#"SomeSegue" sender:nil];
..Then you will want to include the delegate method in your view controller and do any preparing you might want before the next view controller is initialised.
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
SomeController *vc = [segue destinationViewController];
// Here you will want to do your prep e.g. pass iVars etc from one controller to the other.
}
I'm trying to use a custom segue (at bottom) to present a view controller modally with a blur view. I need to instantiate the view controller with properties before I present the view controller.
Instating the VC works great when I am using pushVC, but when I use perform segue with identifier, I don't see an option to choose an already instantiated VC.
CustomViewController* VC = [self.navigationController.storyboard instantiateViewControllerWithIdentifier:#"customVC"];
[self.navigationController performSegueWithIdentifier:#"blurSegue" sender:self];
How can I perform the custom segue and force it to use the view controller I allocated (called VC above)?
https://github.com/AlvaroFranco/AFBlurSegue
I need to instantiate the view controller with properties before I
present the view controller.
Why do you have to instantiate CustomViewController before triggering the segue. That shouldn't be necessary, if you need access to a property of CustomViewController before it's shown, you can set it in prepareForSegue.
Try this:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"blurSegue"]) {
CustomViewController *customViewController = (CustomViewController *)segue.destinationViewController;
customViewController.propertyToSet = XXX; // set the property here
}
}
Ah, by the way, instead of
[self.navigationController performSegueWithIdentifier:#"blurSegue" sender:self];
just use:
[self performSegueWithIdentifier:#"blurSegue" sender:self];
I have code that uses Storyboards for seques, like so:
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"ShowDiagnosis"])
{
[segue.destinationViewController setHappiness:self.diagnosis];
}
...
But I want to do it programmatically. I have myViewController class and when I click on a button I want to animate and push to myUINavigationController.
How is this done programmatically?
First things first, a segue cannot be created programmatically. It is created by the storyboard runtime when it is time to perform. However you may trigger a segue, which is already defined in the interface builder, by calling performSegueWithIdentifier:.
Other than this, you can provide transitions between view controllers without segue objects, for sure. In the corresponding action method, create your view controller instance, either by allocating programmatically or instantiating from storyboard with its identifier. Then, push it to your navigation controller.
- (void)buttonClicked:(UIButton *)sender
{
MyViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"my-vc-identifier"];
// OR MyViewController *vc = [[MyViewController alloc] init];
// any setup code for *vc
[self.navigationController pushViewController:vc animated:YES];
}
First of all segue can be used only with if you have a UINavigationController that will handle the navigation (push, pop, etc).
So if you have a UINavigationController and you want to push another UIViewController on the stack without using segue then you can use pushViewController:animated: method which also has a reverse popViewControllerAnimated:. Also UINavigationController provides other methods for adding/removing UIVIewControllers, for more info check UINavigationController class reference.
I have a project which has a view controller as initial screen and then a view controller embedded inside a navigational view controller. I also have a button on first screen on click of which I want the navigational controller screen to be opened.
I clicked on button and then on ' connections inspector', I added push event to that navigational controller, but segue is not happening. How could I achieve it please?
SOLUTION
Finally after a bit of research I managed to get this thing working. Here is the code i am using:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSLog(#"Source Controller = %#", [segue sourceViewController]);
NSLog(#"Destination Controller = %#", [segue destinationViewController]);
NSLog(#"Segue Identifier = %#", [segue identifier]);
if ([segue.identifier isEqualToString:#"mysegue"])
{
NSLog(#"coming here");
SecondViewController *loginViewController = (SecondViewController *)segue.destinationViewController;
//SecondViewController *navigationController = [[UINavigationController alloc]init];
[self presentModalViewController:loginViewController animated:YES];
}
}
Are you sure that the Navigation Controller's connection to the embedded view controller is set up correctly? The first view controller should be connected to the Navigation Controller, with a Push style segue, and the navigation controller should be connected to the second view controller, with a Relationship style segue.
At any rate, one of the official Apple tutorials does just this, so you might be able to compare your code to it and see if there's a difference: Your Second iOS App. The prepareForSegue method itself isn't really involved with firing the segue; it is just invoked before the segue runs to prepare the new view controller.
I was wondering how to properly use the storyboard to put up a view controller modally. Personally I prefer working with xibs, but it seems that the storyboard is gaining popularity and will be the way to go in the future.
The way I would normally put up a view controller modally would be like this: let's say we have ViewControllerA (A for short) and ViewControllerB (B for short).
I would then normally put a protocol in B.h specifying the delegate method when B wants to be dismissed and add the id<theProtocol> delegate field as an assign property. Assuming i'm busy in A and I want to present B modally, I would write:
B* b = [[B alloc] initWithNibName:#"B" bundle:nil];
b.delegate = self;
[self presentModalViewController:B animated:YES];
Using the storyboard, I know it's possible to put up a different view controller in a modal way by ctrl-dragging from a button to a viewcontroller and selecting modal as transition type. I'm just wondering though; where do I set the delegate of the new view controller? What's the correct practice of passing things to your modal view controller? I don't really know what the whole deal with Segues is...
Take a look at this tutorial
According to it, you should set the delegate as follows:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"AddPlayer"])
{
UINavigationController *navigationController =
segue.destinationViewController;
PlayerDetailsViewController
*playerDetailsViewController =
[[navigationController viewControllers]
objectAtIndex:0];
playerDetailsViewController.delegate = self;
}
}
Where #"AddPlayer" is the name of your 'modal' segue
Instead of using the navigation controller you could directly use the UIStoryboardSegue object passed in prepareForSegue. It has a property called destinationViewController which is the view controller that is being instantiated. I find that a lot cleaner.
This is an example.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"AddPlayer"])
{
PlayerDetailsViewController
*playerDetailsViewController =
(PlayerDetailsViewController *) segue.destinationViewController;
playerDetailsViewController.delegate = self;
}
}
IMO I think that storyboards are great because they function like a blueprint of your application. Also I've never liked nibs. =D