Two controllers inside of a UIPopoverController: having issues with frames - ios

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.

Related

ios uitableview bounce went wrong

I implemented a horizontal table view and it looks like this
The category bar, Dining Shopping something, is a horizontal table view and here is the implementation code.
LogInfo(#"Show Category Table start");
// add categories to be subview controller
self.categoriesTable = [[UITableView alloc] init];
self.categoriesTable.transform = CGAffineTransformMakeRotation(-M_PI * 0.5);
[self.categoriesTable setFrame:CGRectMake(0, 64, SCREENWIDTH, 44)];
self.categoriesTable.showsVerticalScrollIndicator = NO;
self.categoriesTable.showsHorizontalScrollIndicator = NO;
self.categoriesTable.pagingEnabled = YES;
self.categoriesTable.delegate = self;
self.categoriesTable.dataSource = self;
self.categoriesTable.separatorStyle = UITableViewCellSeparatorStyleNone;
[self.superView addSubview:self.categoriesTable];
LogInfo(#"Show Category Table Finished");
self.categoriesTable.backgroundColor= [UIColor redColor];
It works as expect but if I change view, for example, I click any button to go to other view and go back to this view. The tableview looks like this
This problem also happpens even if I disable the bounce effect of the table view. Does anyone know how to solve this problem? Thanks!
Rather than applying a transform to the table to make it horizontal, use a collectionView with a horizontal layout.
Edit: If you want to continue using your current setup, try disabling automaticallyAdjustsScrollViewInsets on your view controller.
self.automaticallyAdjustsScrollViewInsets = NO
Edit 2: If you're curious, since iOS 7 every view controller looks at its topmost/first scroll view and adjusts its contentInsets to compensate for the navigation bar transparency which is enabled by default. In this case of course, such behaviour isn't desired at all.

How do you present One small ViewController on Top of a full screen ViewController

I have designed two ViewControllers - VCLarge and VCSmall. VCSmall is freeform.
When I display VCSmall on top of VCLarge - I shows full screen.
So I play tricks and change the formSize in ViewWillAppear - The VCLarge still does show (I see black)
FYI - I do this when the ViewControllers are in a storyboard and have no problem.
IF you want to present your viewcontroller like UIPopover controller like below...
Please see this OpenSource FPPopver.
It is perfect and works fine.
Very easy to implement.
https://github.com/50pixels/FPPopover
YourViewController *controller = [[YourViewController alloc] init];
//our popover
FPPopoverController *popover = [[FPPopoverController alloc] initWithViewController:controller];
[popover presentPopoverFromView:okButton];
That's all.
If you want to get rid off that ARROW tip, you can do that too!
you use [UIView addSubview] to show it on top of VCLarge.
For example, if you're within VCLarge, you would do something like this:
UIView *smallView = [VCSmall alloc] init...
[self.view addSubview:smallView];
You can adjust the size and or position of smallView using appropriate CGRects for smallView.

UIViewController view not size correctly when running iOS7 simulator

I have a custom UIViewController which create a view containing an action bar at the top (view with 4 buttons), a tableview and then another view below the tableview. Layout is done all in code and is not using auto layout.
Everything works perfectly on various device with iOS 7.0 and 7.0.2, but in the simulator, the root view of the controller get anchored at the top right corner of the screen (0,0) instead of below the navigation bar.
I'm going to force the relay out in the viewDidAppear: method, but this seem like a hack...
Thanks for any insights
Edit: added an image. You can see the UIView highlighted. As ManicMonkOnMac mentioned, the UIView is under the toolbar (but this only happens in the simulator, on the device, the view lines up fine)
In the loadView method on the controller, i set the frame when creating the view:
- (void)loadView
{
// Our parent view controller will resize us appropriately. The size set
// here is a convenience for initial view layout.
self.view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 320)];
self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
}
But this frame is later changed. Not by my code, though, but by UIkit code)
Edit2: addded loadView method body
EDIT: After going through session 201 of WWDC 2013, I think I have the solution.
in iOS 7 there is a property that you can set on your view controllers to specify whether you want the views to be overlapped by navigation bar.
viewController.edgesForExtendedLayout = UIRectEdgeNone;//UIRectEdgeAll specifies that nav bars should overlap the view.
Unlike iOS 6, navigation bars are placed over the views in iOS 7.
Use the frame size that excludes the navigation bar.
code:
CGRect frame = CGRectMake(self.view.frame.origin.x,self.view.frame.origin.y+self.navigationController.navigationBar.frame.size.height,self.view.frame.size.width,self.view.frame.size.height);
CustomView *view = [[CustomView alloc] initWithFrame:frame];
[self.view addSubview: view];

UINavigationController nav bar overlaps contained TableView

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];

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