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.
Related
I have a main navigationController controlled on the app's delegate and this navigationController contains a RootViewController.
Inside this view controller I have defined a UISegmentedControl that is assigned to the toolbar, using something like:
[self.navigationController.toolbar addSubview:segmentedControl];
this segmentedControl has 3 segments, each one pushing a viewController.
The problem now is this: I want to show a view that will contain an iAd or AdMob ad and this view must be always be visible independently of which segmented is pushed by the segmentedControl.
Is it possible to add a view that is somehow on front of the segmented control and is not affected by the controls it pushes on screen? thanks
Another option would be to not use a NavigationController - don't navigate - make the toolbar and the ad view space stable and swap out the contents.
That option would have a standard UIViewController with a UIToolbar at the top containing the segment control. Below that would be an addView and below that would be a content view where you could swap out views or layers based on the segment control selection.
That access pattern might not be appropriate for your app and data patterns but it does have the benefit of not navigating/pushing a completely new viewController.
From the UIView Programming Guide:
http://developer.apple.com/library/ios/#documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/CreatingViews/CreatingViews.html
... transitionFromView:toView:duration:options:completion: methods to
swap out entire sets of views for new ones.
http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIView_Class/UIView/UIView.html#//apple_ref/occ/clm/UIView/transitionFromView:toView:duration:options:completion:
I have a Custom TabViewController that adds subviews to the current view depending on what UITabBarItem is selected. For the different subviews I have simulated a Navigation Bar and a Tab Bar so that the sub views match the format when they are displayed. The one sub view, which contains a UILabel, displays fine however the sub view with the UITableView overlaps the UITabBar. However in the Interface Builder I have sized the UITableView to not cut off the UITabBar.
Adding the subview in the TabViewController
[self.view addSubview:subViewController.view];
You haven't provided enough information to be sure, but I think you are adding the table view to the wrong view. Assuming that self is your UITabBarController subclass, you are adding the custom view in the view that covers the entire screen, including the tab bar.
Instead, you should be adding the custom views to the selected view controller's view:
[self.selectedViewController.view addSubview:subViewController.view];
This will limit the stuff you are adding to the tab bar controller's content area, and won't overlap the tab bar.
I'm not sure what you are trying to accomplish with this approach, though: it seems like it would make more sense to add subViewController to the set of view controllers that the UITabBarController manages, rather than messing around with the view hierarchy.
Also, there is nothing inherently wrong with loading views from a nib and then manipulating them in code. "Mixing styles" is not a problem.
As Legolas stated, it seems like you are mixing styles here. Given that it sounds like you need to push it from the code, you could try full instantiation of the object from the code, for example:
UITableView *table = [[UITableView alloc] initWithFrame:CGRectMake(x, y, width, height)];
table.delegate = self; //or whatever the delegate is
table.dataSource = self; //or wherever the datasource is
...then add it to whatever view you need to.
If that all fails, double check your nib and make sure you have the proper options set for whether a tab bar is being shown, nav bar, etc, as that will effect the size.
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.
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.
Fundamentally, what I want to do is within, for example, ViewControllerA display ViewControllerB and ViewControllerC. How would I do that?
Thanks in advance.
You don't display view controllers, you display views. Having said that, you can do something like this:
UIViewController *a = ...;
UIViewController *b = ...;
[a.view addSubview:b.view];
Now, having said that, you shouldn't do it. Tons of stuff does not behave properly, because there are tons of undocumented interactions between UIView, UIWindow, and UIViewController. There is nothing in the documentation that says it won't work, but random things stop behaving properly (viewWillAppear: on the interior view's VC doesn't get called, etc).
If you need this functionality, you should file a bug with Apple.
The default template for a navigation view controller should do what you want assuming you want two different screens (not two different sections on the same screen). Whenever you want to change the view from the current one to another, just tell the navigation controller to push it on the stack:
[self.navigationController pushViewController:viewBoards animated:YES];
The default navigation view controller gives you a root view controller with a navigation view controller in it. It also gives you one view controller called MainWindow. Just add as many copies of MainWindow as you need to get your functionality.