How to override the UIBarButtonItem triggered segue defined in a storyboard - objective-c

I have a UIViewController in a storyboard iPhone app that I need to reuse in several places. In the storyboard, there is a UIBarButtonItem that has a triggered segue to another controller. In some cases, however, I would like to override the behavior of the button to segue to a different view controller. I'm thinking that there must be a way to either initialize the view controller with a message that specifies the target view controller, or to set some property after the controller is initialized but before it's pushed?
One challenge seems to be that segues can't be defined programmatically (based on what I've read so far), and I don't think I can have multiple segues on the same view controller in storyboard. So I may need to do something like this:
[self presentModalViewController:myNewVC animated:YES];
... rather than use a segue, but I'm not sure how to override the behavior of the button defined in storyboard to do it that way.
Any help is appreciated.

Just create an IBAction and a BOOL for some condition to pick which view controller should be instantiated.
UIViewController *viewController;
if (someCondition) {
viewController = [self.storyboard instantiateViewControllerWithIdentifier:#"someViewID"];
}else{
viewController = [self.storyboard instantiateViewControllerWithIdentifier:#"someOtherID"];
}
[self presentViewController:viewController animated:YES completion:nil];

Related

return to ViewController after presentViewController

Im trying to return to a specific ViewController in it's current state after going from that ViewController to another using presentViewController.
But when I try to close the other ViewController (with dismissViewController) I get a white screen.
RootViewController *rootViewController
= [[UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil]
instantiateViewControllerWithIdentifier:#"RootViewController"];
[self presentViewController:rootViewController animated:YES completion:nil];
This isn't an option either because that instantiates a new viewcontroller and I want the old ViewController in its current state.
Do I need to pass the RootViewController as an argument when presenting the other ViewController or is there another option to return to the RootViewController in its current state?
Yes, there is a way to return original screen.
I met just like problem but solved it with following code line
[self dismissViewControllerAnimated:YES completion:nil];
one way to address this is to avoid having one view controller responsible for presenting and dismissing the other one.. what you can do is create a controller of controllers (give it a singelton method).. and have that object basically keep a reference to any view controller you are interested in maintaining its state. That way you wouldn't have worry about what's going on behind the scenes when you dismiss or present a view controller.

how to access the UITabBarController when its not the initial view?

I'm having problem with accessing my tabbarcontroller in the storyboard when its not the initial view. So basically there is an initial view in the storyboard which leads to the tabbarcontroller. I want to change the color of the tab but i dont have access to it! I know that it can be added to the delegate if its the initial view but in this case its not the initial view in the storyboard! I read somewhere that I have to override a method in the first view but there was no detail about it!
If you are in a viewcontroller in the storyboard then this code:
UIStoryboard *storyboard = self.storyboard;
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"OtherViewController"];
Will get the other viewcontroller youw want and you could do things such as:
set yourself as delegate for it:
[(OtherViewController *)vc setDelegate:self];
display it:
[self presentViewController:vc animated:YES completion:nil];
I think you could use this to get the other viewcontroller and then access the tabbar from it.
Sorry if I misunderstood what you are trying to do.

Modal segue no transition

How to remove the transition effect from a modal segue when displaying the modal like this:
[self performSegueWithIdentifier:#"SomeIdentifier" sender:self];
I know I can go into the storyboard and toggle between 4 different animations but I don't want any! How do I remove them?
I know I could say presentModalViewController animated: NO but I do not and can not call it this way. I need to use the performSegueWithIdentifier method.
In the storyboard you can select your segue and in the Attributes Inspector uncheck "Animates". That should do it.
Here's the full source of a no-animation segue:
BVNoAnimationSegue.h
#import <UIKit/UIKit.h>
#interface BVNoAnimationSegue : UIStoryboardSegue
#end
BVNoAnimationSegue.m
#import "BVNoAnimationSegue.h"
#implementation BVNoAnimationSegue
- (void)perform
{
[[self sourceViewController] presentModalViewController:[self destinationViewController] animated:NO];
}
#end
To use this, add the files to your project (e.g. as BVNoAnimationSegue.m/.h) then in storyboard, select 'Custom' as your Segue type and type BVNoAnimationSegue in the Segue Class box. After you've done this Xcode seems to be clever enough to add 'no animation segue' as an option when you CTRL-drag between UIViewControllers in future.
You need to make a custom segue (without the animation) if you need a segue but don't want the animation.
You should look at Apples "creating custom segues" example in the view controller programming guide, they do a custom modal segue without an animation (just like you wanted).
One more way we can
YourViewController *aYourViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"aYourViewControllerIdentifier"];
[self.navigationController pushViewController:aYourViewController animated:NO];
and add the #"aYourViewControllerIdentifier" to view controller in your storyboard.

Modal UIViewController will not push to next UIViewController

The start of the structure is as follows...
UITabBarController -> UINavigationController(s)
From each of the UINavigationControllers, I have a UIBarButtonItem that modally presents a UIViewController.
This UIViewController has a MKMapView with pins at multiple locations. When clicked, they display an annotation with a disclosure button.
Within this UIViewController, it is my intention to push a detail page (UITableViewController) when pressing the disclosure button of the annotation. The method calloutAccessoryControlTapped: receives the appropriate pin, but the transition to the next controller fails.
I have tried every combination of the following methods...
[self.navigationController ...]
[self.parentViewController ...]
[self.parentViewController.navigationController ...]
with the method being either...
presentModalViewController:
pushViewController:
I have done all of these with the UIViewController being on its own, and also with it embedded inside of a UINavigationController.
All of these properties return null...
self.navigationController
self.parentViewController
self.parentViewController.navigationController
This is the first time I've used storyboard for an Xcode project. Am I missing a step?
Try getting rid of the code and implementing the transitions in storyboard by control dragging from the button to the view controller you wish to load modally. When the "Storyboard Segue" menu pops up select "modal". In the modal view controller, I like to use code to return from the modal by calling:
[self dismissModalViewControllerAnimated:YES];
To Presenting Storyboard View Controllers Programmatically scroll to that section in gravityjack on the link provided.
For example, I have a view controller that I created in storyboard which I can call programmatically with the following two statements:
SettingsViewController *settingsVC = [self.storyboard instantiateViewControllerWithIdentifier:#"settingsVC"];
[self.navigationController pushViewController:settingsVC animated:YES];

UIModalPresentationFullScreen not working in iPad landscape mode?

I have added a ViewvController(B) as subview on ViewController(A). In ViewController A(SuperView) UIModelPresentationFullScreen working fine. But when am calling UIModelPresentationFull in ViewController B(SubView) it modelview showing in Portrait mode and that is also not fully viewed. How to solve this problem. Can any one help me please. I have tried 2 days.
This is what I tried in both the superview and subview...
picFBCapture *fbCapt = [[picFBCapture alloc] init];
//[self.navigationController pushViewController:fbCapt animated:YES];
//fbCapt.modalPresentationStyle = UIModalTransitionStyleFlipHorizontal;
fbCapt.modalTransitionStyle = UIModalPresentationFullScreen;
[self presentModalViewController:fbCapt animated:NO];
[fbCapt release];
Thanks in advance..
The problem is that if you add a view controller as a subview it's not connected to the view controller hierarchy and thus certain things doesn't work. You should avoid adding view controllers as subviews whenever possible, since this is not how Apple intend view controllers to be used, but sometimes it can't be avoided.
If this is one of those cases when it can't be avoided you should save a reference to view controller A in view controller B and then call presentModalViewController: on view controller A (that is connected to the view controller hierarchy) instead of self (view controller B, that isn't connected).
EDIT: In controller A you probably have code looking something like:
[self.view addSubview:controllerB.view];
In conjunction to this line add:
controllerB.controllerA = self;
I hope you know how to create properties, but if not here's a hint:
#property (nonatomic, assign) UIViewController *controllerA;
The rest you should be able to figure out using Google and the documentation.
You will have to handle viewController B's view in landscape by yourself. Since viewController B has been added as a subview, its view controller will not be handling its landscape orientation. The UIModalPresentationFullScreen style (landscape and portrait) will work only if viewController B is shown, ie not as subview but as a full view itself.