UINavigationController nav bar overlaps contained TableView - ios

I have a third party control that wants me to put a view inside of it. I'm trying to get a UINavigationController containing a series of table views inside of it, but when adding the controls the navigation bar overlaps the tableview by about half a row, which looks dumb.
Here's the code. I'm using the ArcGIS Server iOS SDK to put the navigation controller in a callout box on the map:
IdentifyResultsViewController *idWindow = [[IdentifyResultsViewController alloc] init];
idWindow.results = results;
UINavigationController *nvc = [[UINavigationController alloc] initWithRootViewController:idWindow];
map.callout.customView = nvc.view;
nvc.view.frame = CGRectMake(0, 0, 275, 400);
[map showCalloutAtPoint:self.mapPoint];
Is this a common problem using the UINavigationViewController, or should I look to the third party control?

I actually just had a similar problem with a third party control obstructing my navigation bar. I tried to look into the control but I'm not versed enough to unhide the navigation bar.
What I did may be something you can do too: instead of using the built in UINavigationBar, I kind of built one myself by just putting in a UIView at the top of the page and adding custom buttons to it that performed the functions that I wanted in the bar. This gives you a little more wiggle room around that third party control if you can't find what's causing the issue.
Hope it helps!

I solved this using some simple reordering of code - instead of using initWithRootViewController, I created the navigation view controller, set it's frame manually, and then pushed the view controller on to it:
IdentifyResultsViewController *idWindow = [[IdentifyResultsViewController alloc] init];
idWindow.results = [self filterResults:results];
UINavigationController *nvc = [[UINavigationController alloc] init];
nvc.view.frame = CGRectMake(0, 0, 275, 400);
[nvc pushViewController:idWindow animated:NO];
map.callout.customView = nvc.view;
[map showCalloutAtPoint:self.mapPoint];

Related

How can we place tab bar on top of screen in IOS

I have usually placed tab bar on its as usual bottom I have used following code in application didFinishLaunchingWithOptions for that.
MemberVC *MemberTabBar = [[MemberVC alloc]init];
UINavigationController *navMember = [[UINavigationController alloc] initWithRootViewController:MemberTabBar];
MemberTabBar.tabBarItem.title = #"Member";
MemberTabBar.tabBarItem.image = [[UIImage imageNamed:#"home_icon.png"]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
MemberTabBar.tabBarItem.selectedImage = [[UIImage imageNamed:#"home_icon.png"]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
-----------------------
self.tabBarController = [[UITabBarController alloc]init];
self.tabBarController.viewControllers = #[navMember,navEvent,navPromo,navProfile,navAbout];
self.window.rootViewController = tabBarController;
tabBarController.selectedIndex = 0;
I haver found one source to place it in top but i want to find out the better way.
I have gained some knowledge about how to place in top from following git projects. If any one knows some better way then i will be glad to know about that
https://github.com/hollance/MHTabBarController
How to place tab bar on top of screen in iPhone
You cannot move the TabBar to the top. You'll have to create custom one. Check this article about customizing tab bar:
http://idevrecipes.com/2011/01/04/how-does-the-twitter-iphone-app-implement-a-custom-tab-bar/
Basing on it you may move the custom tab bar to the top and acheive desired result
One way is, you can add UIViewController instead of UITabBarController and add a tabBar to that view controller on the top.
This link may help you.

UINavigationController's nav bar seems invisible, but title and buttons are still visible

I've run into a weird situation. This is all done in code - no Interface Builder.
I'm creating a UIViewController and adding some content to it:
UIViewController* popoverViewController = [[[UIViewController alloc] init] autorelease];
UIView* popoverContentView = [[[UIView alloc] init] autorelease];
popoverContentView.backgroundColor = [UIColor blackColor];
// Add some stuff to popoverContentView
popoverViewController.view = popoverContentView;
I then create a UINavigationController, set its root view controller to the UIViewController from above, and add a title and a button to the navigationItem:
UINavigationController* popoverNav = [[[UINavigationController alloc] initWithRootViewController:popoverViewController] autorelease];
popoverViewController.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(dismissPopover)] autorelease];
[popoverViewController.navigationItem setTitle:#"MY TITLE"];
Then I set up a UIPopoverController with the UINavigationController in it and present it:
self.popoverController = [[[UIPopoverController alloc] initWithContentViewController:popoverNav] autorelease];
self.popoverController.delegate = self;
[self.popoverController setPopoverContentSize:CGSizeMake(320, 216) animated:NO];
[self.popoverController presentPopoverFromRect:self.cell.frame inView:self.popoverParentView permittedArrowDirections:UIPopoverArrowDirectionUp | UIPopoverArrowDirectionDown animated:YES];
The problem is that everything appears correctly with one exception: the navigation bar is invisible, but the title text and the bar button still show up and work correctly. I've tried messing with the bar's hidden and tintColor properties and changed the size of the popover, but nothing changes.
I'm sure I'm missing something obvious, but I can't see it.
I have other examples of similar things in my project's codebase, but those appear correctly. Any ideas as to why this is happening or how I could fix it?
EDIT
Not sure if the following will help, but I'm hoping it will provide some clues as to what's really going on here to someone who's seen something like this before.
I pushed a new (blank) view controller onto popoverNav just to see what would happen. It pushes and animates perfectly. Everything looks right except that the nav bar is still transparent and the bar button items are pushed to the top of the view.
Perhaps not the main cause of the problem, but it looks like the UIDatePicker is clipped by the CGSize you have setup. As far as I can remember, the default height for the picker is 216 (which you have) but you haven't taken into consideration the required height for the UINavigationBar.
I'm not sure why the background of the view looks to be some kind of textured grey unless this is set in your UIViewController but it doesn't appear that way from the code you pasted. This certainly isn't a default texture for iOS though.
Perhaps try and make your CGSize a little larger to accommodate the contents of the view as it looks as though the "Done" button is hugging the top right corner where there should be a fair few points worth of spacing around this by default.
Also, is there a reason why you're creating a new view and assigning it as the view property of your view controller?
UIView* popoverContentView = [[[UIView alloc] init] autorelease];
popoverContentView.backgroundColor = [UIColor blackColor];
// Add some stuff to popoverContentView
popoverViewController.view = popoverContentView;
Why not add the content as subviews of the view instead?

Custom NavigationBar

I have a Navigation Controller as the root of my app and I am using the appearance proxy to customise the look on iOS 5, but for iOS 4 I was hoping to use a category to override drawRect:, this was fine, except that all the Navigation bars were affected as you would expect from a category.
I don't want to tamper with the "system" popups, such as the Mail composer, or the SMS composer, I want their bars to stay blue and system-like.
I Tried to create my own UINavigationController with it's xib and change the class of the NavigationBar to my custom sub lass of UINavigationBar. But the results are not taking affect at all on screen.
I am aware of the following post but couldn't get any solutions to run as expected.
How to subclass UINavigationBar for a UINavigationController programmatically?
My first attempt which does work but uses an undocumented setNavigationBar: method:
_myNavigationController = [[UINavigationController alloc] initWithRootViewController:someVC];
if([[BT_NavigationController class] respondsToSelector:#selector(appearance)]){
// some iOS 5 magic in here !
[_myNavigationController.navigationBar setBackgroundImage:[UIImage imageNamed:#"topbar.png"];
}else{
// Probably looking at app store refusal
CustomBar * bar = [[CustomBar alloc] init];
// [_myNavigationController setNavigationBar: bar];
[bar release];
}
[parentView presentModalViewController:_myNavigationController animated:YES];
To avoid that I created a UINavigationController, which I also had a xib for, reassigning the class of the navigation bar to my custom class, but placing breakpoints in drawRect: method, I can see that this isn't being called.
Why would that be, it seems that my code is not loading the nib, and therefore not realising the nab bar should be my custom class and not the UINavigationBar.
Any tips would be helpful, thanks.
If your modification is just about adding an image, you can simply insert it from the view controllers you want to customize:
UIImageView *bgImageView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"topbar.png"]] autorelease];
[self.navigationController.navigationBar addSubview:bgImageView];
You have to tweak a little based on what other elements you have in your UINavigationBar for your UIImageView to be at the lowest index of the subviews but still above the background. Worked for us.
Good luck.

Two controllers inside of a UIPopoverController: having issues with frames

I have a UIPopoverController with two view controllers inside of it. I'm building it like so:
CommentsPopoverController *commentsPopoverController = [[CommentsPopoverController alloc] init];
self.delegate = commentsPopoverController;
commentsPopoverController.navigationItem.title = #"Comments";
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:commentsPopoverController];
popover = [[UIPopoverController alloc] initWithContentViewController:navController];
Inside my commentsPopoverController I have this:
commentsViewController = [[CommentsViewController alloc] init];
commentsViewController.view.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
addCommentsViewController = [[AddCommentViewController alloc] init];
addCommentsViewController.view.frame = CGRectMake(0, commentsViewController.view.bounds.size.height - 200, 320, 346);
addCommentsViewController.view.backgroundColor = [UIColor darkGrayColor];
[self.view addSubview:addCommentsViewController.view];
[self.view addSubview:commentsViewController.view];
So when I first load the popover, the addCommentsViewController is hidden by the commentsViewController. When I reveal it, it looks like this:
So far so good. The problem I'm having is that from here, when the user rotates the device or shows the keyboard or shows the keyboard THEN rotates the device things start to get out of whack. The top view controller (commentsViewController) which is a UITableView always does the right thing no matter what the orientation is or whether or not the keyboard is showing. But the bottom view controller (addCommentsViewController) doesn't automatically change it's origin.y to stay directly under the top view controller.
So I've basically had to hack the crap out of my code to keep the addCommentsViewController directly under the commentsViewController by constantly calculating the height of the top view controller so that I could adjust the bottom view controller's origin.y. This involved dropping in NSNotifications for the keyboard's show/hide state and for the device's orientation and constantly recalculating. Very hackish and ugly.
So my question (finally) is: Is there an easier way of controlling these views or am I stuck hacking it the way I did?
To handle rotation, there are two appropriate techniques. One is that you make CommentsPopoverController's view a subclass of UIView that overrides layoutSubviews to lay out your two views properly. The other is that you define viewDidLayoutSubviews on CommentsPopoverController to lay out your views. If you lay out your views in either of these methods, you shouldn't have to subscribe to rotation notifications.
As for moving your view out from under the keyboard, that is discussed in the Text, Web, and Editing Programming Guide for iOS. Part of the technique involves subscribing to keyboard will show/did hide notifications.
I assume your CommentsViewController is a subclass of UITableViewController, because UITableViewController takes care of adjusting the table view when the keyboard is hidden or shown.

ABNewPersonViewController in a subview

I am writing an iPad app that requires the user to enter names and addresses and would like to use ABNewPersonViewController as the interface. The documentation says that this view controller should only be used from within a navigation controller. Is there anyway I can use just the ABNewPersonViewController in a subview (with a navigation controller) without it taking over my whole screen? I assume I can do this easily enough in a popover but I would prefer to have it integrated into my interface... Thanks for any help you can provide!
Consider presenting your UINavigationViewController by presentModalViewController:animated: and change modalViewPresentationStyle to UIModalPresentationPageSheet.
See the reference : http://developer.apple.com/library/ios/#documentation/uikit/reference/UIViewController_Class/Reference/Reference.html
Well, after much looking into this, it does not see that there is any way to use the address book UIs in a subview but they do work quite well in a popover view. However, this popover needs to be exactly 320x460 pixels or some other number with the same aspect ratio for the "add photo" to work correctly (otherwise the photo is stretched). In the popover's view controller viewDidLoad method I added:
self.picker = [[[ABNewPersonViewController alloc] init] autorelease];
self.picker.newPersonViewDelegate = self;
self.navigationController = [[[UINavigationController alloc] initWithRootViewController:self.picker] autorelease];
self.navigationController.view.frame = CGRectMake(0.0, 0.0, self.view.frame.size.width, self.view.frame.size.height);
[self.view addSubview:self.navigationController.view];
This seems to work fine. Let me know if you know of something better.

Resources