iPad presentModalViewController appears in wrong position - ios

First of, I get the feeling apple really doesnt like us optimizing apps for landscape view.
After struggling with my app for 2 days I finally convince it to always and only show in Landscape mode. I even convinced the UIViewController that I present with presentModalViewController to appear in landscape as well. So far so good...
The position of the UIViewController that I present with UIModalPresentationFormSheet is all the way to the bottom right (with the ipad in Landscape positition). I cannot get it to move to the center like it should. Does anyone have any ideas why and or how this works and how I can make it apear in the right position?
EDIT: Added code, this code is called from a UIViewController when a button is pushed.
- (void) buttonPushed
{
pickerViewController = [[UIViewController alloc] init];
[pickerViewController.view setBackgroundColor:[UIColor whiteColor]];
_pickerCustomers = [[UIPickerView alloc] initWithFrame:CGRectMake(22,20,380,216)];
_pickerCustomers.delegate = self;
_pickerCustomers.dataSource = self;
[_pickerCustomers setShowsSelectionIndicator:YES];
[pickerViewController.view addSubview:_pickerCustomers];
_btnPickerDone = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[_btnPickerDone setFrame: CGRectMake(300,250,98,45)];
[_btnPickerDone setTitle:#"Select" forState:UIControlStateNormal];
[pickerViewController.view addSubview:_btnPickerDone];
pickerViewController.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentModalViewController:pickerViewController animated:YES];
}

Have you tried playing with the little "autoposition springs" on the layout IB? Probably you have it attached to the bottom and right, simply remove those attachments.
Here's a link for you: http://disanji.net/iOS_Doc/#documentation/DeveloperTools/Conceptual/IB_UserGuide/Layout/Layout.html
Can also be done in code if you like.

Related

UINavigationController inside UIPopoverController 'Back' animations weird in Landscape

I'm stumped :-\
I have a legacy app in the store that I'm refreshing for iOS 8/9. It was written years ago (pre-ARC) and is a universal app for iPhone and iPad. Everything is now working apart from this ...
On iPad, there is a toolbar at the top of the screen from which I present UIPopoverControllers containing a UINavigationController containing some standard UITableViewController type screens you can drill down into.
In Portrait (and Portrait Upside Down) everything works as expected.
In Landscape however, pressing 'Back' (the standard back not a custom one) causes weird animations - the outgoing controller jumps outside the popover and rapidly slides offscreen (the direction being governed by which orientation the device is in) while the incoming controller simply appears instantly as soon as the outgoing controller jumps outside the popover. I had to use slow animations to determine this as at full speed it just looks like a huge glitch.
There's a short 20 second movie showing the defect here; Note what happens when tapping 'Locations' at 14 seconds in.
If, instead of a UIPopover, I present the VC stack as a form sheet, everything works as expected regardless of orientation. I've also tried the newer UIPopoverPresentationController and experienced the SAME problem, which surprised me a little.
This happens on both of the popovers I'm presenting (one from left of toolbar, one from right of toolbar) and they both have very different internals. The only common factor is that they have a UINavigationController inside a UIPopover.
I've used the view debugger to inspect the view hierarchy, but nothing seems out of the ordinary and I can't capture the view during the glitch no matter how slow I run the simulator so I suspect I'm seeing an internal issue with the popover or navigation controller.
Has anyone seen anything similar? I see this both on-device (iOS 8.4) and in Simulators for iOS 8 and 9.
For context, this project has no storyboards, rarely uses xibs and generally constructs the UI in code within loadView - it really is an old application...
Thanks for any pointers. Not sure how much any code will help here, but here's the presentation of the popover concerned;
LocationsViewController* locationsvc = [[LocationsViewController alloc] init];
UINavigationController *localNavigationController = [[UINavigationController alloc] initWithRootViewController:locationsvc];
localNavigationController.navigationBar.barStyle = UIBarStyleBlackTranslucent;
[locationsvc release];
UIPopoverController* aPopover = [[UIPopoverController alloc] initWithContentViewController:localNavigationController];
aPopover.delegate = self;
aPopover.backgroundColor = [UIColor colorWithWhite:0 alpha:0.9];
self.locationPopoverController = aPopover;
[aPopover release];
[localNavigationController release];
[locationPopoverController presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
I get the same defect with the following, new flavour code;
UINavigationController *destNav = [[UINavigationController alloc] initWithRootViewController:locationsvc];
locationsvc.preferredContentSize = CGSizeMake(320,280);
UIPopoverPresentationController *newPresentationController;
destNav.modalPresentationStyle = UIModalPresentationPopover;
newPresentationController = destNav.popoverPresentationController;
newPresentationController.barButtonItem = sender;
destNav.navigationBarHidden = NO;
[self presentViewController:destNav animated:YES completion:nil];
And the same problem shows when I use UIModalPresentationPageSheet but NOT when I use UIModalPresentationFormSheet.
I had the same issue. The issue was fixed after I added support of landscape orientation to view controllers inside the navigation controller.
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll;
}

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.

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?

UIScrollView Custom ViewController

I have an odd situation. I want user to choose a category by clicking an button inside UIScrollView. Here's the relevant code of page view controller (the one containing UIScrollView made with IB):
- (void)viewDidLoad
{
[super viewDidLoad];
uiScroll.contentSize = CGSizeMake([[SawData shared].categories count]*320,480);
int i = 0;
for (NSString* key in [SawData shared].categories) {
Baton *b = [[Baton alloc] initWithNibName:#"Baton" bundle:nil];
b.view.frame = CGRectMake(i++*320, 0, 320, 480);
[uiScroll addSubview:b.view];
[b release];
}
}
Baton is new UIViewController subclass containing only one button with touchUp action that prints some log info using NSLog. With this code I get the Batons properly arranged side by side. Problem is that clicking the button gives EXC_BAD_ACCESS as Batons view controller is released.
If i remove the [b release]; line I have Batons overlayed one over other as i++ * 320 is giving same result (which i checked and its correct). In this case click on button is working.
Thank you for help!
iOS SDK 4.3
EDIT 1:
After much trial and error, I have managed to find out whats happening. Its 320px width of controls. If i changed them to 321 or 319 all works as it should. I dont need to release the controller to image fill the UIScrollView content AND clicking the button works. What the hell is this?
This might be the reason.
Baton *b = [[Baton alloc] initWithNibName:#"Baton" bundle:nil] autorelease];
You should also make sure that the UIButton is initialized before you click on it. You can do this easily with the debugger.
Take a look here
Does UIView's addSubview really retain the view?

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