I have 2 view controllers . First one is UIview controller and second one is table view controller.
I want to send data 2nd (table view controller) to first(uiview Controller) after the selection of rows of 2nd view controller.
For this i have written a delegate protocol.
But my delegate protocol is not working...
I figured out the problem.The object of second view controller that i am creating.
address = [[second_viewcontroller alloc] init];
address.delegate = self;
is different from self of second_viewcontroller view controller page.
How to make this two same.
self = [[second_viewcontroller alloc] init];
your problem my delegate protocol is not working... I figured out the problem.The object of second view controller that I am creating. address=[[second_viewcontroller alloc]init]; address.delegate=self; is different from self of second_viewcontroller view controller page.
It's clear say that way you create the second_viewcontroller object is not right.
You have to create the object from ViewController storyboard identifier.
First give the Storyboard ID to ViewController from Storyboard.Follow this step to Giving the Storyboard ID.
Select the particular ViewController in Storyboard.
Go to IdentityInspector.
Under IdentityInspector, There is identity section and add the Storyboard ID In "Storyboard ID" Field.
Syntax For Creating a ViewController Object.
Second_viewController *aVC = [self.storyboard instantiateViewControllerWithIdentifier:#"Second_viewController"];
aVC.delegate = self;
I assume that you are calling the Second_ViewController from storyboard instead of doing programmatically.
In that case, the correct instance of Second_ViewController can be accessed in prepareForSegue. For that, you need to set a Storyboard segue identifier, eg "Second_ViewController"
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"Second_ViewController"]) {
SecondViewController *aSecVC = segue.destinationViewController;
// Register the Delegate to self.So when we call the delegate method from secondVC, SendMessage will be call of ViewController
aSecVC.delegate = self;
}
}
If you use alloc-init or instantiateViewControllerWithIdentifier, when you are using a storyboard push segue, it will create another instance.
Yes as your instantiating a new instance of the second view controller. From what I could make out from your question, I guess if you obtain the instance of your secondViewController from the Navigation Stack it should work
I created a sample project for you to get the basic knowledge of how to pass data backward using NSUserDefaults. try this in GitHub. hope this will help to you. project url Pass data backward using NSUserDefaults in Objective-C
I have added a segue between two view controllers using XCode 6 interface builder. However it calls the default constructor. How can I get it to call a specific constructor for the second view?
view 1 -> click button -> activates segue -> calls constructor of view 2 -> displays view 2
Using a segue this is unfortunately not possible, you can't further specify how the destinationViewController should be instantiated.
However, instead of using the Storyboard segue, you can instantiate the UIViewController yourself and just push it manually onto the navigation stack.
- (IBAction)buttonTap
{
ViewController2 *vc2 = <your custom constructor>;
[self.navigationController pushViewController:vc2 animated:YES];
}
(note that this mimics the exact same behaviour that the push segue gives you)
Otherwise, if you want to keep on using the Storyboard segue and your actual goal is to initialize certain properties of ViewController2, you can implemented prepareForSegue: and set the properties there.
- (void)prepareForSegue:(UIStoryboardSegue *)segue
{
ViewController2 *vc2 = segue.destinationViewController;
// set properties here
vc2.prop = xyz;
}
(note the code is not tested but it should convey the main ideas, let me know if you need further explanation)
I have a couple of "ViewControllers" and one for Update a picture in an iOS app.
The first one has a button when tapped asks if the user wants to use gallery photo or camera.
Now i am presenting this controller by using presentViewController on self.
But when the second view controller is presented i want to set the UIImagePicker source according to what the user has passed in.
I have made 2 different methods. one with camera source and one with "photoslibrary".
I don't know how to invoke one of these methods based on the use choice from the previous controller.
Am i going the right way with this approach? or should i just have one controller?
Basically there are two ways of passing data to a view controller.
Storyboard
If you are working with storyboard segues (that is, control drag from your "root" view controller to the destination view controller, choose a transition style and define a identifier), you can present the view controller
via
[self performSegueWithIdentifier:#"yourSegueIdentifier" sender:self];
Most of the times your destination view controller will be a custom class, so define a public property to hold the data you want to pass through. Then implement the following in your "root" view controller
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Setup the location menu delegate
if([segue.identifier isEqualToString:#"yourSegueIdentifier"]) {
// The custom class of your destination view controller,
// don't forget to import the corresponding header
ViewControllerCustomClass *vc = segue.destinationViewController;
// Set custom property
vc.chosenImageId = self.chosenImageId;
// Send message
[vc message];
}
}
Hints:If your destination view controller is the root view controller of a navigationViewController you can access it via [[segue.destinationViewController childViewControllers] objectAtIndex:0]; Additionally, as senderis an id, you can "abuse" it to pass any object through, just as a NSDictionary, for example.Also note, that when I am referring to the root view controller, I am talking of the view controller from which we segue to the destination from.
Programmatically
ViewControllerCustomClass *vc = [[ViewControllerCustomClass alloc] init];
vc.chosenImageId = self.chosenImageId;
// If you want to push it to the navigation controller
[self.navigationController pushViewController:vc animated:YES];
// If you want to open it modally
[self presentViewController:vc animated:YES completion:nil];
You can use inheritance, make your previous controller superClass, and invoke method in presentViewController in viewDidload.
I have a UIViewController subclass that will itself be subclassed into many custom UIViewControllers. It contains a method to check authentication info, and if the authentication fails, it should segue to a particular view. I am looking at making use of UIStoryboardSegue's *"segueWithIdentifier"* method for this purpose. The question is, what do I specify for the destination parameter, i.e. how do I get the UIViewController instance pertaining to my desired destinationviewcontroller?
I afraid it's not that easy because ever subclass of your view controller could go to different view controller and if you want to do it via segue all of that segue will be different. I think the best solution is let your child view controller decide which segue to fire (which view present/push).
Add your check authentication method like that to the parent view controller
-(void)checkAuthentication
{
if (userAuthenticated)
{
[self userAuthenticatedMethod];
}
else
{
// if you want to go to the same view controller if user not authenticated you can
// perfoem segue like that:
[self performSegueWithIdentifier:#"failedSegue" sender:nil];
// but if it depends on the view controller you are in do it like that
[self userNotAuthenticatedMethod];
}
}
Add declaration of this method to .h file and put empty implementation to .m file:
//in .h
-(void)userAuthenticatedMethod;
//just if you need it
//-(void)userNotAuthenticatedMethod;
//in .m
-(void)userAuthenticatedMethod
{
//override in child
}
//just if you need it
//-(void)userNotAuthenticatedMethod
{
//override in child
}
Now in every child view controller you need to implement userAuthenticatedMethod method and if needed userNotAuthenticatedMethod.
If you want to use segue just do something like that:
-(void)userAuthenticatedMethod
{
[self performSegueWithIdentifier:#"yourSegue" sender:nil];
}
You can also add view controller to view hierarchy programatically. In this scenario each child view controller is responsible to add another view to the view hierarchy.
If you need pass the data you can override prepareForSegue: method in every child VC you want.
I have a common UIViewController that all my UIViewsControllers extend to reuse some common operations.
I want to set up a segue on this "Common" UIViewController so that all the other UIViewControllers inherit.
I am trying to figure out how do I do that programmatically.
I guess that the question could also be how do I set a segue for all my UIViewControllers without going into the story board and do them by hand.
I thought I would add another possibility. One of the things you can do is you can connect two scenes in a storyboard using a segue that is not attached to an action, and then programmatically trigger the segue inside your view controller. The way you do this, is that you have to drag from the file's owner icon at the bottom of the storyboard scene that is the segueing scene, and right drag to the destination scene. I'll throw in an image to help explain.
A popup will show for "Manual Segue". I picked Push as the type. Tap on the little square and make sure you're in the attributes inspector. Give it an identifier which you will use to refer to it in code.
Ok, next I'm going to segue using a programmatic bar button item. In viewDidLoad or somewhere else I'll create a button item on the navigation bar with this code:
UIBarButtonItem *buttonizeButton = [[UIBarButtonItem alloc] initWithTitle:#"Buttonize"
style:UIBarButtonItemStyleDone
target:self
action:#selector(buttonizeButtonTap:)];
self.navigationItem.rightBarButtonItems = #[buttonizeButton];
Ok, notice that the selector is buttonizeButtonTap:. So write a void method for that button and within that method you will call the segue like this:
-(void)buttonizeButtonTap:(id)sender{
[self performSegueWithIdentifier:#"Associate" sender:sender];
}
The sender parameter is required to identify the button when prepareForSegue is called. prepareForSegue is the framework method where you will instantiate your scene and pass it whatever values it will need to do its work. Here's what my method looks like:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"Associate"])
{
TranslationQuizAssociateVC *translationQuizAssociateVC = [segue destinationViewController];
translationQuizAssociateVC.nodeID = self.nodeID; //--pass nodeID from ViewNodeViewController
translationQuizAssociateVC.contentID = self.contentID;
translationQuizAssociateVC.index = self.index;
translationQuizAssociateVC.content = self.content;
}
}
I tested it and it works.
By definition a segue can't really exist independently of a storyboard. It's even there in the name of the class: UIStoryboardSegue. You don't create segues programmatically - it is the storyboard runtime that creates them for you. You can normally call performSegueWithIdentifier: in your view controller's code, but this relies on having a segue already set up in the storyboard to reference.
What I think you are asking though is how you can create a method in your common view controller (base class) that will transition to a new view controller, and will be inherited by all derived classes. You could do this by creating a method like this one to your base class view controller:
- (IBAction)pushMyNewViewController
{
MyNewViewController *myNewVC = [[MyNewViewController alloc] init];
// do any setup you need for myNewVC
[self presentModalViewController:myNewVC animated:YES];
}
and then in your derived class, call that method when the appropriate button is clicked or table row is selected or whatever.
I've been using this code to instantiate my custom segue subclass and run it programmatically. It seems to work. Anything wrong with this? I'm puzzled, reading all the other answers saying it cannot be done.
UIViewController *toViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"OtherViewControllerId"];
MyCustomSegue *segue = [[MyCustomSegue alloc] initWithIdentifier:#"" source:self destination:toViewController];
[self prepareForSegue:segue sender:sender];
[segue perform];
Guess this is answered and accepted, but I just would like to add a few more details to it.
What I did to solve a problem where I would present a login-view as first screen and then wanted to segue to the application if login were correct. I created the segue from the login-view controller to the root view controller and gave it an identifier like "myidentifier".
Then after checking all login code if the login were correct I'd call
[self performSegueWithIdentifier: #"myidentifier" sender: self];
My biggest misunderstanding were that I tried to put the segue on a button and kind of interrupt the segue once it were found.
You have to link your code to the UIStoryboard that you're using. Make sure you go into YourViewController in your UIStoryboard, click on the border around it, and then set its identifier field to a NSString that you call in your code.
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard"
bundle:nil];
YourViewController *yourViewController =
(YourViewController *)
[storyboard instantiateViewControllerWithIdentifier:#"yourViewControllerID"];
[self.navigationController pushViewController:yourViewController animated:YES];
For controllers that are in the storyboard.
jhilgert00 is this what you were looking for?
-(IBAction)nav_goHome:(id)sender {
UIViewController *myController = [self.storyboard instantiateViewControllerWithIdentifier:#"HomeController"];
[self.navigationController pushViewController: myController animated:YES];
}
OR...
[self performSegueWithIdentifier:#"loginMainSegue" sender:self];
well , you can create and also can subclass the UIStoryBoardSegue . subclassing is mostly used for giving custom transition animation.
you can see video of wwdc 2011 introducing StoryBoard. its available in youtube also.
http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIStoryboardSegue_Class/Reference/Reference.html#//apple_ref/occ/cl/UIStoryboardSegue
I'd like to add a clarification...
A common misunderstanding, in fact one that I had for some time, is that a storyboard segue is triggered by the prepareForSegue:sender: method. It is not. A storyboard segue will perform, regardless of whether you have implemented a prepareForSegue:sender: method for that (departing from) view controller.
I learnt this from Paul Hegarty's excellent iTunesU lectures. My apologies but unfortunately cannot remember which lecture.
If you connect a segue between two view controllers in a storyboard, but do not implement a prepareForSegue:sender: method, the segue will still segue to the target view controller. It will however segue to that view controller unprepared.
Hope this helps.
Storyboard Segues are not to be created outside of the storyboard. You will need to wire it up, despite the drawbacks.
UIStoryboardSegue Reference clearly states:
You do not create segue objects directly. Instead, the storyboard
runtime creates them when it must perform a segue between two view
controllers. You can still initiate a segue programmatically using the
performSegueWithIdentifier:sender: method of UIViewController if you
want. You might do so to initiate a segue from a source that was added
programmatically and therefore not available in Interface Builder.
You can still programmatically tell the storyboard to present a view controller using a segue using presentModalViewController: or pushViewController:animated: calls, but you'll need a storyboard instance.
You can call UIStoryboards class method to get a named storyboard with bundle nil for the main bundle.
storyboardWithName:bundle:
First of, suppose you have two different views in storyboard, and you want to navigate from one screen to another, so follow this steps:
1). Define all your views with class file and also storyboard id in identity inspector.
2). Make sure you add a navigation controller to the first view. Select it in the Storyboard and then Editor >Embed In > Navigation Controller
3). In your first class, import the "secondClass.h"
#import "ViewController.h
#import "secondController.h"
4). Add this command in the IBAction that has to perform the segue
secondController *next=[self.storyboard instantiateViewControllerWithIdentifier:#"second"];
[self.navigationController pushViewController:next animated:YES];
5). #"second" is secondview controller class, storyboard id.
I reverse-engineered and made an open source (re)implementation of UIStoryboard's segues: https://github.com/acoomans/Segway
With that library, you can define segues programmatically (without any storyboard).
Hope it may help.
A couple of problems, actually:
First, in that project you uploaded for us, the segue does not bear the "segue1" identifier:
no identifier
You should fill in that identifier if you haven't already.
Second, as you're pushing from table view to table view, you're calling initWithNibName to create a view controller. You really want to use instantiateViewControllerWithIdentifier.
Here is the code sample for Creating a segue programmatically:
class ViewController: UIViewController {
...
// 1. Define the Segue
private var commonSegue: UIStoryboardSegue!
...
override func viewDidLoad() {
...
// 2. Initialize the Segue
self.commonSegue = UIStoryboardSegue(identifier: "CommonSegue", source: ..., destination: ...) {
self.commonSegue.source.showDetailViewController(self.commonSegue.destination, sender: self)
}
...
}
...
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// 4. Prepare to perform the Segue
if self.commonSegue == segue {
...
}
...
}
...
func actionFunction() {
// 3. Perform the Segue
self.prepare(for: self.commonSegue, sender: self)
self.commonSegue.perform()
}
...
}