Alright, this seems simple enough but I haven't found much documentation or posts regarding this. Basically, I want to have a completely custom tab bar at the bottom of my app. Being new to iPhone dev I thought I could do the following:
Place custom images on bottom of
screen to act as tab buttons.
Create a UIView (lets call it
"ContentView") to fill the rest of
the screen that will display the
appropriate tab's NIB. This
"ContentView" is inside the main
UIView for the NIB.
Hook up image "press" actions to the
controller managing all this.
I'm not sure how I would go about loading the appropriate NIB into the "ContentView" with this method though. From the "Touch Up" action method in the controller can I dynamically load a NIB into that "ContentView" UIView?
Something about this whole thing makes me uneasy.
Is there a better way?
To solve your problem I would create a nib with a UIView and its associated content in it. Connect the nib to a UIViewController. This will be the content of each tab. Create as many of these UIView-UIViewController combination as needed.
When the user touches a tab, create and load the UIViewController from the nib using
– initWithNibName:bundle:
Add the UIView in the nib to the main content view as a subview. Use
– addSubview:
As the user presses other tabs load the other nibs into memory and add their UIView into the main content view as a subview.
If a view is already in memory you can show and hide subviews with the following methods.
– bringSubviewToFront:
– sendSubviewToBack:
I think that would work.
You can solve this by,
either make different views with same tab bar image and custom button(load view on IBAction for button click:toucp up inside) or you can make different views for the same view(so you can hide views and show only one view at a time accordingly).
and you can load view (if you app is view based then add other views on window otherwise for navigation based app you need to pushViewController of navigation controller.
This is a tricky task but you need to handle this.
Related
I want to duplicate this controller same functionality without using it, this is because tab bar controllers are not customizable at all (fixed size, toggleable state tabs, etc...).
I want a customized "tab bar" that contains whichever view I want. And also I need to push view controllers leaving this customized tab bar fixed in its position.
I´ve seen lots off apps that do this, and I was wondering if using different UIWindow objects (one for the custom tab bar and other one for the content) was the best approach.
Any advice or guidance on this?
Thanks in advance.
Definitely not UIWindows - in an iPhone app there should only ever be one UIWindow.
I'd make a UIViewController subclass that had your new navigation bar ui at the top and a UIView underneath it. This view would be used to contain all the views of the controllers you are going to push in it. The view would have clipsToBounds set to YES to make sure your other controllers views don't overlap your navigation bar etc.
It would also have an array to hold the list of controllers that are currently inside it.
Your controller would implement the pushViewController:animated: methods etc to allow you to add other view controllers to the stack - you would add the new controller to your array and would add it's view as a subview of your controller's view.
However, it's actually quite a lot of work to make this well - a navigation controller will release child controller views on low memory warnings, handle rotation, animating on/off views etc. Are you 100% sure that this is what you want to do?
I've used a very simple approach. I subclass UITabbarController and during the init:
// Custom TabBar View
//
self.tabBar.hidden = YES;
MyTabBarView *myTabBarView = [[MyTabBarView alloc] initWithFrame:CGRectMake(0, 1024-44, 768, 44) // it'a an iPad app
configuration:configuration]; // an array of dictionary representing the view controllers
[self.view addSubview:myTabBarView];
[bottomBarView release];
then I load some view controllers with:
aViewController.hidesBottomBarWhenPushed = YES;
From MyTabBarView instance I perform on the UITabBarViewController:
setSelectedIndex:
In this way I've a customizable full screen application without pains.
I'm getting confused on view controllers and would love a straight example. Here's the preamble:
I have a UIViewController with a matching .xib.
By default IB gives me a single View in the Document window.
I can make it appear by telling my UIWindow to addSubview:controller.view and bringSubviewToFront:controller.view
Here's the questions:
Should I add another View to the ViewController in IB? Or is there a better, programmatical way?
How do I tell the ViewController to switch between the Views?
From the ViewController downward, what does the code look like to achieve this?
I'm trying things but just making a mess so I thought I'd stop and ask...
Note that every button, label, image, etc. in your main view controller is actually a view in itself, however I've interpreted your question to mean that you want to manage multiple full-screen views or "screens". Each screen should have its own view controller to manage it. So to get the terminology right, a view-controller is an object that manages a single full-screen view (or almost full screen if it's nested inside a navigation controller or tab bar controller for example) and a view is the big area managed by the view controller as well as all the sub-views (images, buttons, labels, etc.) within it (they are all UIView sub-classes). The view controller manages all of them on that screen, if you want another screen/page then you should create a new view controller to manage it.
The root view controller (the one you add to the window) can be a plain old normal view controller that you've designed in IB, however it's probably more useful if you use a navigation controller or a tab bar controller and add your designed view controller to that - then you can push additional view controllers as needed.
Another way (if you don't want navigation or tab-bar style) would be to transition to other view controllers directly in the main window using whatever transitions you like (or just replace the old one). We'll leave that for now though.
Any sub-views of your main view controller (the one you've designed in IB) will be automatically loaded from the nib file, but you can also add your own views programatically if you want (typically you would use one or the other, i.e. nibs or programatically, but you can mix and match if you want). To do it programatically, override loadView in the view controller and then call [super loadView]; then do [self.view addSubView:myOtherView]; (create the myOtherView first of course). Note that the first time .view is accessed on your view controller, it actually calls loadView to create the view, so inside loadView it's important to call [super loadView]; before trying to access self.view :D
To switch between views, using the navigation or tab bar controllers makes it very easy. So put your main view controller inside (for example) a navigation controller and put the navigation controller in the window, so you've got window->navigationController->myController. Then from an action method in your view controller (you can hook up the action methods in IB), for example when an "about" button is pressed do this:
- (void)doAbout
{
// Create the about view controller
AboutViewController* aboutVC = [AboutViewController new];
// Push the view controller onto the navigation stack
[self.navigationController pushViewController:aboutVC animated:YES];
[aboutVC release];
}
Note that the about view controller is created programatically here - if your about view is designed in IB then instead use initWithNibName:bundle: to create it.
And that's how you manage multiple screens.
I'm working on an iPhone app where I'm using a navigation controller (UINavigationController) to navigate through the various child views, and I would like to add a uiview to either the main window or the navigation controller, as a footer overlay that shows up on top of all the child views. I've tried this through interface builder, and programmatically, but nothing seems to work.
Working in interface builder, I've tried adding the footer to the bottom of the main window, and decreasing the height of the child views so the footer would show up, but the children seem to resize to fill the whole window. I've tried playing with some of the options, like 'wants full screen', 'resize view from NIB', tried to resize the navigation controller and couldn't. Same problem when I try to add it programmatically instead.
I can add a toolbar to the navigation controller in interface builder, is there a way to add a UIView instead? Or even attach a UIView to a toolbar? I'm sure there's a simple way to do what I'm trying, I'm hoping someone out there has had a similar experience.
Thanks!
If you want to have a toolbar sized custom view you can just position it where the toolbar would be and add it to the window as a subview above your navigation controller. Then you don't have to worry about autoresizing ruining your fun, you'll just always be drawing your view over the navController's toolbar.
[myWindow insertSubview:newView aboveSubview:myNavController.view]
Just make sure you adjust the size of your view if you want to respond to device rotations, as the toolbar size changes then.
You may also have success creating a view hierarchy that looks like this:
UIWindow
Subview 1: Custom view which holds app content
Subview 1a: UINavigationController with your main view as its root view
Subview 2: Custom view which holds your footer content
Subview 2a...2z: whatever views you need inside your footer
That way you can make your footer whatever height you want. Just set the appropriate autoresizingMask properties on your window's two subviews so that you can ensure proper positioning as well as respond to interface orientation changes automatically.
I have a view (and corresponding view controller) in my iPhone app that allows the user to edit settings for the application. This view is accessible via a menu (a table view). I use pushViewController in my UIViewController subclass to get it shown. When I do this, it appears as I expect - the nav bar appears on top of the xib, and the empty space I left up there in the xib is occupied.
I also sometimes show that settings view as a modal view using presentModalViewController. When I do this, the top of the xib starts at the bottom of the nav bar instead of underneath it.
The documentation does say that presentModalViewController will resize the view to fit, so I could see this being expected behavior. However, for me, it isn't desired behavior.
I can kind of work around it by setting the settings view controller to not show the nav bar, but then there's a weird empty space at the top of the view.
Ideally, I'd like to use the same xib in both of these situations. However, maybe that's not a best practice? How do you guys usually reuse a xib?
I was thinking that maybe I could have the view controller shift all of the controllers up if it's in modal mode, but I'd like something better, if it's available.
Each UIView has an autoresizingMask property. By configuring that (can be done in Interface Builder), you should be able to reuse the view and have it automatically resize to take up the whole screen when the nav bar should not be there.
Apple's documentation is here:
http://developer.apple.com/iPhone/library/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/WindowsandViews/WindowsandViews.html#//apple_ref/doc/uid/TP40007072-CH8-SW10
I have created an iPhone application based on an OpenGL view. Now I
would like to show a "settings" form. Since my code runs in UIView, I have no pushViewController. How do I show a view controller on screen?
Thanks!
You can do this in one of two ways:
You can create a new view hierarchy, and then add it as a subview of your UIWindow when you want to show preferences. When you're done with your prefs, you can animate it out and then remove it as a subview.
You can switch to a UINavigationController/UIVIewController based hierarchy, and hook your current OpenGL/UIView to a UIViewController's view outlet. Then you can use all the regular UINavigationController based navigation stuff.