Parameter passing between two views - objective-c

I use a first view (a class) where there is a button that shows me one second view (another class).
display looks like this:
listContactsViewController viewController * = [[listContactsViewController alloc] init];
UINavigationController * vc = [[UINavigationController alloc] initWithRootViewController: viewController];
[self presentModalViewController: vc animated: YES];
Then in the second view, I select the rows and then I have an "add" button that to display the first view as this:
[self dismissModalViewControllerAnimated: YES];
My problem is that in the second view I have an NSMutableArray that I would like to send to the first view.
If you have an idea.
Thank you.

There are many way to solve this.
Quick: in your second view controller
listContactsViewController
define a delegate property which holds a reference to the presenting controller (the one where you would like to use the NSArray created in listContactsViewController. Then, before dismissing the view controller, call a method in the delegate interface so that your presenting controller can get a copy of the array.
This is just a quick solution to your problem, though, not the best one.
A more correct solution would be to create a "model" object that is accessible from any controller in your app (a singleton would do) that holds the relevant data: listContactsViewController stores the array into the model; the presenting controller gets it from there.

Use Delegates and Protocol.
Refer this tutorial : Passing data between views tutorial – using a protocol & delegate in your iPhone app.

Related

How to Access the UIViewController class/className that presents a Modal View?

Just a simple question
Currently i present a modal view like this:
+ (void)showModalController:(id)ContentController InViewController:(UIViewController*)vc withFrame:(CGRect)rect{
UINavigationController *modalViewNavController = [[UINavigationController alloc] initWithRootViewController:ContentController];
modalViewNavController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
modalViewNavController.modalPresentationStyle = UIModalPresentationFormSheet;
[vc presentModalViewController:modalViewNavController animated:YES];
//it's important to do this after presentModalViewController
modalViewNavController.view.superview.frame = rect;
//self.view assumes the base view is doing the launching, if not you might need self.view.superview.center etc.
modalViewNavController.view.superview.center = vc.view.center;
[modalViewNavController release];
}
I pass the values of the UIViewController Content that it will be presented, at a custom modal size. I also pass the values of the UIViewController where the modal it will be presented.
In terms of code, i want to know the "vc" name at the content class, if it's possible to do so.
EDIT
Lets say i have 2 classes, one is called DetailViewController where the modal will be presented. And the other one is called ModalContentViewController.
I want to know at the ModalContentViewController class (when the view appears, or is loaded) the name of the DetailViewController.
Any ideas?
PD: Currently Using...
XCode 4.4.1
iPad Simulator iOS5.1
iOS5.1
Look for the UIViewController property presentingViewController. Here's a quote from the docs:
If the view controller that received this message is presented by
another view controller, this property holds the view controller that
is presenting it. If the view controller is not presented, but one of
its ancestors is being presented, this property holds the view
controller presenting the nearest ancestor. If neither the view
controller nor any of its ancestors are being presented, this property
holds nil.
So you could use that property to get the presenting VC's name.
You can use NSStringFromClass(vc.class) to get the class name as an NSString.

How to addsubview to a view on class1 from class2?

I'm trying to do a really simple thing - I've got a main Xib file for the whole app and another Xib file for a small view.
I want the small view (Xib called "additionalView.xib") to appear in the first Xib ("ViewController.xib").
I have succeeded to do so in the "ViewController.m" but I want more - I want to do it from "additionalView.m"
There is a method I created called "openView:" in "additionalView.m" and it looks like this:
-(IBAction)openView:(id)sender
{
ViewController *vc = [[ViewController alloc] init];
NSArray *nibObjects = [[NSBundle mainBundle] loadNibNamed:#"additionalView" owner:self options:nil];
UIView *nibView = [nibObjects objectAtIndex:0];
[vc.view addSubview:nibView];
}
The method is being called and the lines are being read by the debugger - but nothing happens.
No crash - No error - No small view in bigger view.
Why is that?
I know that the last line is probably what's
screwing everything up but i don't know how to put it correctly.
Your problem is that ViewController *vc = [[ViewController alloc] init]; creates a new view controller. Because it's new, it's not the one that already exists in the view controller hierarchy that's managing the display.
Your method needs to access the existing view controller. How it does that depends on your app's structure and which object has a reference to the original controller object.
Try
[self.view addView:view.vc];
However, I'm not sure what is you view structure here. You say your -(IBAction)openView:(id)sender is in your "additionalView.m", but it is not the main view controller, correct? You need to do this in the main controller, so basically move the openView: method to your ViewController.m
And you normally need a separate view controller for each view to keep things neat and separate, so the additionalView.m should be an instance of UIViewController, which you can then create from your main view as follows:
-(IBAction)openView:(id)sender
{
AdditionalView *vc = [[AdditionalView alloc] initWithNibName:#"additionalView"];
[self.view vc.view];
}
You have options ... First you don't need to create a view controller vc if you just need the view . Create a uiview and add it .
Option 1: pass a ref to the app vc as suggested above and then :
[appVC.view addsubview:additionalView]
This will add it to main.
Use a view controller manager / ref in the app delegate that you can refer to as delegate and add your view to the current showing view.
Hope this helps

Container View Controllers pre iOS 5

iOS 5 adds a nice feature allowing you to nest UIViewControllers. Using this pattern it was easy for me to create a custom alert view -- I created a semi-transparent view to darken the screen and a custom view with some widgets in it that I could interact with. I added the VC as a child of the VC in which I wanted it to display, then added its views as subviews and did a little animation to bring it on the screen.
Unfortunately, I need to support iOS 4.3. Can something like this be done, or do I have to manage my "alert" directly from the VC in which I want to display it?
MORE INFO
So if I create a custom view in a nib whose file owner is "TapView" and who has a child view that is a UIButton. I tie the UIButton action to a IBAction in TapView.
Now in my MainControllerView I simple add the TapView:
TapView *tapView = [[TapView alloc] init];
[[self view] addSubview:tapView];
I see my TapView, but I can't interact with the UIButton on it and can interact with a UIButton on the MainControllerView hidden behind it. For some reason I am not figuring out what I'm missing...
Not sure if this helps, but, in situations where I've needed more control over potential several controllers, I've implemented a pattern where I have a "master" controller object (doesn't need to be descendent from UIViewController), which implements a delegate protocol (declared separately in it's own file), and then have whatever other controllers I need to hook into declare an object of that type as a delegate, and the master can do whatever it needs to do in response to messages from the controllers with the delegate, at whatever point you need; in your case, that being displaying the alert and acting as it's delegate to handle the button selection. I find this approach to be very effective, simpler and usually cleaner. YMMV ;-)
Regd. your second query, where you are trying to create a custom view using nib. Don't change the FileOwner type, instead set "TapView" for the class property of the top level view object.
Once you have done this, you might experience difficulty when making connections. For that just manually choose the TapView file for making connections.
Also, to load the view you need to load its nib file. For which you can create a class level helper method in TapView class like below
+(TapView *) getInstance
{
NSArray *bundle = [[NSBundle mainBundle] loadNibNamed:#"TapView" owner:self options:nil];
TapView *view;
for (id object in bundle) {
if ([object isKindOfClass:[TapView class]]) {
view = (TapView *) object;
break;
}
}
return view;
}
Now, you get a refrence to you view object like this
TapView *tapView = [TapView getInstance];

How to load a view controller using a segmentControl value change event?

I have three views each represented by a View controller named firstVC, secondVC and thirdVC. In the firstView (firstVC) I have a segmented control with three options first,second and third. When I click on the second segment control I want to load the corresponding view controller which in this case would be secondVC. I am new to View Controllers but I did try various options. I created an outlet and also a value changed event. I event tried pushing a view controller when the value changes but it pulls a blank page as opposed to secondVC.
Please see below for the code.
- (IBAction)chainAction:(id)sender {
UINavigationController *navcon = self.navigationController;
if (chainSegControl.selectedSegmentIndex == 1) {
secondVC *atSecondVCChain = [[secondVC alloc] init];
[navcon pushViewController:atSecondVCChain animated:YES];
}
}
Any help would be greatly appreciated. Thank You.
P.S I am using Xcode 4.2
Instead of using alloc to create a controller, define a named segue in your storyboard (if you don't already have one) that describes a push from firstVC to secondVC and then use the performSegueWithIdentifier:sender: method instead of pushViewController:.

Subclassing in objective c and viewWillAppear message delegates?

I might be confused here and asking the wrong question.
If I use a class like the UISplitViewController inside the appdelete.m, will the only message i will receive is the message the UISplitViewController calls and not any VIEW message? for example:
in my myappdelegate.m
....
UISplitViewController *mySplitViewController = [[UISplitViewController alloc] init];
mySplitViewController.viewControllers = [NSArray arrayWithObjects:leftside,rightside,nil];
...
mySplitViewController.delegate = self;
....
[windows addSubView:mySplitViewController.view];
....
-(void) viewWillAppear:(BOOL) animated {
}
in myappdelegate.h I included UISplitViewControllerDelegate
I expected viewWillAppear to fire but it is not. I assume if I had subclass UISplitViewControler it would have fire. right?
BTW: I am doing this without using IB. Do I need to set the target for the mySplitViewController?
What I want to do is setup the orientation of the splitviewcontroller when it rotates.
the viewWillAppear method and other view related methods will be called on the view or view controller themselves, not on the delegate.
That means that if you make a subclass of UISplitViewController called SplitViewControllerSubClass, the view... methods will be called on the instance of SplitViewControllerSubClass, not on the delegate object.
But considering you are creating the views and displaying them programmatically, you already know exactly when the view will appear (i.e., right before you add it to the window), so I believe you could do whatever setup you want at that point.