Transitioning to view programmatically ios - iphone

I have a view that carries out a task, when the task is completed the activity indicator will become hidden, I want to send the user to another view when the activity is completed, or give the user an error if unsuccessful. So far I am using an If Else statement to give a success alert or an error alert. There is no buttons to click or anything, simply after the activity is completed the user will be sent to another view passing a few variables along the way.
How would I go about sending the user to another view after completion?

If you use a navigationcontroller:
[self.navigationController pushViewController:theNextViewController animated:YES];
For Storyboard, look up the method in the docu.

To elaborate on AlexWien's answer a little...
Create a view controller or table view controller class that you want
the user to go to after completion.
Create some properties for the data you want to pass in.
#protocol UpdatePricesDelegate;
#interface NXUpdatePricesViewController : UITableViewController
#property (strong, nonatomic) NSArray *calculationProducts;
#property (strong, nonatomic) NSArray *filteredCalculationProducts;
#property (weak, nonatomic) id<UpdatePricesDelegate>delegate;
#end
#protocol UpdatePricesDelegate <NSObject>
- (void)updatePricesController:(NXUpdatePricesViewController *)controller didUpdateCalculationProducts:(NSArray *)calculationProducts;
#end
When you are ready to display your controller (presumably in your If/Else statement), instantiate the class (don't forget #import "MyClassName.h") and set the properties to the variables you want to pass.
Present the class modally (example includes a navigation controller), or if you want to push the view, use your navigation controller.
NXUpdatePricesViewController *updatePricesController = [[NXUpdatePricesViewController alloc] initWithStyle:UITableViewStyleGrouped];
updatePricesController.delegate = self;
updatePricesController.calculationProducts = self.calculationProducts;
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:updatePricesController];
navigationController.modalPresentationStyle = UIModalPresentationFormSheet;
[self.navigationController presentViewController:navigationController animated:YES completion:nil];
NXCalculationViewController *calculationController = [[NXCalculationViewController alloc] init];
calculationController.calculation = calculation;
[self.navigationController pushViewController:calculationController animated:YES];

I actually got it working, along with passing a variable to the other view using this method:
DetailViewController *detail = [self.storyboard instantiateViewControllerWithIdentifier:#"DetailView"];
[detail setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
detail.videoURL = outputURL;

Related

Passing data between view controllers ios 7

I'm working on an app and I need to pass data between view controllers. I know this is a common question but I couldn't find an answer for my problem : I'm able to pass data from the FirstViewController (MasterViewController in my case) to the SecondViewController (SettingsViewController) but not the reverse. What happens is that I call a method from the FirstViewController in my SecondViewController.m file. This works and it logs the data. But when I quit the SecondViewController (using [[self presentingViewController] dismissViewControllerAnimated:YES completion:nil];) the data is reset.
I tried using other methods to pass data but it didn't work. I'm using this code to pass data:
MasterViewController *vc = [[MasterViewController alloc] initWithNibName:#"MasterViewController" bundle:nil];
[vc setPorts:SelectedPorts];
I also tried replacing [vc setPorts:SelectedPorts]; with vc.selectedCellIndexes = SelectedPorts; but the same problem occurs.
the setPorts method is declared in the FirstViewController.h file and SelectedPorts is a variable I declared in SecondViewController.m (it's not nil I checked).
Here's the setPorts: in FirstViewController.m :
- (void) setPorts:(id)selectedPorts {
selectedCellIndexes = selectedPorts;
NSLog(#"selectedCellIndexes : %#", selectedCellIndexes);
}
This logs the good value but when I log it in viewWillAppear in FirstViewController.m it's reset to the value it has before I called the method from SecondViewController.m.
Just to clarify, if I DON'T quit the SecondViewController.m, the data isn't reset.
I did read all your comments, and I really thanks you for your help. for convenience, I used a global variable.
Thanks for your help.
You have a list of ports in MasterViewController and you expect to use it in the SettingsViewController.
The MasterViewController can hold this list and SettingsViewController should have an access to it.
In SettingsViewController, have a setSelectedPort method:
#property (nonatomic, retain) id selectedPorts
- (void) setPorts:(id)selectedPorts;
The method saves the selected ports list into a property.
In MasterViewController, call the SettingsViewController and give it the list.
SettingsViewController *vc = [[SettingsViewController alloc] initWithNibName:#"SettingsViewController" bundle:nil];
[vc setSelectedPorts:yourValue];
When the list is modified inside the SettingsViewController, the list of ports contained in MasterViewController won't move even if you leave the SettingsViewController.
In secondViewController, You create protocol
#import <UIKit/UIKit.h>
#protocol sampleDelegate <NSObject>
- (void)passValue:(id)selectedPorts
#end
#interface SecondViewController : UIViewController
#property (nonatomic, strong) id <sampleDelegate> passDelegate;
#end
In viewDidLoad or wherever method as per your need, call method like this,
[self.passDelegate passValue:selectedPorts];
In FirstViewController.h,
Import the delegate <sampleDelegate>,
#import "SecondViewController.h"
#interface FirstViewController : UIViewController<SampleDelegate>
#end
In FirstViewController.m,
-(void)passValue:(id)selectedPorts
{
id receivedValues = selectedPorts;
}
and set self in your SecondViewController allocation,
SecondViewController *vc = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
vc.passDelegate = self;
There is nothing unusual in the getting result. By doing
MasterViewController *vc = [[MasterViewController alloc] initWithNibName:#"MasterViewController" bundle:nil];
[vc setPorts:SelectedPorts];
You are creating a new instance of MasterViewController from your SecondViewController. This is not the same from which you navigated to the SecondViewController. So you wont get the expected result. Since you are setting the ports([vc setPorts:SelectedPorts]) to the newly created instance of the Master.
Instead of creating a new instance,just hold the reference of the MasterViewController in SecondViewController in a property and assign it before moving to second VC. As a beginner I suggested this way. But using delegate is the prefferred way passing data back.
Either use delegate methods to communicate with the master VC from the modal VC, or you could do something like this if you want to retrieive some manipulated objects from the modal VC.
Set the object(s) as properties in the modal view controller's .h-file (so they are public).
Using unwind segues, in the master VC, just do this:
-(IBAction)exitModalVC:(UIStoryboardSegue*)segue
{
SomeObject *obj = ((YourModalVC*)segue.sourceViewController).someObject;
//Do what you want with obj
}
EDIT:
This will only work if you are using unwind segue (which is a neat way of dismissing modal VC when using story board)
And you are using this, which is not unwind segues:
[[self presentingViewController] dismissViewControllerAnimated:YES completion:nil];
You were creating a new instance of the first view controller from the 2nd view controller not accessing the same instance of the original caller. That was the reason why while you could see the logs but data were not there when you got back to the original caller - your MasterViewController.
You need to use delegate method. Check my answer for this SO.
This is problem related to object ownership.
Follow the below steps:
As per understanding you want reverse value from "SecondViewController" to "FirstViewController"
Don't create new object of FirstViewController in SecondViewController, it will not work.
Create object of "FirstViewController" in "SecondViewController.h" file.
#property (nonatomic,strong) FirstViewController *firstViewController;
When you navigate from FirstViewController to SecondViewController, please pass the "self".
e.g. SecondViewController *vc = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
vc.firstViewController = self;
If you want pass the reverse value to FirstViewController then in SecondViewController.m file.
[self.firstViewController setPorts:SelectedPorts];
And in FirstViewController.m refresh your controls with latest values.
Try above code will defiantly work as per your requirement.

Set Title with Modal View doesn´t work

I initiate the following Modal Controller:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UIViewController *modal = [storyboard instantiateViewControllerWithIdentifier:#"modalController"];
modal.title = #"Example Title";
[self presentModalViewController:modal animated:YES];
I set the title with:
modal.title = #"Example Title";
but this doesn´t work, can anyone help me?
Edit:
I have wrapped my ModalView with a UINavigationController like this
You are going about this in a slightly convoluted way... but to stay with your paradigm, you need to present the navigationController, not the contained viewController: trying to do it the latter way will instantiate the viewController, but this action will not pull the containing navController along with it out of the storyboard. You are setting the viewController's title property ok, but you have no (automated) way to display the title. Whereas if you instantiate the navController, it's contained viewController does get unarchived along with it as it's topViewController.
//give the navigation controller a storyboard id eg "navVC"
UINavigationController* modalNav = [self.storyboard instantiateViewControllerWithIdentifier:#"navVC"];
[modalNav topViewController].title = #"Example Title";
//[self presentModalViewController:modalNav animated:YES];
//deprecated method, use this instead:
[self presentViewController:modalNavController
animated:YES
completion:nil];
You have to add a IBOutlet property for UINavigationItem (the title) in your model controller with a classic drag & drop method.
#property (weak, nonatomic) IBOutlet UINavigationItem *navTitle;
Then set the title in viewDidLoad function.
- (void)viewDidLoad
{
[super viewDidLoad];
// title view
[self.navTitle setTitle: #"atitle"];
}

How to pass the Uiimage when popview controller in iphone

Any one have exact solution for passing image from one view to other view when using popview controller in iPhone.
Please give me some guidelines for this problem.
Thanks.
Using Protocol Delegate method use the image, or else assign your image to another controller image object and use it.
suppose your imageview is existingImageView;
.h
#interface SecondController : UIViewController
#property (retain, nonatomic) UIImageView *previousImageView;
.m
#interface SecondController ()
#end
#implementation SecondController #synthasize previousImageView;
Now in firstController while navigating use it like,
SecondController *second = [[SecondController alloc] init];
[self.navigationController pushViewController:second animated:YES];
[second setPreviousImageView:existingImageView];
[photoController release];
After Cropping Image it will reflect to existingImageView.

How to communicate with different view controller?

I have a VC that presents another VC modally. This 2nd VC pushes to a 3rd VC. The 3rd VC dismisses itself and needs to call a method on the initial VC. I can't seem to get this working. Any advice?
VC3 *aVC3 = [[self.navigationController.viewControllers objectAtIndex:0] parentViewController];
aVC3 = self.name;
[aVC3 addExercise];
[self dismissView];
Use delegate for backward messsaging.
Refer simple-delegate-tutorial-for-ios-development. Also refer the-basics-of-protocols-and-delegates
If you have UINavigationController there is no need of delegate to communicate to any viewController in navigationController like:
ViewController *objViewController = (ViewController *)[self.navigationController.viewControllers objectAtIndex:0]; //need to which controller u would like to communicate
[objViewController yourMethodHere]; // your method here
Here is an alternate method:
Step 1: Create a FirstViewController Property in the SecondViewController.h
#interface SecondaryViewController : UIViewController{
}
#property (nonatomic, strong) FirstViewController *viewControllerOne;
Step 2: set that property to self when presenting the SecondViewController in FirstViewController.m
#implementation SecondaryViewController
-(void)functionThatPresentsSecondViewController{
SecondViewController *viewControllerTwo = [[SecondViewController alloc] init];
[viewControllerTwo setViewControllerOne: self];
[self presentViewController:viewControllerTwo animated:NO completion:nil];
}
Step 3: You can now call FirstViewController functions from SecondViewController by using the viewControllerTwo.viewControllerOne property.

iPhone - pushViewController Issue

I have a root view controller which should load another view controller as soon as it is done loading (i.e. in the viewDidLoad method).
I am using the UINavigationController in order to push a new view controller onto the stack:
In my rootviewcontrollerappdelegate:
-(void) viewDidLoad{
LoginViewController* lvc = [[LoginViewController alloc]init];
[self.navigationController pushViewController:lvc animated:NO];
}
I have textfields and buttons in the view controller to be loaded. The above doesn't seem to work however...It loads just a blank grey screen and no UINavigation bar is present. If I comment out the second line (pushViewController line), then I see the navigation bar. So I think it is loading something, but the items in the view controller being loaded are not being shown...Any ideas why?
Check if navigationController is pointing to nil. If it does, try
[self.view addSubview:self.pushViewController.view]
I had the same problem and found the above solution here:
UIViewController -viewDidLoad not being called
Unless you're doing something tricky, you should be calling alloc on the LoginViewController class rather than a variable. Also, if you've set up LoginViewController in Interface Builder (as opposed to programmatically), you'll need to load it from an NIB:
LoginViewController *lvc = [[[LoginViewController alloc] initWithNibName:nil bundle:nil] autorelease];
[self.navigationController pushViewController:lvc animated:NO];
Have a look at initWithNibName:bundle: in the docs.
Not entirely sure what you are trying to achieve but when you instantiate LoginViewContoller it should probably look like this
LoginViewController* lvc = [[LoginViewController alloc]init];
Judging by the nature of your naming for your view controller, is your LoginViewController the first view controller for your UINavigationController?
If that is what you're trying to do, you should instead initialise your navigation controller with the LoginViewController as the root controller instead of pushing it onto the navigation stack.
UINavigationController has a method to do this:
- (id)initWithRootViewController:(UIViewController *)rootViewController
EDIT:
Well, one way you can go about it is like this.
In your application delegate .h file, you should have declared a UINavigationController.
#interface MyAppDelegate : NSObject <UIApplicationDelegate>
{
UINavigationController *navController;
}
#property (nonatomic, retain) UINavigationController *navController;
#property (nonatomic, retain) IBOutlet UIWindow *window;
#end
In your App Delegate didFinishLaunching:withOption: you can create an instance of your LoginViewController there, and use that to init your UINavigation controller as the root view controller
#import "LoginViewController.h"
#implementation MyAppDelegate
#synthesize navController;
#synthesize window = _window;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
LoginViewController *loginController = [[LoginViewController alloc] init];
navController = [[UINavigationController alloc] initWithRootViewController:loginController];
[loginController release];
[[self window] setRootViewController:navController];
[navController release];
[self.window makeKeyAndVisible];
return YES;
}
I probably have a typo here or there but that's one way I would go about doing it.