I have created a UITabBarController in my app delegate.
where each tab bar item holds a different UINavigationController that loads a custom UIViewController with a NIB (using -pushViewController:).
Inside one of the navigation controller, I load a custom UIView class with a custom NIB also.
This view is loaded multiple times inside the UIViewController.
The custom UIView has a UIButton, that on the event of touching it, I want to push a new UIViewController on the stack.
Problem is that I 'lost' the UINavigationController that holds the UIViewController.
I know I should use delegates, but haven't figured out who should which class should be the delegate.
Thanks in advance!
Neither .navigationController or .tabBarController will be available for a UIView or UIViewController that's been created but not pushed onto a stack
Either create a property on your View (or ViewController) class that is a UIViewController that is provided optionally after initialization or you could add a third argument to initWithNibName:bundle:
#interface CustomViewController : UIViewController
{
UIViewController *owner;
}
#property (nonatomic, assign) UIViewController* owner;
#end
Then in the owner ViewController:
CustomViewController *cvc = [[CustomViewController alloc] initWithNibNamed:nil bundle:nil];
cvc.owner = self;
It's too bad .parentViewController is read-only, this would be the sensible place for this.
You can get this using UIApplication class. Using this class you can find which viewController is placed at first. Here is the solution link for your problem.
Related
I have two UIViewController class, in first class I have a UIScrollView as a subview and I want to add this UIScrollView in another class as a subview .
You can add [view1 addSubView:view2];.if you added the UIScrollView on UIViewController add that controller view to other view on which you want to add.
I don't think this will work properly, once you added a UIView to one UIView I don't think it's proper to add it to another subview. You might need to explicitly call removeFromSuperview before adding it to another view. Ensure though that it's retained enough to be able to do that.
Make the UIScrollview as a property of viewController A .i.e by assigning it #property(nonatomic,retain) in the .h file of class A and synthesizing it in .m file of class A..
Further in class B create a instance of class A in B .h file eg: ViewController *VC1; and synthesize it in B's .m file
Now..in ViewController A when you are calling ViewController B (Typically when you are pushing)
Eg :
ViewControllerB *VC2 = [[ViewControllerB alloc]initWithNibName:#"ViewControllerB" bundle:nil];
VC2.VC1 = self;
[self navigationController pushViewCOntroller:VC2 animated:YES];
Now in Class B where you want the scrollView of Class A to be added ,
write the following in Class B
[ self.view addSubView:VC1.scrollView];
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.
I need to push a UIView into my UINavigation controller. I am doing it by
[self.view addSubview:showContactFlow];
And on a button click in UIView I need to push another UIViewController over the UIView. From the UIView I am not able to access self.navigationcontroller How can I do this?
Edit:
I have set the UIView as the view of a new UIViewController I am pushing into, the before mentioned UIViewController . Now I would like to know, how to handle the UIView button event inside its UIViewController, in which's view it is set.
Add a UINavigationController ivar to the UIView and assign it to the main view controller's. Then you should be able to access it from the UIView.
Edit:
Your UIView subclass:
// CustomView.h
#interface CustomView: UIView {
// ...
// your variables
// ...
UINavigationController *navController;
}
#property (nonatomic, assign) UINavigationController *navController; // assign, because this class is not the owner of the controller
// custom methods
#end
// CustomView.m
#implementation Customview
// synthesize other properties
#synthesize navController;
// implementation of custom methods
// don't release the navigation controller in the dealloc method, your class doesn't own it
#end
Then before the [self.view addSubview:showContactFlow]; line just add [showContactFlow setNavController:[self navigationController]]; and then you should be able to access your hierarchy's navigation controller from your UIView and use it to push other UIViewControllers.
You should try to work with an MVC approach. So your controller has access to all that stuff and can keep pushing and popping views, so the view doesn't need to know too much about the controller.
Otherwise, and for this case you can solve it fast by using delegation. So:
showContactFlow.delegate = self;
[self.view addSubview:showContactFlow];
So later in the UIView, you can just say:
[self.delegate addSubview:self];
This is gonna work, but it's not likely to be the best approach you should use.
On button click, you can present a view controller like,
-(void)buttonFunction{
ThirdVC *third= [[ThirdVC alloc]initWithNibNme];......
[self presentViewController:third animated:NO];
}
Using Core animation you can make NavigationController's pushviewController like animation on writing code in ThirdVC's viewWillAppear: method.
where do you add the UIButton is it in showContactFlow view or in the ViewController's view??
In regard to the modalViewControllers issue the correct method is
[self presentModalViewController:viewController animated:YES];
the standard animation in upwards
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 two NIB's
ParentViewController.xib
ChildViewController.xib
ParentViewController.xib contains a UIView and a UIViewController.
ChildViewController.xib contains a UIButton
I want ChildViewController.xib to load in the ParentViewController.xib's UIView
I have done the following:
Created #property for UIView in ParentViewController
Connected File's Owner to UIView in ParentViewController
Set UIViewController in ParentViewController's NIB Name property to ChildViewController in Interface Builder
Set ChildViewController view property to UIView in ParentViewController
I was hoping this would load ChildViewController into my UIView in ParentViewController but no luck.
I did get the following warning, which could be the culprit:
'View Controller (Child View)' has both its 'NIB Name' property set and its 'view' outlet connected. This configuration is not supported.
I also have added additional code in ParentViewController's viewDidLoad():
- (void)viewDidLoad {
[super viewDidLoad];
ChildViewController *childViewController = [[ChildViewController alloc]initWithNibName:#"ChildViewController" bundle:nil];
childViewController.view = self.myView;
}
Any thoughts on why ChildViewController does not load in the UIView of ParentViewController?
Try this
[self.myview addSubview: childViewController.view];
instead of
childViewController.view = self.myView;
The alternative is to build the "embedded" view (!) in a Nib, say ChildView.xib, then instantiate it in the ParentViewController.xib (change the class in the Identity inspector). There is no need to programmatically [self.view addSubview:embeddedView] in the parent view controller's -viewDidLoad method.
I wrote up how we embed custom-view Nibs inside other Nibs in a longish blog post. The crux is overriding -awakeAfterUsingCoder: in the ChildView class, replacing the object loaded from the "parent" Nib with the one loaded from the "child" Nib.
Note that our custom controls subclass UIView, not UIViewController (see Apple's docs on Custom view controllers: "You should not use multiple custom view controllers to manage different portions of the same view hierarchy.")