Dealing with views and some other things - iphone

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.

1) Is this the correct approach to show/remove views. One controller
(rootViewController in my case) to rule them all ?
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.
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
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
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.
In your code above, the subviews were only added when the controller ivars were nil. Try to fix that logic.

Related

Show a subview when button is pressed. (Something like view which appears when operating system Windows "start" button is pressed

I want to show a subview that will contain list of menu when a UIbutton is pressed. Should I use vertical SegmentControl?
Thanks for any help in advance
You don't have to use vertical TabbarViewController.
First of all, go to the interface builder and drag a Button, connect the Button to an action method you declare in the .m file
let's said that the method is
- (IBAction) btnHandler :(id)sender {
}
then declare a new view and add it to your main view
so the btnhandler method will look like this
- (IBAction) btnHandler :(id)sender {
UIView *subview = [[UIView alloc] initWithFrame:CGRectMake(0, 50, 320, 300)];
//here add what ever you want to the new created view using the
//[subview addSubview:(your Componant)];
[self.view addSubview:subview];
}
please forgive me if i made a mistake, this is not tested code. i write it now in the browser.
If its an iPad application, maybe consider calling a UIPopOverController
You could use an Action Sheet if you're aiming for a native iOS look and feel.
Agree with the previous answer that a pop over is a great option if this is an iPad app.
You could go full custom of course with your own viewController which you can animate in from the top or bottom depending on your need.
Option 1:
Design the view in your nib.
Option 2:
Have a separate view controller
You can use addSubView method to add the view when you press the UIButton
Try below code that will help you.
- (void)viewDidLoad {
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
[button setTitle:#"Show View" forState:UIControlStateNormal];
button.frame = CGRectMake(80.0, 210.0, 160.0, 40.0);
[self.view addSubview:button];
[super viewDidLoad];
}
-(IBAction)buttonPressed:(id)sender
{
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(10, 200, 300, 100)];
view.backgroundColor = [UIColor clearColor];
view.backgroundColor = [UIColor grayColor];
[self.view addSubview:view];
}

Best Practice to Float a View over Another View?

I have a 320x460 view with a number of buttons, depending on the button pressed, a 280x280 view pops up over the 320x460 view (similar to the behavior of the UIAlertView) using code like this:
UIView *overlayView = [[UIView alloc] initWithFrame:CGRectMake(20, 200, 280, 280)];
overlayView.backgroundColor = [UIColor whiteColor];
[overlayView autorelease];
[overlayView addSubview:label]; // label declared elsewhere
[overlayView addSubview:backgroundImage]; // backgroundImage declared elsewhere
//... Add a bunch of other controls
[label release];
[backgroundImage release];
//... Release a bunch of other controls
[self.view addSubview:overlayView];
Everything works fine displaying the overlayView and all its controls.
The question I have is, how do I get rid of the overlayView once it's displayed? I want to make it not only not visible but to remove it completely, since the user will be popping up the overlayView repeatedly during use.
You need access to overlayView to remove it, I'd suggest adding this to the create side:
overlayView.tag = 5; // Or some other non-zero number
Then later you can use it like this:
-(void)removeOverlayView
{
UIView *overlayView = [self.view viewWithTag:5];
[overlayView removeFromSuperview];
}

to display one view in another view by clicking button

hi guys i am new to iphone apps development please help me to show another view from one view using buttons
Thats a very vague question... here is a start - you can look up some of the syntax and research a bit:
this in viewDidLoad:
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button setTitle:#"Click" forState:UIControlStateNormal];
[button addTarget:self action:#selector(showView) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
[button release];
then this method
- (void)showView {
UIView *view = [[UIView alloc] initWithFrame:CGRect(0,0,320,460)];
[self.view addSubview:view];
[view release];
}
if you want to push a view controller then you need to look up navigation controllers and the method pushViewController:animated:
This is the common code u can use to go on next view or go on back, Just change button name which u want to press and the view name on which u want to go. For example on back button press u want to go on library view then write this code -
-(IBAction)backButtonPressed:(id) sender
{
libraryView *libraryview=[[libraryView alloc] initWithNibName:nil bundle:nil];
libraryview.modalTransitionStyle=UIModalTransitionStyleCoverVertical;
[self presentModalViewController:libraryview animated:YES];
[libraryview release];
}
Let me know whether ur problem is solved or not.

UIButton and UIPicker

Is there any reason adding a UIPicker to a view might somehow rob a programatically created button of its functionality? I initially instantiated a UIButton to take me to a different view, and all was well and fine. Then I went ahead and added a UIPicker to the same view with the purpose of selecting a few key fields which could then be passed on to the view the UIButton led to. Unfortunately it seems I somehow broke my button in the process of adding the picker.
Here's the instantiation of the button:
switchToGame = [UIButton buttonWithType:UIButtonTypeRoundedRect];
switchToGame.frame = CGRectMake(140,250,100,100);
[switchToGame setTitle:#"Play God" forState:UIControlStateNormal];
[switchToGame setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[switchToGame addTarget:self action:#selector(playGame) forControlEvents:UIControlEventTouchUpInside];
[self.view insertSubview:switchToGame atIndex:0];
The method playGame checks the fields of the picker, sends them to a shared singleton object then loads the game view as such:
Singleton *mySingleton = [Singleton sharedSingleton];
NSInteger numCellsRow = [theDataPicker selectedRowInComponent:0];
NSInteger aliveColorRow = [theDataPicker selectedRowInComponent:1];
NSInteger deadColorRow = [theDataPicker selectedRowInComponent:2];
UIColor * theAliveColor = [aliveColors objectAtIndex:aliveColorRow];
UIColor * theDeadColor = [deadColors objectAtIndex:deadColorRow];
NSInteger numCellsPerRow = [[cellRowOptions objectAtIndex:numCellsRow] intValue];
mySingleton.cellsPerRow = numCellsPerRow;
mySingleton.aliveColor = theAliveColor;
mySingleton.deadColor = theDeadColor;
[theAliveColor release];
[theDeadColor release];
GameController * viewController = [GameController alloc];
self.theViewController = viewController;
[self.view insertSubview:theViewController.view atIndex:1];
[viewController release];
I hope these stretches of code are enough for someone to point out where I went astray, as I am quite lost at the moment.
Out of curiosity what happens if you replace:
[self.view insertSubview:switchToGame atIndex:0];
with
[self.view insertSubview:switchToGame atIndex:1];
and
[self.view insertSubview:theViewController.view atIndex:1];
with
[self.view insertSubview:theViewController.view atIndex:0];
Hopefully this might order your views correctly so that the button is on top. Also look here for a great link on addSubview versus insertSubview:
Difference between addSubview and insertSubview in UIView class

Objective-C: addTarget:action:forControlEvent for subview button

I'm doing an iPhone ap which contains a viewController class (PhotoListViewController). This viewController's view has a subview which contains a button attached as a subview. I'm trying to use the addTarget:action:forControlEvent method to call an instance method of the PhotoListViewController class in order to perform an action when the button is pressed but the method is not being called. Any thoughts on how to make this work?
Here's the pertinent code. I know your first though will be why am I nesting subviews, but this just a distilled version of my program - there are reasons I'm doing the nesting. I know there are probably other ways of setting up the program so I don't have to do this nesting, but my real question is - why does this not work?
/Code/
#implementation PhotoListViewController
- (void)loadView {
[super viewDidLoad];
//load elements into the viewController
//first create the frame
CGRect frameParent = CGRectMake(0, 0, 0, 0);
UIView *viewPerson = [[UIView alloc] initWithFrame:frameParent];
CGRect frameChild = CGRectMake(0, 20, 0, 0);
UIView *newView = [[UIView alloc] initWithFrame:frameChild];
UIButton *btnShow = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btnShow.frame = CGRectMake(230, 120, 80, 30);
[btnShow setTitle:#"View!" forState:UIControlStateNormal ];
[btnShow addTarget:self
action:#selector(viewPhoto_click:)
forControlEvents:UIControlEventTouchUpInside];
[newView addSubview:btnShow];
[viewPerson addSubview:newView];
[newView release];
[self setView:viewPerson];
[viewPerson release];
}
- (void)viewPhoto_click:(UIButton*)sender {
NSLog(#"HI");
}
It may not be related, but both viewPerson and newView have a width and height of 0. You may want to give these views a non-null size (the 3rd and 4th arguments of CGRectMake).
action:#selector(viewPhoto_click:)
forControlEvents:UIControlEventTouchUpInside];
May be a copy paste typo but have you tried to remove the : after the viewPhoto_click after the selector?
Also. In most examples the event Handler look like this.
- (void) viewPhoto_click: (id)sender
Not sure if it makes any difference though