I'm sure this is a matter of me not knowing how to phrase my question, but I'm at a loss.
I'm working on an app with 2 subviews that will be on the top of the screen at all times (taking up a total of 114 pixels including the status bar). I want the rest of the space to be taken up with a UITabBar and it's child views.
The closest I've been able to get is a tab view that is sized correctly but is positioned at 0,0 so it's under my persistent subviews.
// Create the main toolbar
toolbar = [[UIToolbar alloc] init];
[toolbar sizeToFit];
toolbar.frame = CGRectMake(0.0, 20, 768, 44);
UILabel *textLabel = [[UILabel alloc] init];
textLabel.frame = CGRectMake(240, 20, 300, 40);
textLabel.textAlignment = UITextAlignmentCenter;
textLabel.backgroundColor = [UIColor clearColor];
textLabel.text = #"Character Name";
[self.window addSubview:textLabel];
[textLabel release];
...
// Create the stats bar
StatsViewController *statsView = [[StatsViewController alloc] init];
statsView.view.frame = CGRectMake(0.0, 64, 768, 50);
[self.window addSubview:statsView.view];
// Create Tab Bar Controller and Tab View Controllers
tabBarController = [[UITabBarController alloc] init];
...
[self.window setRootViewController:tabBarController];
[tabBarController release];
[self.window addSubview:toolbar];
[self.window bringSubviewToFront:statsView.view];
[self.window bringSubviewToFront:textLabel];
[self.window makeKeyAndVisible];
return YES;
A tab bar controller (or any view controller, for that matter) will always try to resize its view so that it takes up the entire bounds of its superview. So if you want the tab bar controller to not do that, I would create another plain view controller that becomes your new root view controller.
In that view controller's view, you create 2 container subviews, one for your statsView and one for the tab bar controller. Now you add the tab bar controller's view to the one container view and the StatsViewController's view to the other.
(Note: I did not test this.)
Related
problem
I cannot for the life of me get it to show.
Here's the implementation of the nav bar
_navBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 50)];
[_navBar setDelegate:self];
[self.view addSubview:_navBar];
_navBar is a UINavigationBar property.
Here's where I add the button.
UIBarButtonItem *button = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd
target:self
action:#selector(flipView:)];
self.navigationItem.rightBarButtonItem = button;
However, nothing shows. Any help?
self.navigationItem is read automatically by a parent UINavigationController. But you don't have one.
Thus, you have two choices:
Instead of a loose nav bar that you create and put into the interface yourself (as you are doing in your first code), be the child of a UINavigationController. Now setting self.navigationItem will work.
Or, create a navigation item, configure it, and push it manually onto your loose nav bar. Your code will then have this structure:
UINavigationItem* ni = [[UINavigationItem alloc] initWithTitle:// ...];
UIBarButtonItem* b = // ...;
ni.rightBarButtonItem = b;
_navbar.items = #[ni];
I am using the following code to create my scrollview. I would like to move the scrollView down 44px to make room for my nav bar.
scroll = [[UIScrollView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
scroll.backgroundColor = [UIColor clearColor];
scroll.delegate = self;
image = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Menu.png"]];
scroll.contentSize = image.frame.size;
[scroll addSubview:image];
scroll.minimumZoomScale = scroll.frame.size.width / image.frame.size.width;
scroll.maximumZoomScale = 2.0;
[scroll setZoomScale:scroll.minimumZoomScale];
UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleDoubleTap:)];
[doubleTap setNumberOfTapsRequired:2];
[scroll addGestureRecognizer:doubleTap];
self.view = scroll;
any help is appreciated.
Your code is correct, to manually create a frame do:
scroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0,44,320,480)];
:)
This is for iPod and iphone View but this will let the scroll start at 44px
Cant you just add a scroll view in in interface builder as an outlet, place it underneath your nav bar.
Declare scroll view in .h
in .m under ViewDidLoad
[scroll setScrollEnabled:YES];
[scroll setContentSize: CGSizeMake(320, 1000)]; ////or whatever size you want here
You probably want to init it with a different frame... but it depends on where/how this nav bar is being created. If you have a view controller, and these are all subviews of the view controller's view, then you should be creating the objects in viewDidLoad, then just create the nav bar first, using self.view.bounds to obtain the initialization width. I assume you'll want to put UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleBottomMargin as the autoResizingMask here. Then if the scrollview is the rest of the view below the nav bar, you can create the frame for it using
CGRect scrollFrame = CGRectInset(self.view.bounds, 0, navbar.bounds.size.height)
Put an autoresizingMask of UIViewAutoresizingFlexibleWidth | UIViewAutoResizingFlexibleHeight on the scrollview.
If you are creating the views in a different place/way, then some of that might need modification. I was assuming your view is a nav bar at the top, x pixels tall (44 in this case but it doesn't and shouldn't matter in the context of setting the scrollview frame). and then a scrollview that fills the rest of the view.
I can't figure out why that view takes the entire screen.
In AppDelegate file
...
self.viewController = [[[ViewController alloc]init]autorelease];
[self.window setRootViewController:self.viewController];
self.window.backgroundColor = [UIColor whiteColor];
..
In ViewController.m
UIView *view = [[UIView alloc]initWithFrame:CGRectMake(30, 30, 30, 30)];
[view setBackgroundColor:[UIColor greenColor]];
self.view = view;
When I run the app the screen is entirely green instead of having just a square in green.
What is wrong here ?
The erroneous line is here:
self.view = view;
When you set a view of a UIViewController that is the root controller, it is guaranteed to fill the screen. Instead, add it as a subview:
[self.view addSubview:view];
And you should be fine.
The view controller automatically manages the size of its root view (self.view), so even if you initialize it with a smaller size it will later get resized to fill the screen. This resizing conveniently also happens when the interface orientation changes (see the answer this question).
As suggested by Richard's answer, you can add your green view as a subview to the controller's root view. The crash you get is probably because the root view does not exist yet when you try to access it. Try the following:
- (void) loadView
{
[super loadView]; // creates the root view
UIView* subView = [[UIView alloc] initWithFrame:CGRectMake(30, 30, 30, 30)];
[subView setBackgroundColor:[UIColor greenColor]];
// because you don't set any autoresizingMask, subView will stay the same size
[self.view addSubview:subView];
}
I have added a UISearchBar to a table in my iPad app using the below code. The table is on the left hand side of my split view controller.
The problem is that when the app starts the search bar is strangely off screen to the left - you can just see the last few pixels of it. If you click on it, or scroll down and back up, it reverts itself and looks like it should.
Can anyone suggest how to fix this ?
Thanks
searchBar = [[UISearchBar alloc] init];
self.tableView.tableHeaderView = searchBar;
searchController = [[UISearchDisplayController alloc]
initWithSearchBar:searchBar
contentsController:self];
searchBar.delegate = self;
searchController.delegate = self;
searchController.searchResultsDelegate=self;
searchController.searchResultsDataSource=self;
You can try to create the UISearchBar with a frame like:
CGRect searchViewFrame = CGRectMake(33, 33, 264, 31);
or whatever dimensions or origin.
Like other resource, you can create the UISearchBar within a UIView, and add this UIView to the UITableView:
UIView *containerSearch = [[UIView alloc] initWithFrame: searchViewFrame];
searchBar = [[UISearchBar alloc] init];
[containerSearch addSubview: searchBar];
self.tableView.tableHeaderView = containerSearch;
So, my iPad program has a pseudo-split view controller (one that I implemented, not base SDK one), and was working correctly a while ago. It has the basic layout (UINavController for master, content view controller for detail on right), but I have it so the master view doesn't disappear when rotated into portrait view.
Recently, I added in a UITabBarController to contain the entire split view, which has made the navigation bar go wonky, while all the other views are positioned fine. In addition, the navigation bar only gets mispositioned when the program starts up while the iPad is in landscape, or upside-down portrait. If it starts out in portrait, everything is fine.
Example images can be found here:
http://profile.imageshack.us/user/Pzychotix
Image where the navigation bar is upwards is when I initially launch the program.
Image where the navigation bar is downwards is after I rotate once or more times.
Relevant Code:
RootViewController.m:
- (void)loadView {
navController = [[NavigationBreadcrumbsController_Pad alloc] init];
ABTableViewController_Pad * tableViewController = [[ABTableViewController_Pad alloc] initWithNibName:#"ABTableView"];
master = [[UINavigationController_Pad alloc] initWithRootViewController:tableViewController];
[tableViewController release];
// Dummy blank UIViewcontroller
detail = [[UIViewController alloc] init];
detail.view = [[[UIView alloc] init] autorelease];
[detail.view setBackgroundColor:[UIColor grayColor]];
self.view = [[[UIView alloc] init] autorelease];
self.view.backgroundColor = [UIColor blackColor];
[self positionViews];
[self.view addSubview:navToolbarController.view];
[self.view addSubview:master.view];
[self.view addSubview:detail.view];
}
// Handles the respositioning of view into it's current orientation
-(void)positionViews{
CGFloat tabBarOffset = 0;
if(self.tabBarController){
tabBarOffset = self.tabBarController.tabBar.frame.size.height;
}
if(self.interfaceOrientation == UIInterfaceOrientationPortrait || self.interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) {
self.view.frame = CGRectMake(0, 0, 768, 1004);
navController.view.frame = CGRectMake(0,0,768,44);
//adjust master view
[master.view setFrame:CGRectMake(0, 44, 320, 1024 - 44 - 20 - tabBarOffset)];
//adjust detail view
[detail.view setFrame:CGRectMake(321,44, 448, 1024 - 44 - 20 - tabBarOffset)];
}
// Landscape Layout
else{
self.view.frame = CGRectMake(0, 0, 748, 1024);
navToolbarController.view.frame = CGRectMake(0,0,1024,44);
//adjust master view
[master.view setFrame:CGRectMake(0, 44, 320, 768 - 44 - 20 - tabBarOffset)];
//adjust detail view
[detail.view setFrame:CGRectMake(321,44, 1024 - 320, 768 - 44 - 20 - tabBarOffset)];
}
}
Well I've found a solution, though I'm still scratching my head as to why it's working.
Basically, I called layoutIfNeeded on my UINavigationController, and that fixed everything right up. What I don't understand is why it was working before, or why I would need to call layoutIfNeeded, as I assumed setFrame would automatically deal with laying out any subviews of controllers.