Inherit view from base view controller - iphone

In a project I'm working on, I have the need of a base UI. So i made a baseViewController, made the view in a xib-file and set the baseViewController's view to be the view in the xib-file.
Then I want to inherit that view from the xib-file to my other controllers, but it does not work. Is this impossible? Or have I just missed something?

Example:
//common
playagain = [[game alloc] initWithNibName:#"game" bundle:nil];
//depends on what you use
[[self view] addSubview: [playagain view]];
Use this in other controllers and make sure you import the controller in other controllers... The function is initWithNibName where your nibName goes in.

What I ended up doing was creating a container view controller with a nib, and then adding all other view controllers as child view controllers when it was needed, and removing them when I was done with them. See this tutorial: http://www.cocoanetics.com/2012/04/containing-viewcontrollers/

Related

Added UIViewController in UIView giving trouble

I want to add a UIViewController class to an existing class as a subview, so i used the following code.
myEventsView = [[EventNameViewController alloc]initWithNibName:#"EventNameViewController" bundle:nil];
[myEventsView.view setFrame:CGRectMake(0, 39, 320, 400)];
[self.view addSubview:myEventsView.view];
It is added successfully but the problem is with button actions, those actions which have to navigate to other view controllers are not working. Those action methods are called, but action not performed, not getting why so, please guide for the above.
Thanks in advance.
Try
myEventsView = [[EventNameViewController alloc]initWithNibName:#"EventNameViewController" bundle:nil];
[myEventsView.view setFrame:CGRectMake(0, 39, 320, 400)];
[myEventsView willMoveToParentViewController:self];
[self.view addSubview:myEventsView.view];
[self addChildViewController:myEventsView];
[myEventsView didMoveToParentViewController:self];
From the docs:
Each custom view controller object you create is responsible for managing all of the views in a single view hierarchy.
What you are trying to do is to add one viewcontroller's view as a subview of another viewcontroller's view, hence mixing two view hierarchies. That will cause you problems as you have already experienced. Have a look at Carbon Emitter's Abusing UIViewCtrollers article, it gives a thorough explanation and an alternative.
Update
As suggested in the correct answer above, there exists a way to make one UIViewController act as a container for another. From Implementing a Container View Controller (UIViewController Class Reference):
A custom UIViewController subclass can also act as a container view controller. A container view controller manages the presentation of content of other view controllers it owns, also known as its child view controllers. A child’s view can be presented as-is or in conjunction with views owned by the container view controller.
However, this is an iOS >= 5 feature, so my answer will remain correct for applications running iOS versions < 5.
Muncken is right. You cannot add myEventsView.view as a subview to self.view, since myEventsView.view is controlled by its own view controller.
What you probably wanted to do is to add just an new view (that is not controlled by another view controller) as a subview to self.view. So, why don't you just instantiate such a view without a new view controller?

iOS: confused about removeFromSuperview and switching views

New to iPhone development, but I've been given a big project as a first go and I'm a bit stuck.
Basically the app will start with a settings screen, then you click a button to go to a dashboard with multiple option buttons. Each button will lead to a different Navigation View with tables.
The way I've approached this is to start with a UIViewController with a button, which I've got wired up but when you hit the button and I do:
[self.view removeFromSuperview];
UIViewController *newView = [[UIViewController alloc] initWithNibName:#"Dashboard" bundle:nil];
[self.view addSubview:newView.view];
the second view isn't loading. I just get a blank screen. Do I need to make a reference in the first controller to the second?
Also, am I approaching this in the right way? As long as I removeFromSuperview will I be able to load the navigation controllers on the press of a button?
Sorry if this isn't too clear, I've been through books and lots of websites but don't seem to be able to get my head around this.
Thanks
There is nothing here with the new view, rather the problem is with current view. You have removed the self.view from super view.
[self.view removeFromSuperview];
So anything added to self.view will not be shown, as self.view itself is removed.
When presenting child controller/view from a parent controller, you should consider using presentViewController. Eventually, use dismissViewControllerAnimated when you want child to disappear and parent to reappear.
In parent view controller:
ChildViewController * child = [[ChildViewController alloc] init];
[self presentViewController:child animation:YES completion:Nil];
In child view controller, ie. in some action handler:
-(IBAction)close:(id)sender
{
[self dismissViewControllerAnimated:YES completion:Nil];
}
IMHO you should also get in the habit of naming instance variables to what they are instantiated from. In your example you name the instance newView, when it should be something like newViewController. That way you make sure you don't mix up views with view controllers.
[self.view removeFromSuperview];
You've removed the view from the superview
[self.view addSubview:newView.view];
But you're adding the new view to the same view that you have just removed from the superview. It's not displaying anywhere.
Your third line adds newView as a subview of self.view, but you just removed self.view from it's superview.
I'd suggest reading more about view controllers. You'll want to have one view controller per "screen", so one for your settings screen, one for your dashboard, one for each table, and so on. Then, manage which one is visible by pushing and popping these view controllers from the nav controller's stack.
This removes self.view, which will most likely destroy the object since there will be no other references to it:
[self.view removeFromSuperview];
Here you are creating an UIViewController, and adding it's view to self.view, which is probably not what you want:
UIViewController *newView = [[UIViewController alloc] initWithNibName:#"Dashboard" bundle:nil];
[self.view addSubview:newView.view];
Look into UINavigationController so that you can easily swap screens in and out with some built in animations. Here's a bit more about them. Here's a tutorial.
The UIViewController's view should not be removed from or added to a view hierarchy outside the control of the view controller. While you might be able to get that manipulation to work now it won't in the future.
Read up on view controllers here.
The basic idea is that you present the view controller then it will take care of manipulating the view hierarchy for you.
So a better approach to get started would be to do something like this;
[viewController1 presentModalViewController:viewController2 animated:YES];
This line of code will present viewController2 with the default modal animation (slide in from the bottom). If you'd like a different animation you can change the modalPresentationStyle to one of the constants in the UIModalPresentationStyle enum on viewController1 (note thats a viewController1, not viewController2).
If you want something more like the Clock app look into the tab bar controller. If you want something more like the Mail app look into the navigation controller.

Switching between 2 Views in 2 distinct View Controllers

I have a problem with transitioning between views in different ViewControllers.
Here is the situation:
My App is a TabBarApplication done with IB which contains a UIViewController for each Tab. The UIViewController (PlayerTabViewController) of the first tab contains another UIViewController (PlayerCreationViewController) to manage a view that will be added as subview.
I was able to add the subview using
[self.view addSubview:playerCreationViewController.view];
In the PlayerTabViewController.
The problem is that from the subview I have to return to the parent view and reload it because it contains a tableview that must be refreshed.
Using [self.view removeFromSuperview]; in the PlayerCreationViewController I can switch back to the parent view, but I'm not able to reload the tableview or do other actions.
I tried to implement the -(void)willRemoveSubview:(UIView *)subview method in PlayerTabViewController but it seems the function is never called.
Do you have an Idea of what am I doing wrong?
you are using wrong method to go on next view. just use navigation view controller to switch from one view to another view.
create a object of view
PlayerCreationViewController *playerViewController = [[PlayerCreationViewController alloc] initWithNibName:#"PlayerCreationViewController" bundle:nil];
[self.navigationController pushViewController:playerViewController animated:YES];
[playerViewController release];

superview and parentviewcontroller nil after adding a subview

I think I'm missing something fundamental and so I want to ask the community for some help. I'm building an app based around a basic iPhone Utility Application. My MainView and FlipsideView share some elements so I have created separate ViewControllers and nib files for those pieces. In order to do this I have done the following:
1. Created a viewcontroller called searchDateViewController which is the file's owner of searchDateView.xib
2. searchDateView.xib is basically a UIView with a UILabel inside, the view is wired up correctly
3. Inside both MainViewController.m and FlipsideViewController.m I add a subview as folllows:
- (void)loadView{
[super loadView];
searchDateViewController = [[SearchDateViewController alloc] initWithNibName:#"SearchDateView" bundle:nil];
[[searchDateViewController view] setFrame:[searchDateView frame]];
[[self view] addSubview:[searchDateViewController view]];
...
}
Everything displays and works just fine. Basically depending on actions that happen in each of the main and flipside views the UILabel of the nib is changed. However, I wanted to do something slightly different if the searchDateViewController is loaded from the MainView or the FlipsideView. However, I can't seem to figure out which ViewController is adding the searchDateViewController subview.
In searchDateViewController I tried:
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"superview %#", self.view.superview);
NSLog(#"parentviewcontroller %#", self.parentViewController);
}
In both cases I get nil.
So my question is - can I find out which ViewController is adding searchDateViewController a a subview? If so how? Or if my logic here is completely messed up, how should I be doing this?
Thanks!
viewDidLoad is invoked when the view controller has loaded its view. In your case, that happends in this line:
[[searchDateViewController view] setFrame:[searchDateView frame]];
At that moment, you haven't yet called addSubview: so it is no wonder the view's superview is nil.
To solve your problem, you should define a property inside SearchDateViewController to distinguish between the different cases. This property would then be set accordingly by the parent controller that creates the SearchDateViewController instance.
Generally, I do not think it is a good idea to use a UIViewController subclass as a controller for a view that is used as a subview of one or several fullscreen views rather than be used as a fullscreen view itself. Much of UIViewController's logic works on the assumption that it is used to manage a fullscreen view. For instance, with your design, I think it's possible that SearchDateViewController will modify the view's frame when the device orientation changes etc. Since you don't need all this functionality for a non-fullscreen subview, I suggest you subclass your SearchDateViewController directly from NSObject.
ViewController and views are completely separate.
In most cases, when you add a subview to a parent view you don't add its controller to the parent's viewController. The exception to this rule is the navigation controller which adds the controller instead of the view to maintain a hierarchy of view controllers.
Your SearchDate viewController can't find a parent controller because you never assigned one and the system does not do it automatically. You can just assign a parent controller when you evoke the view from another controller.
searchDateViewController.parentController=self;

adding multiple views to view controller inside a tab controller

I have a tabview controller to which I added a UIViewController to each tab. I want to have multiple UIViews inside the UIViewController.
So in the implementation of the UIViewController class I added [self.view addSubView:uiview1] and [self.view addSubView:uiview2]. The problem is that when I run the app, it crahes on load.
However, if I only used a single UIView and did: self.view = UIView1 that would work fine.
Does anyone know what is causing the problem? Or if I'm doing something fundamentally wrong?
Assuming you are doing this programmatically, you're supposed to create the view in the view controller's loadView method. So you must do this:
self.view = [[[UIView alloc] initWithFrame:someFrame] autorelease];
before you do this:
[self.view addSubview:uiview1];
[self.view addSubview:uiview2];
Otherwise, self.view would be nil.
There's no reason you can't have multiple views within your UIViewController's main view member variable. However, there are quite a few items left unanswered in your question:
How are you obtaining view1 and view2?
Are they outlets in your XIB file (are you using a XIB file, or creating everything in code), or are you creating them in code?
Where in your UIViewController subclass are you adding them to your view member variable?
What's the message printed to the console when it crashes?