Call a method with childViewControllers on the same viewController - objective-c

I'd like to know how to call a method in childViewController01 from childViewController02.
These ViewControllers are declared on the parentViewController, as follows.
○ParentViewController.m:
ChildViewController01 *childViewController01 = [[ChildViewController01 alloc] init];
[self.view addSubView:childViewController01];
ChildViewController02 *childViewController02 = [[ChildViewController02 alloc] init];
[self.view addSubView:childViewController02];
I know the way to call parentViewController's method from childViewController01.
○ParentViewController.m:
childrenViewController01.childDelegate01 = self;
○ChildrenViewController01.h:
#property (nonatomic, retain) id childDelegate01;
○ChildrenViewController01.m:
[childDelegate01 performSelector:#selector(parentMethod:) withObject:hogeObj];
so, I can call childViewControllers's method from parentViewController
○ParentViewController.m:
- (void) parentMethod:(id)hogeObj {
[childViewController02 childMethod02];
}
This is so tiring. I'd like to call childMethod02 from childViewController01 directly.
If you know how, please let me know a good way.
Thanks.

Part of the reason you use view controllers at all is to keep things separate and tidy. One view controller shouldn't really know anything about its siblings; it's only responsibility is managing it's view and child view controllers. The parent view controller should be in charge of managing the sibling view controllers. Your options to do this are to tell the parent view controller what you want to happen and have the parent send the message to the other view controller, "pollute" the state of the view controllers with references to each other like Metabble suggested, or use a notification pattern.
I've often used NSNotificationCenter for this purpose. Register for the notifications in each view controller and then post notifications to trigger the method calls in the other view controllers.

When you create the controller's, give them references to each other and store them.

Related

Parameter passing between two views

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.

Accessing an instance method of a ViewController From Another view controller

Let's say I have a view controller called vc1, which a synthesized property called property1, and i wants to access it from another view controller (vc2) and change it from vc2.
Now the methods created by the #syntisize to change and get properties are instance methods, so how can I get to them fro another view controller (do view controllers have instances in the app, and if so, what are they?)
Just to be clear I am using storyboards, so I never really instantiate the view controllers...
VC1.m:
-(void) yourMethod {
...
}
VC2.m
YOURViewController * vc2 = [[YOURViewController alloc]init];
[vc yourMethod];
[vc release];
Make sure to import your YOURViewController in your other view .m file
Something like that should work.
Or if you're having problems, try this tutorial here:
Tutorial on How-To Pass Data Between Two View Controllers
Hope this helps :)
While you can do it the way you describe, I think the common technique (assuming VC1 has a segue to VC2) is a bit different, where VC2 will have a property that will be set by prepareForSegue. See Configuring the Destination Controller When a Segue is Triggered in the View Controller Programming Guide.
You will need to link the storyboard views with the viewcontrollers so the view for vc1 would use the class vc1 etc for the rest (I assume you have done this because this is important when coding for different views)
Then all you need to do is where ever you are calling the properties so lets say the viewDidLoad method, declare the view controller like this:
- (void) viewDidLoad {
vc1 *viewController;
// Now you change the variable I'll presume its a UILabel so I'll change its text [viewController.property1 setText:#"I changed a different views UILabel"];
}
Let me know whether this works... Its worked for me before so should work

Push view to navigation controller from button in other class

I have a UIButton that I create in my sub class ViewController, and add it to my MainViewController.
Now, I added a target method to this button that should push another view controller to my Navigation controller (the one that in the MainViewController).
I know that the method did call when I push the button, but the view wasn't push to the Navigation Controller.
I scanned this drawing - this is the drawing (I also added part of my code):
This is the code I'm using in my button:
(remember it's in a deferent ViewController).
- (void)buttonPressed:(UIButton *)sender
{
Photo_ScreenGlobalView *photo = [[Photo_ScreenGlobalView alloc] init];
[self.navigationController pushViewController:photo animated:YES];
}
Usually I solve these situations with delegation. If there is a view controller which is subordinate to another (i.e. a "sub" view controller) but should have the ability to trigger navigation changes, etc... then it should have a weak pointer back to it's 'parent'. Then the parent VC should implement an appropriately named protocol with a callback for the child to use. The names of these things can be generic, such as #property navigationDelegate and requestNavigationToViewController: or they can be more semantic, such as #property userFormDelegate and userFormDoneButtonPressed:
Generally speaking, a subordinate view controller should not be able to directly modify navigation at it's parent's level; but it can trigger it via more loosely-coupoled interfaces like these.
i came back to let you all know how i actually did it.
after googling a lot found this nice and quick guide how to make DELEGATE
and working with delegate solved all my problems. if you need any help don't hesitate to send me PM.
this is the guide:
http://css.dzone.com/articles/do-not-publishcreating-your

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.

Managing multiple view controllers and data

My app has a main screen that the user always starts at, and from which I want to display other views programmatically. I set up the app identically to the approach in "Beginning iPhone Development" Ch. 6, which is to use a RootViewController that loads in other view controllers.
The book uses a button to trigger loading the next view controller, but in my app I need to swap controllers at the end of function calls and to share data (processed UIImages, etc) between views. I am not using a tab bar or navigation controller.
What I'm wondering is, should I just make my MainViewController the root controller and presentModalViewControllers from there? I'd like to keep the root model but I don't quite understand how to hook it all up and share data. I've seen posts that mention using protocols and notifications but I haven't wrapped my head around it yet. Any advice is appreciated.
What you want to do is add a Cocoa property in your main view controller that references the object instances which you want to share with subordinate view controllers.
For example, if we want to share an NSArray, we specify its property in the main view controller header:
#interface MainViewController : UIViewController {
NSArray *myArray;
}
#property (nonatomic, retain) NSArray *myArray;
#end
In the implementation, add the #synthesize directive and remember to release the array in -dealloc:
#implementation MainViewController
#synthesize myArray;
...
- (void) dealloc {
[myArray release];
[super dealloc];
}
#end
You also want to add this property to view controllers that are subordinate to the main view controller, in the exact same way. In their headers, specify the same variable name and property description.
In your main view controller, when you are ready to push a subordinate view controller, you set the subordinate view controller's property accordingly just before pushing:
- (void) pushSubordinateViewController {
SubordinateViewController *subVC = [[SubordinateViewController alloc] initWithNibName:#"SubordinateViewController" bundle:nil];
subVC.myArray = self.myArray; // this sets the sub view controller's myArray property
[self.navigationController pushViewController:subVC animated:YES];
[subVC release];
}
Likewise in your subordinate view controller, it will need to set its subordinate's array property accordingly, just before it pushes its own sub-sub-view controller.
By setting references in this way, each view controller is pointed at the same array, containing the desired elements.
To use the array, just call self.myArray, e.g. [self.myArray objectAtIndex:index] to get an object at a given index.