Adding a subview without a XIB - cocoa-touch

This may seem painfully simple, but I'm just starting out so bear with me...
I have a main view with a toolbar. When the user presses a button in the toolbar, I would like a small prompt to appear at the top of the screen. I added a UIView within the existing UIView, and set it to be hidden. I connected that to an ivar called 'searchView' in my view controller, and tried the following:
searchView.hidden = NO;
When that didn't work I tried adding...
[self.view addSubview:self.searchView];
...which didn't work either.
Do I need to set the index somehow to bring it above the main view?
Is this approach just altogether wrong?

If you created the UIView from the interface builder, forget to use addSubview because interface builder it's doing this automatically.
To do that in graphical mode (IB), follow this steps:
Define an IBOutlet in your file "h" should be something like:
IBOutlet UIView * myHiddenView;
Then in IB, connect the IBOutlet that you have defined in the h file to the UIView that you have created graphically in the IB and give the hidden property to this UIView (checkbox).
Then in your button press method do this:
myHiddenView.hidden = NO;
If you prefer do it programmatically to copy this example code:
define in the interface of the .h file
UIView *myHiddenView;
after the interface in the .h file:
-(void)displayView:(id)sender;
then in the .m file:
-(void)viewDidLoad{
myHiddenView = [[UIView alloc] initWithFrame: CGRectMake (x, y, width, height)];
myHiddenView.hidden = YES;
[self.view addSubview: myHiddenView]
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(x, y, width, height)];
[button setTitle:#"button" forState:(UIControlState)normal];
[button addTarget: self action: #selector(displayView:) forControlEvents: UIControlEventTouchUpInside];
[self.view addSubview:button];
}
-(void)displayView:(id)sender{
myHiddenView.hidden = NO;
}

Related

add UIView as a subview in UITableViewController (or sliding up menu)

I am trying to add a subview in my UITableViewController. What I want to is when a user click a Navigation Bar Item, a small window or a subview will show which contains two buttons. When users click any button, the subview will disappear. I even have no success to add a subview in my TableViewController. I added following codes in ViewDidLoad:
UIView* simpleView = [[UIView alloc] initWithFrame:CGRectMake(0,200,300,100)];
UIButton* add= [[UIButton alloc] initWithFrame:CGRectMake(0,240,300,100)];
add.titleLabel.text=#"here";
[simpleView addSubview:add];
[self.tableView addSubview:simpleView];
which did not work, the error is
"setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key viewReference.'"
I change to [self.view addSubview:simpleView]; ,which still did not work
Can some one tell me how to add a subview in a UITableViewController and provide some sample code?
Thanks
Your button frame rect is incorrect so your simpleView is fully transparent. Change
UIButton* add= [[UIButton alloc] initWithFrame:CGRectMake(0,240,300,100)];
to
UIButton* add= [[UIButton alloc] initWithFrame:CGRectMake(0, 40,300,100)];

Multiple Views in Xcode 4.2

I'm having a lot of trouble finding a tutorial for implementing multiple views in Xcode 4.2 without storyboard, this is for a class so I can't use storyboard yet. I'm just trying to have a 2nd view with a UIPicker come up when a button is clicked in the main view, I just can't find one for this version of Xcode and it's different enough from the older versions to confuse me.
Any help appreciated if someone can give me a quick description of what I need to do this or a newer tutorial I'd appreciate it :)
I think you should read the UIView Programming Guide to get a good handle on how UIViews work exactly. I find nibs/storyboard are really great at confusing new iOS developers.
In essence, a UIViewController has 1 view which you set in the viewDidLoad or loadView method by using the [self setView:someUIView]. You add more stuff to the screen by adding UIViews as a subview of the viewcontroller's "Main" view. For example
-(void)loadView {
// Create a view for you view controller
UIView *mainView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self setView:mainView];
// Now we have a view taking up the whole screen and we can add stuff to it
// Let's try a button, a UIButton is a subview of UIView
UIButton *newButton = [[UIButton buttonWithType:UIButtonTypeRoundedRect];
// We need to set a frame for any view we add so that we specify where it should
// be located and how big it should be!
[newButton setFrame:CGRectMake(x,y,width,height)];
// Now let's add it to our view controller's view
[self.view addSubview:newButton];
// You can do the same with any UIView subclasses you make!
MyView *myView = [[MyView alloc] init];
[myView setFrame:CGRectMake(x,y,width,height)];
[self.view addSubview:myView];
}
Now here we have our viewController who'se view is just a plain UIView which in turn has 2 subviews; newButton and myView. Since we created the MyView class, maybe it contains subviews as well! Let's take a look at what a UIView subclass could look like:
// Here is the init method for our UIView subclass
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Let's add a button to our view
UIButton *newButton2 = [[UIButton buttonWithType:UIButtonTypeRoundedRect];
// Of course, the frame is in reference to this view
[newButton2 setFrame:CGRectMake(x,y,width,height)];
// We add just using self NOT self.view because here, we are the view!
[self addSubview:newButton2];
}
return self;
}
So in this example we would have a view controller who'se view now contains 2 button! But the view structure is a tree:
mainView
/ \
newButton myView
\
newButton2
Let me know if you have any other questions!
Matt

Linking storyboards elements to code

On one of the scenes in my storyboard, i placed a button. It shows on the view fine.
The view itself is represented by class GameView, which contains both
IBOutlet UIButton *b;
#property (strong) IBOutlet UIButton *b;
I have connected the outlet to button from the storyboard's view.
From .m file of the GameView class, i:
[[self b] setFrame:CGRectMake(420, 260, 50, 30)];
[b setTitle:#"!!!" forState:UIControlStateNormal];
[self addSubview:[self b]];
When button is created programmatically, the following works fine
deal = [UIButton buttonWithType:UIButtonTypeRoundedRect] ;
[deal setFrame:CGRectMake(420,170, 50, 30)];
[deal setTitle:#"Deal" forState:UIControlStateNormal];
[self addSubview:[self deal]];
When program runs, however, the button from the storyboard is not seen. Why?
I am an epic newb. Posting the answer in hopes someone else might find it useful.
Basically, in my case, the view is created programmatically from the controller, whatever is seen on the screen of a storyboard is effectively replaced on object creation.
UIView *gameView = [[GameView alloc] initWithFrame:CGRectMake(0, 0, 480, 300)];
[[self view] addSubview:gameView];
Once i put IBOutlets into the Controller and added
[bb setFrame:CGRectMake(420, 260, 50, 30)];
[bb setTitle:#"---" forState:UIControlStateNormal];
[gameView addSubview:[self bb]];
It worked like a charm.

Resizing UINavigationController?

I want my navigationcontroller to only take half of the screen. Is this possible? In IB, when I drag, it forces me to fill up my entire screen, I can't resize it. If it's not possible, is there an alternative?
Thanks.
You can but you can only do it within iOS 5 because when I tried to do any type of direct view manipulation within a UINavigation controller than pushed or popped another view controller. The navigation controller would not display them.
Here's what you need to do.
-(void)viewDidLoad {
UINavigationController * navController = [[UINavigationController alloc] initWithRootViewController:[[UIViewController alloc] initWithNibName:nil bundle:nil]];
//Used to recieve callbacks (like shouldAutorotateToInterfaceOrientation:)
[self addChildViewController:navController];
//View manipulation
navController.view.frame = CGRectInset(navController.view.frame, 20, 20);
[self.view addSubview:navController.view];
//Calls all the standard methods (viewDidLoad,viewDidUnload,etc.)
[navController didMoveToParentViewController:self];
}
Also if your a registered developer there is a really good video on view controller containers, that might be helpful to you, from last years WWDC.
Based off what you have written I am assuming you have a #property in your header file. Something like:
#property (nonatomic, strong) IBOutlet UINavigationController *navController;
Then have this IBOutlet connected to your navigationController in your xib file. In that same xib file have a view that is connected to the file owner. Set this view's dimensions in interface builder so in your case to fill only half the screen. Then you will add the navController as this view's subview. If you also have a viewController already added in the xib file in the navController then in viewDidLoad do:
-(void)viewDidLoad {
[self addChildViewController:self.navController];
[self.view addSubview:self.navController.view];
[self.navController didMoveToParentViewController:self];
}
Otherwise if you are programmatically setting the rootviewcontroller do:
-(void)viewDidLoad {
self.navController = [[UINavigationController alloc] initWithRootViewController:yourViewController];
[self addChildViewController:self.navController];
[self.view addSubview:self.navController.view];
[self.navController didMoveToParentViewController:self];
}
You have to add self.navController as a childViewController so that it will take on the dimensions of the view it is being added into. Adding it as a subview is not enough to make the view resize. Hope this helps!

UIImageView subclass not passing touches to controller subviews

When I add a UIImageView subclass (fullscreen) behind a couple of UIButton subclass instances, those buttons stop receiving the touches and don't function anymore. Nothing I have tried has worked to restore their connectivity to user touches.
I have tried:
a) Using a UIImageView subclass for the front view (that receives the touches) and making sure setUserInteractionEnabled is YES. Result: UIButtons are not responding when the UIView is present.
b) Explicitly passing the touches from the front view to the view controller in hopes that it will do the right thing. Result: UIButtons are not responding to the touches.
c) Calling the touchesBegan, touchesMoved and touchesEnded methods directly on the button I want to interact with when any touch on the front UIView is received. Result: Strikingly, the buttons don't respond even when I am cramming the touch events down their throat.
d) Passing the touches from the front view to the UIViewController, and iterating over all subviews handing out the touches manually. I included a touchesBegan method showing how I tried to do this. When executed the loop is infinite, it never progresses past the first view (is of type FrameUIView).
I know this problem is likely the result of my lack of understanding of proper view hierarchy or the responder chain.
if I comment the last view created after the button, then the buttons work fine. Is there something special about UIButtons in this respect?
Here is the code.
I have a UIViewController subclass, in it:
- (void)loadView {
mainAppView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.view = mainAppView;
frameImageView = [[FrameUIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
frameImageView.image = [UIImage imageNamed:[[[ThemeController sharedInstance] currentTheme] frameImageFilename]];
[frameImageView setUserInteractionEnabled:YES];
[mainAppView addSubview:frameImageView];
zoomInButton = [[CustomUIButton alloc] initWithFrame:CGRectMake(controlsOriginX + zoomWidth + lightWidth, controlsOriginY, zoomWidth, controlsHeight)];
[zoomInButton setTitle:#"+" forState:UIControlStateNormal];
[[zoomInButton titleLabel] setFont:[UIFont systemFontOfSize:28]];
[zoomInButton addTarget:self action:#selector(doMyAction) forControlEvents:UIControlEventTouchDown];
[zoomInButton addTarget:self action:#selector(cancelMyAction) forControlEvents:UIControlEventTouchUpInside];
[mainAppView addSubview:zoomInButton];
FrameFrontUIView *frameFrontImageView = [[FrameFrontUIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
frameFrontImageView.image = [UIImage imageNamed:[[[ThemeController sharedInstance] currentTheme] frameFrontImageFilename]];
[frameFrontImageView setUserInteractionEnabled:YES];
[mainAppView addSubview:frameFrontImageView];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
for (UIView *view in self.view.subviews) {
NSLog(#"view is a %#", [view description]);
[view touchesBegan:touches withEvent:event];
}
}
Anyone with a tip on how to do this wins the internets and a cookie. Also accepting revolvers for russian roulette mayhem. Thank you.
Have you tried using the buttons without the image view behind them? Subclassing UIButton is not advisable. The way to instantiate UIButtons is with factory methods:
UIButton* myButton = [UIButton buttonWithType:UIButtonTypeCustom];
So my guess is that the CustomUIButton instances you have created are not properly set up.
This question is old, but I just ran into the same problem.
The solution I used is to create a container UIView, then add the UIImageView as a subview, then add the buttons, text boxes, etc. over that. Seems to work well.
I don't really understand why this is an issue with using a UIImageView as the superview for buttons.