I have a UIViewController in my IPhone application.For some animation i make a view like rootview with in that and added all the elements in that.When clicking on a button i removed that rootview and added another view controllers view.The problem is i was only loaded the view.I want to execute a function with in the new view controller.For that i need to set the first view controller as a delegate of the second view controller?can anybody help me ?
in secondVC, define something like the following:
#protocol secondVCDelegate
#interface secondVC : UIViewController
#property (nonatomic, assign) id<secondVCDelegate> delegate;
#end
#optional
-(void)someDelegateMethod:(secondVC*)viewController;
#end
at the time of creating the instance of secondVC you must assign the delegate property of secondVC to self! something like this:
// in firstVC
secondVC vc = [[secondVC alloc]...];
vc.delegate = self;
[navcontroller pushVC:vc];
the line vc.delegate = self; does the trick.
hope it helps...
Not sure from your typing that you want to call method of which controller from which controller?
Two scenarios:
A. In the first view controller you want to call a method of second view controller, use this:
[instantOfSecondViewController methodInSecondVC];
B. In the second view controller, you want to call a method of the first view controller. In this case you need to use The delegate pattern.
I have posted an example of both in this SO.
Related
Noob question fellas, but I cant get it.
I've got a View Controller that loads in a separate View Controller. I would like to be able on a button press to call a method inside the parent View controller. So here is what i've got
parent VC:
.h
-(void)callParentMethod;
.m
-(void)viewDidLoad{
self.childVC.parentVC = self;
}
-(void)callParentMethod{
NSLog(#"Hello?");
}
child VC:
.h
#import "TheParentViewController.h"
#property (nonatomic, weak) TheParentViewController *parentVC;
.m
-(void)addThis{
[self.parentVC callParentMethod];
}
I get no errors, the child VC method addThis seems to call the method, but the NSLog is never called. Any thoughts what i'm doing wrong?
I think parentVC releases because of weak reference. Try to use this method.
-(void)addThis{
NSLog(#"%#", self.parentVC);
[self.parentVC callParentMethod];
}
YourParentVC *parent = (YourParentVC*)[self presentingViewController];
parent.whatever = blah;
I am not quite sure what your application is, but you should not have to keep a reference to the parent view controller. A UIViewController already has a property called parentViewController which you can use in the following way:
[self.parentViewController methodToCall];
This will call a method on the parent view controller. You may need to cast the object in order to call custom methods
[(TheParentController *)self.parentViewController methodToCall];
This of course assumes that the child view controller's view is a subview of the parent view controller view. Hope this helps
Check whether your parent view controller is allocated.
parentnvc = [ParentViewController alloc]initWithNibName:#"somenib" bundle:nil];
if parentvc is allocated and initialised and call the method
You can create a property in child view controller say,
#class ParentVC;
#property(weak,nonatomic)ParentVC *parentVCreference;
and get the reference for the Parent view controller as follows
self.parentVCreference=(ParentVC*)self.parentViewController;
then you can call any exposed methods from ParentVC as follows
[self.parentVCreference parentVCMethod];
Note: You need to import header of ParentVC in ChildVC implementation file.
How would I go about changing the a UILabel property in another view controller?
I have #import "SecondViewController.h" imported in the FirstViewController.m file and then
I have the following in a method in FirstViewController
-(IBAction) someAction {
SecondViewController *objV1 = [[SecondViewController alloc]init];
objV1.secondViewControllerLabel.alpha = 0.2;
NSLog(#"someAction");
}
when someAction is called nothing happens to the UILabel in the SecondViewController.
also, in this example both first and second view controllers are in another view controller called MainViewController. So, they are both onscreen at the same time.
thanks for any help.
From what you tell us, it would seem that you need to set the "embeded view controllers" as childs of the parent View Controller.
[mainViewController addChildViewController:childViewController];
[childViewController.view setFrame:self.view.bounds];
[self.childContainerView addSubview:childViewController.view];
[childViewController didMoveToParentViewController:self];
This is very powerful, because you can forward IBActions from the mainViewController to their child...
[mainViewController childViewControllers]
Returns an array of them, and also take a look at
– shouldAutomaticallyForwardRotationMethods
– shouldAutomaticallyForwardAppearanceMethods
So your child get automatically informed about the rotations of their parent.
To answer your question, you could do something like:
// In Parent View Controller
- (IBAction) anAction:(id) sender
{
for (CustomChildController *child in self.viewControllers) {
[child handleSomeAction];
}
}
Check out what the docs say for more details.
#Goles answer will work, but if you specifically want to trigger the change from FirstViewController.m you need to pass in a reference to SecondViewController somehow.
So you could do it with a custom init that takes a reference to your second viewcontroller as a parameter, or create a property on your FirstViewController that you can set from outside, which would be something like this:
FirstController.h:
#interface
..
#property (strong, nonatomic) UIViewController *second;
...
#end
FirstController.m:
#implementation
#synthesize second
In your parent ViewController you would create both the child view controllers, then:
ViewController1.second = ViewController2;
Then your action method would become:
-(IBAction) someAction {
self second.secondViewControllerLabel.alpha = 0.2;
NSLog(#"someAction");
}
Since in the secondViewController, secondViewControllerLabel has not been created yet, 'objV1.secondViewControllerLabel.alpha' will have no effect. Ideally, you should create a NSNumber property called labelAlpha in the secondViewController, set that property in the firstViewController, and then in the viewDidLoad of the second controller, add this line ::
self.secondViewControllerLabel.alpha = self.labelAlpha;
This will work for you.
I have a View-based app. The first view that is loaded has a button which loads another view using this code:
AddPost *addView = [[AddPost alloc] initWithNibName:#"AddPost" bundle:nil];
addView.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:addView animated:YES];
What I want to do is provide a button on the view (AddPost) that will let me close it and go back to the original view. How can I do this?
It seems a little strange, but you can actually have addView call:
[self dismissModalViewControllerAnimated:YES];
From the docs:
"The parent view controller is responsible for dismissing the modal view controller it presented using the presentModalViewController:animated: method. If you call this method on the modal view controller itself, however, the modal view controller automatically forwards the message to its parent view controller."
The answer Conrad gave will work perfectly well. In the name of slightly better encapsulation you could put a delegate protocol on addView and have your first view implement this.
So in the header file for your addView controller:
#protocol addViewDelegate <NSObject>
- (void)addViewRequestDismissal;
#end
You will also need an external properly on the addView controller:
#property (assign) id<addViewDelegate> delegate;
Then make your first view controller implement this, so in it's .h file you should have
#interface firstView : NSObject <addViewDelegate> {
}
When you instantiate your addView remember to set the delegate:
addView.delegate = self;
In the addView controller when your button is pressed call back:
- (void)buttonPressed {
[self.delegate addViewRequestDismissal];
}
Finally in your first view remember to implement this method
- (void)addViewRequestDismissal {
[self dismissModalViewControllerAnimated:YES];
}
Hope all goes well with this. Post back if you have any further problems :)
I have an UIViewController with a UIToolBar at the top with 3 buttons and a UIView, when touch upInside those buttons I have to change the views that the controller has. What can I do to get my porpuse? Thanks in advance.
You probably want to use something like a UINavigationController to control the view stack and then have your button(s) call one of these methods for the Touch Up Inside action:
pushViewController:animated:
popViewControllerAnimated:
popToRootViewControllerAnimated:
popToViewController:animated:
Here is a good uinavigationcontroller-tutorial to look into.
You need to do something like this for each of the actions you set up.
In the .h file of the current viewController:
#import "OtherViewController.h"
#interface MyViewController : UIViewController
{
OtherViewController *otherViewController;
}
#property(nonatomic, retain)IBOutlet OtherViewController *otherViewController;
Then in the .m file of the current viewController you need to add the following for each IBAction (touch up inside).
At the top of the .m file add:
#synthesize otherViewController;
Then make an IBAction and put the following line of code to display the other view:
[self presentModalViewController:otherViewController animated:NO];
In your otherViewController you can dismiss itself by using:
[self dismissModalViewControllerAnimated:NO];
NOTE: The other thing you will need to do is create a UIViewController in Interface Builder for each of the views you plan to display. You need to then go into the identity inspector and set the Class as OtherViewController. You then need to link the IBOutlet to the OtherViewController as normal.
There is a YouTube video tutorial which covers all of what I have mentioned above. It's a nice simple way to get started.
UiViewController view property is the base view you are seeing. It could be set(replaced with another). SO replace the view object of ViewController with another view you created.
UIView * customView = [[[UIView alloc] initWIthFrame:viewFrame] autorelease];
[self setView:customView];
Here self represent the current viewController.
I have a UITableView in a UINavigationController. On the navigation bar I have a button called add. When this button is pressed it presents a UIPopoverController, where user can input data to be added as a new row/cell in the UITableView. My issue is how can I add a new cell to the UITableView from the UIPopover? Do I pass in the array data to the UIPopOver root controller?
There are two solutions to this that I'm aware of. One would be to send a notification from the popover to the root controller and apply the necessary code to update the tableView in the handleNotification method.
The other, one that I personally use, is to set up a delegate protocol for the popover. You'll have to set it up something like this:
#protocol PopoverDelegate
- (void)addNewCell; // you can add any information you need to pass onto this if necessary such as addNewCellWithName:(NSString *)name, etc.
#end
#interface MyPopoverViewController..... {
id <PopoverDelegate> delegate;
// the rest of your interface code;
}
#property (nonatomic, retain) id delegate;
// any other methods or properties;
#end
Then in your root view controller header file, you need to add the delegate
#interface RootViewController .... <PopoverDelegate> {
Then in your root view controller implementation file, assign the popover delegate when you instantiate it. For example:
MyPopoverViewController *vc = [[MyViewController alloc] init];
vc.delegate = self; // this is where you set your protocol delegate
myPopover = [[UIPopoverController alloc] initWithContentViewController:vc];
myPopover.delegate = self;
[vc release];
Finally, you'll add your protocol method somewhere in the code
- (void)addNewCell {
// do what you want with the tableView from here
}
Sorry that's a bit long. I just wanted to make sure I was thorough. Hope it helps