Accessing UITabBarController's content view - iphone

Is there a way to access the content view (shown as Custom content on the diagram) in order to change its frame?

Access to selected view controller's view in tab bar
UIView *view = tabBarController.selectedViewController.view;
Access to second view controller's view in tab bar
UIView *view2 = [(UIViewController*)[tabBarController.viewControllers objectAtIndex:1] view];

Related

How to place a view behind navigation bar while the navigation bar is the superview view?

I have a UITableView and a small custom view. I want the custom to stay below the navigation bar, but above the tableview. So when the custom view moves up and down, it looks like that the custom view pops out from navigation bar's back.
At first I make the custom view the subview of the tableview and everything seems fine. But when the tableview is scrolled, the position of the custom view is also changed, which is not what i want.
Then i made the navigation bar the superview, but now the custom view stays above the navigation bar. And i don't know how to change the z-order between parent view and subview.
So can anybody give me some advice?
Thank you!
Depending on how you create your view hierarchy - insert it either above the table view or bellow navigation bar:
- (void)viewDidLoad
[super viewDidLoad];
// let's assume self.tableView is table view
// and self.navigationBar is navigation bar
// that both are subviews of [self view]
UIView *customSubview = [[UIView alloc] initWithFrame:someRect];
[[self view] insertSubview:customSubview aboveSubview:[self tableView]];
// -- OR --
[[self view] insertSubview:customSubview belowSubview:[self navigationBar]];
}
There's also an option to insert your subview at certain index. So if your navigation bar is topmost (i.e. at index 0) and table view is bottommost (i.e. index of [[[[self view] subviews] count] - 1]) you can insert your custom view in-between like this:
[[self view] insertSubview:customSubview atIndex:1];
This way your table view will descend by one level in its superview and "layering" of subviews will be following:
Index 0 - navigation bar
Index 1 - custom subview
Index 2 - table view
Beware though that putting your custom subview into standard superview you'd have to maintain the position yourself as it won't be scrolling together with the tableview as before.

View outside screen

I have a tab controller, which contains a navigation controller which again contains a view controller. The view controller shows a tab bar and a navigation bar.
In this view controller I want to add a full screen view (hides the tab bar and the navigation bar but leaves the status bar) which is shown during loading. I have subclassed UIView and set up a layout in a nib file which is loaded to this view:
- (id)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame])
{
// Load nib
self = [[[NSBundle mainBundle] loadNibNamed:#"FrontpageCountdownView" owner:self options:nil] objectAtIndex:0];
}
}
I add this view in the view controller like this:
// Hide tab bar and navigation bar
self.tabBarController.tabBar.hidden = YES;
self.navigationController.navigationBar.hidden = YES;
// Add loading (frontpage countdown) view
CGRect frame = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height);
NFFrontpageCountdownView *countdownView = [[NFFrontpageCountdownView alloc] initWithFrame:frame];
[self.view addSubview:countdownView];
The view in my nib has a size of 460 (full screen, minus the status bar). My problem is, that when I add it to the view controller it appears "bigger".
I would think that since the view has a size of 460 it should show the entire view when it is added to the view controller but it doesn't show the bottom. It seems that the view is too big even though it is 460 pixels.
Can anybody tell me why this is?
EDIT
How my view looks in Interface Builder:
How my view looks in the simulator:
This happens when hiding the tab bar using self.tabBarController.tabBar.hidden = YES.
Instead, you should hide it and then extend the view of the tabBarController.
CGRect tabBarFrame = self.tabBarController.view.frame;
tabBarFrame.size.height += self.tabBarController.tabBar.frame.size.height;
self.tabBarController.view.frame = tabBarFrame;
self.tabBarController.tabBar.hidden = YES;

xib-specified location moves on UIView load?

I have a couple of view controllers that I want all to share a header status bar. This header view shows status of certain things in my app. I used IB to lay out the contents of the header view in its own xib, then also used IB to layout the view controllers, adding a placeholder UIView element in the view controller's xibs for when I load in the header programmatically.
Now, when I create a UIView subclass from the contents of the view xib, and add that as a subview to the view of any of my view controllers, the location that I specified for the header view in my view controller xib seems to get ignored, and the header view gets placed at (0,0) no matter what. All the contents of the header view load and appear fine, it's just the location of the header view in the view controller that is wrong.
Here's how I'm loading and adding my header view to my view controller:
header = [InfoHeader loadFromNib:MY_NIB_NAME withOwner:self];
[self.view addSubview:header];
The view controller xib is confirmed to have an outlet connected to the 'header' variable. And here's that 'loadFromNib' method:
+(InfoHeader *) loadFromNib: (NSString *) nibName withOwner:(id) objectOwner
{
NSBundle *b = [NSBundle mainBundle];
NSArray *nib = [b loadNibNamed:nibName owner:objectOwner options:nil];
InfoHeader *header;
for (id obj in nib)
{
if ([obj isKindOfClass:[InfoHeader class]])
{
header = (InfoHeader *) obj;
}
}
return header;
}
Any ideas on what to check here? I'd rather not locate the header bar programmatically, but let IB do it.
Did you change the location of your subview in IB? Usually, the default location (0, 0) of the view will be the (top, left) coordinate of the big view in the screen. I think checking that will work fine
You can do this without using a "placeholder" view at all, by programmatically specifying the frame of the subview:
InfoHeader *header = [InfoHeader loadFromNib:MY_NIB_NAME withOwner:self];
header.frame = CGRectMake(0, 44, header.frame.size.width, header.frame.size.height);
[self.view addSubview:header];
(that code asssumes that you have removed the header outlet from your class, so it can be a local variable instead).
Or, if you'd rather use the placeholder (so you can specify the header's position using IB instead of programmatically), do it like this:
InfoHeader *headerView = [InfoHeader loadFromNib:MY_NIB_NAME withOwner:self];
[header addSubview:headerView];

How do I change the UIView programmatically?

I have created View A and View B. My window has View A displayed on the screen. I also have a UIButton on View A. I want to switch from View A to View B when I click on the Button. I am not using any UIViewController. Is it possible to switch the views without using controller?
I am calling buttonAction method on TOUCHUPINSIDE
The problem is that it doesn't do anything when I say
[ViewA removeFromSuperView];
What should I do now?
If viewB is not in the view hierarchy:
[[viewA superview] addSubview:viewB];
If viewB is in the view hierarchy:
[[viewA superview] bringSubviewToFront:viewB];
Once viewB is in the view hierarchy, then remove viewA:
[viewA removeFromSuperview];

iPhone - tabbar + view issue

I am using a UITabBar control from library in one of my view (note that I am not using UITabBarController but the UITabBar control).
Now, I am adding two tabBar items to this tabBar.
I have created controller class for this view (.m and .h) files and used delegates in the .h file.
In the .m file I have used the following function:
(void)tabBar:(UITabBar *)TabBarControl didSelectItem:(UITabBarItem *)FirstView
I have assigned tag = 0 and tag = 1 to respective tabBar items.
What I want to do is that, on click of first tabBar item I want to show a view and click of another tabBar item, I want to show another view.
So, in the above function I am checking that if the tag of clicked tabBar item is 0 than I will show one view else I will show another view.
I am showing the view as following:
Team1Scoreboard *tempTeam1Scoreboard = [Team1Scoreboard alloc];
tempTeam1Scoreboard = [tempTeam1Scoreboard initWithNibName:#"UserTeamScoreboard" bundle:[NSBundle mainBundle]];
self.cntrlTeam1Scoreboard = tempTeam1Scoreboard;
[tempTeam1Scoreboard release];
UIView *theWindow = [self.view superview];
[self.view removeFromSuperview];
[theWindow addSubview:self.cntrlTeam1Scoreboard.view];
Now the problem is that, when I click on any of the tabBar item, it will load the correct view but the tabBar itself will be disappeared as I am adding the view to window itself.
Please help me so that I can load correct view and also my tabBar itself is visible.
The TabBar is disappearing because it's a child of the view which you are then adding a new child to and the new child is sized the same as the parent. Did that make sense? Ok, look at it this way:
You have ViewA and ViewA has a couple of labels and a TabBar. ViewA is managed by ViewControllerA. In ViewControllerA you are creating an instance of ViewB and calling ViewControllerA.view addSubView:instanceOfViewB, right? Before doing that, you will want to resize ViewB.
Try something like this:
ViewControllerB *viewControllerB = [[ViewControllerB alloc]initWithNibName:#"ViewB" bundle:nil];
CGRect frame = CGRectMake(self.view.frame.origin.x,
self.view.frame.origin.y,
self.view.frame.size.width,
self.view.frame.size.height - 40);
viewControllerB.view.frame = frame;
[self.view addSubview:viewB.viewControllerB];
Basically it should be close to what you are doing, but I'm setting the size to be 40 px less (whatever you need to remove the tab bar).