Following is my code for button action event.
-(IBAction)reportRepair{
if(![Common hasReportRepairURL]){
NSArray *forms = [[self delegate] getFormsForSection:#"REPORTREPAIR"];
if(forms.count == 0){
[self performSegueWithIdentifier:#"ReportRepairView" sender:self];
}else if(forms.count == 1)
[self getFormByFormID:[[forms objectAtIndex:0] intValue]];
else
[self performSegueWithIdentifier:#"FormsView" sender:self];
}
}
and prepareForSegue is as below:
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([[segue identifier] isEqualToString: #"RepairDetailView"]){
RepairDetailViewController *dest = (RepairDetailViewController *) [segue destinationViewController];
dest.job = self.selectedJob;
dest.tenancy = self.tenancy;
}else if([[segue identifier] isEqualToString: #"ReportRepairView"]){
ReportRepairViewController *dest = (ReportRepairViewController *) [segue destinationViewController];
dest.tenancy = self.tenancy;
}else if([[segue identifier] isEqualToString: #"FormsView"]){
FormsSearchViewController *dest = (FormsSearchViewController *) [segue destinationViewController];
dest.allowedForms = [[self delegate] getFormsForSection:#"REPORTREPAIR"];
dest.tenancy = self.tenancy;
dest.formSectionType = #"REPORTREPAIR";
}else if([[segue identifier] isEqualToString: #"FormView"]){
FormViewController *dest = (FormViewController *) [segue destinationViewController];
dest.form = self.form;
dest.tenancy = self.tenancy;
dest.formSectionType = #"REPORTREPAIR";
}
else if([[segue identifier] isEqualToString: #"RepairsWebView"]){
WebViewController *dest = (WebViewController *) [segue destinationViewController];
dest.siteURL = [Common getReportRepairURL:self.tenancy];
dest.screenTitle = AGLocalizedString(#"Report a Repair", #"Report a Repair");
}
}
when I debug the code it is know to me, that prepareForSegue method is called before Action event. Due to this, For UI point of view, I am facing some abnormal behaviour in my application.
You should use either Button click or segues from View controller, but not both. So make sure if already have added segues in view controller in storyboard remove it first.
Important Note :
When we add segues directly from storyboard view controllers than prepareForSegue method call immediately when view appears & it will not wait for the button click event.
Hope it helps.
Try to make segues like below images. Don't draw segues from Button to ViewController. If the segues have been added already remove them.
Related
This question already has answers here:
Passing data between view controllers
(45 answers)
Closed 6 years ago.
I am trying to pass data from one ViewController to another ViewController.
Firstviewcontroller.m
-(void)NavigateToAnotherScreen:(NSMutableDictionary*)dict{
[self performSegueWithIdentifier:#"NavDashBoardToInfo" sender:self];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"NavDashBoardToInfo"])
{
InfoViewController *vc = [segue destinationViewController];
[vc setAppointmentDictionary:dict];
}
}
Secondviewcontroller.h
#property (strong, nonatomic) NSMutableDictionary *AppointmentDictionary;
Secondviewcontroller.m
#synthesize AppointmentDictionary;
- (void)viewWillAppear:(BOOL)animated{
NSLog(#"dict===>%#",AppointmentDictionary); // This gives me null
}
Please help me. What i am doing wrong.
I am getting AppointmentDictionary = (null) in viewwillappear.
Though I am doing proper copy of this.
try this
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.destinationViewController respondsToSelector:#selector(setAppointmentDictionary:)]) {
[segue.destinationViewController performSelector:#selector(setAppointmentDictionary:)
withObject:dict];
}
}
Try this one:
-(void)NavigateToAnotherScreen:(NSMutableDictionary*)dict
{
[self performSegueWithIdentifier:#"NavDashBoardToInfo" sender:dict];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
InfoViewController *info = segue.destinationViewController;
info.AppointmentDictionary = sender;
}
If you are using performsegue for navigation then you can use below method for transferring data between ViewControllers
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"NavDashBoardToInfo"])
{
InfoViewController *info = [segue destinationViewController];
info.AppointmentDictionary = "Value you want to pass";
}
}
You are creating InfoViewController instance and not pushing that view controller. You doing a "performSegueWithIdentifier" here new instance will create, so you first instance "info" is not passing here. You can do in other way.
InfoViewController *info = [[InfoViewController alloc] init];
info.AppointmentDictionary = [dict mutableCopy];
[self.navigationController pushViewController: info animated:true];
Option 2:
-(void)NavigateToAnotherScreen:(NSMutableDictionary*)dict{
[self performSegueWithIdentifier:#"NavDashBoardToInfo" sender: [dict mutableCopy]];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"NavDashBoardToInfo"]) {
InfoViewController *viewController = (InfoViewController *)segue.destinationViewController;
viewController.AppointmentDictionary = (NSMutableDictionary *)sender;
}
}
In the prepareforsegue method you have to pass the value like mentioned above.
Note: make sure your destination view controller is InfoViewController
If you are using performSegueWithIdentifier then provide the body in function . Don't create any new instance using code and provide segue in storyboard -
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"YourController_Segue"]) {
YourController *viewController = (YourController *)segue.destinationViewController;
viewController.AppointmentDictionary = (NSMutableDictionary *)sender;
}
}
I'm trying to get a simple NSLog message if the destinationviewcontroller isKindOfClass like this:
FirstViewController.m
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.destinationViewController isKindOfClass:[SecondViewController class]]) {
NSLog(#"The destinationViewController isKindOfClass SecondViewController");
}
Within the storyboard i have ctrl+dragged from a bar button item in the FirstViewController to the SecondViewController and chosen modal segue.
I've also made sure to #import the SecondViewController.h in FirstViewContrller.m and i have given the SecondViewController the "custom class" of SecondViewController in the identity inspector.
Do i need to add/do something else, because I'm not getting the NSLog message at this point.
Edit: I forgot to inform that i did in fact embed the secondViewController in a navigationViewController.
This should work for you:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
UINavigationController *navigationController = segue.destionationViewController;
if ([navigationController.viewControllers[0] isKindOfClass:[SecondViewController class]]) {
NSLog(#"The destinationViewController isKindOfClass SecondViewController");
}
But if you want something more generic I would do:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
id dvc = segue.destinationViewController;
if ([dvc isKindOfClass:[UINavigationController class]] && ((UINavigationController *)dvc).viewControllers > 0) {
dvc = [[dvc viewControllers] firstObject];
}
NSLog(#"The destinationViewController is: %#", NSStringFromClass([dvc class]));
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
HomeViewController *edit=[segue destinationViewController];
if ([HomeViewController.viewControllers[0] isKindOfClass:[CheckViewController class]])
{
//You are ready for coding here
}
}
Try this code. This might help.
First you would have to set destinationViewController
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([segue.identifier isEqualToString:#"YourSegueIdentifierHere"] )
{
//Now you can assign here the destinationViewController
SecondViewController *secondController = [segue destinationViewController];
//now you don't need this but if you want you can
if([segue.destinationViewController isKindOfClass:[SecondViewController class]])
{
NSLog(#"The destinationViewController isKindOfClass SecondViewController");
}
}
}
You can use [segue.destinationViewController isKindOfClass:[SecondViewController class]]
inside the if statement if you want.But its not needed now you can get the Identifier from your xcode.
What is wrong with below code. It is crashing with SIGABRT (unrecognized selector sent to instance)
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSLog(#"%#",valueName);
if([segue.identifier isEqualToString:#"pushView"])
{
secondViewController *svc = (secondViewController *)[segue destinationViewController];
svc.passedName = valueName;
}
}
The valueName iVar is an NSString which i want to pass.
1) Don't forget to embed you FirstViewController with NavigationController
2) Don't forget to set your segue identifier.
3) Use the same code you have:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
//for example if you value is "123"
NSString *valueName = #"123";
NSLog(#"%#",valueName);
if([segue.identifier isEqualToString:#"pushView"])
{
secondViewController *svc = (secondViewController *)[segue destinationViewController];
svc.passedName = valueName;
}
}
4) Now, in your secondViewController, log you value in ViewDidLoadto see if it is passed...
- (void)viewDidLoad
{
NSLog(#"value: %#", self.passedName);
}
5) The result you should get:
I'm trying to pass an object using unwind segue. My button unwinds successfully, but all the objects in the view are reinitialized or something. I use prepareForSegue method to prepare my object successfully, but when I access the viewController in my destination segue (through an action button) all the objects are either reinitialized or not allocated.
I'm pretty new at this so any suggestions would be appreciated! Here's the code I'm stupefied with.
//prepareForSegue is called in my view controller i'm trying to unwind from.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"ReturnInput"])
{
GLUPipeDataController *dataController;
dataController.length = [[NSNumber alloc] initWithFloat:1.5];
self.dataController = dataController;
[self.dataController print];
}
}
//this done is called in my destination view controller. It is linked in IB by control-draging the unbutton to the exit routine on the connections panel. I then updated the name of the unwind segue in the document outline.
- (IBAction)done:(UIStoryboardSegue *)segue
{
if ([[segue identifier] isEqualToString:#"ReturnInput"])
{
GLUEditViewController *editController = [segue destinationViewController];
if (editController.dataController)
{
self.dataController = editController.dataController;
[self.dataController print];
[[self tableView] reloadData];
}
}
if ([[segue identifier] isEqualToString:#"ReturnInserts"]) {
GLUEditInsertsViewController *editInsertController = [segue destinationViewController];
if (editInsertController.listInserts) {
self.dataController.listInserts = editInsertController.listInserts;
[[self tableView] reloadData];
}
}
}
The call [self.dataController print] in prepareForSegue prints property. But the same call in the done method prints a newly initialized object.
I've one problem. I have a ViewController1 whcich opens the ViewController2 through a push-segue. //Both are NavigationControllers
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"show2"])
{
ViewController2 *vc2 = [segue destinationViewController];
}
}
But is it possible to deactivate the animation of this push-action, so it directly shows the new ViewController?
Why not just do something like this?
[ViewController1 pushViewController:ViewController2 animated:NO];