I’m study iOS development. Now playing with views. I don’t use interface builder at the moment, because I prefer to understand how all stuffs works under the hood. This is why I create my views UI elements etc programmatically. However.
Here is how my project looks like.
I have a class called RootViewController. I use that class as a window rootViewController.
Within that class I have a logic which load/unload views. Here is some code.
RootViewController.m
-(void)loadView
{
UIView *view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];
self.view = view;
self.view.backgroundColor = [UIColor lightGrayColor];
// create FirstViewController button
UIButton *firstViewButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
firstViewButton.frame = CGRectMake(20, 60, 280, 50);
firstViewButton.tag = 1;
[firstViewButton setTitle:@"Load First view" forState:UIControlStateNormal];
[firstViewButton addTarget:self
action:@selector(loadViewControlllers:)
forControlEvents:UIControlEventTouchUpInside];
// crate SecondViewController button
UIButton *secondViewButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
secondViewButton.frame = CGRectMake(20, 140, 280, 50);
secondViewButton.tag = 2;
[secondViewButton setTitle:@"Load Second view" forState:UIControlStateNormal];
[secondViewButton addTarget:self
action:@selector(loadViewControlllers:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:firstViewButton];
[self.view addSubview:secondViewButton];
[self.view release];
}
-(void)loadViewControlllers:(UIButton *)sender
{
if ([sender tag] == 1) {
if(firstViewController == nil) {
firstViewController = [[FirstViewController alloc]
initWithNibName:@"FirstViewController"
bundle:nil];
[self.view addSubview:firstViewController.view];
}
} else {
if(secondViewController == nil) {
secondViewController = [[SecondViewController alloc]
initWithNibName:@"SecondViewController"
bundle:nil];
[self.view addSubview:secondViewController.view];
}
}
}
The first and the second view controllers contain same code
-(void)loadView
{
UIView *view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];
self.view = view;
self.view.backgroundColor = [UIColor redColor];
UIButton *remove = [UIButton buttonWithType:UIButtonTypeRoundedRect];
remove.frame = CGRectMake(20, 60, 280, 50);
[remove setTitle:@"Remove First view from superview" forState:UIControlStateNormal];
[remove addTarget:self
action:@selector(removeFromView:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:remove];
[self.view release];
}
-(IBAction)removeFromView:(id)sender
{
[self.view removeFromSuperview];
}
So far, so good.
Here is where my questions begin.
1) Is this the correct approach to show/remove views. One controller (rootViewController in my case) to rule them all ?
2) Could you suggest me a way to pass data between first, second and root views ? Lets say a firstViewController is loaded. That controller contains textfield and a button. What I want is when a user type something in a textfield and a button is pressed the data in that textfield to be able to read by rootViewController and secondViewController
3) The applications works well. No crashes etc. The problem is that when neither of first or second controller are called once they can’t be loaded again.
When I press a button nothing is happens.
Last but not lest, sorry about my language.
It’s OK. However, if the firstViewController and the secondViewController share exactly the same logic, then they are actually one class, and it is generally safe for you to remove the redundancy.
You can use a singleton instance to hold the shared state(, the model in the MVC pattern), but it is not recommended.
IMHO, you can use an Observer model with Key-value-observing pattern. See Apple’s guide here. Or you can post NSNotification(s) from one controller to notify any other controllers that is interested in that type of notifications. See [guides here].2
In your code above, the subviews were only added when the controller ivars were nil. Try to fix that logic.