Presenting UIModalViews in landscape mode - cocoa-touch

I'm trying to present some UIModalFormSheets in a my iPad application. It's working without any problems, except one thing:
When I have my iPad in landscape mode my modal form sheet is moving to the center of the screen and then rotates into the appropiate angle. All I want is to present the modal form sheet in the right angle according to the view mode (portrait or landscape), before it is displayed, so that the user doesn't see this rotation.
I have tried all the modes for modalTransitionStyle and modalPresentationStyle, but nothing seems to prevent the modal form sheet from rotating after it is displayed.
This is what I'm doing:
NewFavouriteSheet *newFavouriteSheet = [[NewFavouriteSheet alloc]
initWithNibName:#"NewFavouriteSheet" bundle:nil];
newFavouriteSheet.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentModalViewController:newFavouriteSheet animated:NO];
Does anyone has a suggestion on how to show the modal view in a correct way?
Thanks for your help.

Make sure every view controller in your modal sheet responds appropriately to shouldAutorotateToUserInterfaceOrientation: for the landscape orientations.

Related

iOS 8 - Modal in Popover

I have a popover with TabBarController in it. In one tab there is a TableViewController with a list of names. And there is a plus button, that has a modal segue to AddCharacterVC for adding new names.
In iOS 7 I do it like this:
AddCharacterViewController *acvc = (AddCharacterViewController *)segue.destinationViewController;
acvc.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
acvc.modalPresentationStyle = UIModalPresentationCurrentContext;// so it does not take full screen in popover
And in AddCharacterVC I set content size like this:
- (void)viewWillAppear:(BOOL)animated {
CGSize size = CGSizeMake(320, 480); // size of view in popover
if (IDIOM == IPAD && [self respondsToSelector:#selector(preferredContentSize)]){
self.preferredContentSize = size;
}
And it works perfectly.
However, in iOS 8 modal view does not cover the whole popover, leaving TabBar visible. The user can tap on it or not, anyway modal view won't unwind properly.
I've tried:
setting acvc.modalPresentationStyle to UIModalPresentationOverCurrentContext
tried to set TabBar hidden
checked in storyboard that edges of TableVC extend under Bottom Bar and Bottom Bar in Modal View (AddCharacterVC) is set to none
All with no results.
Now the only thing I can think of is to try making modalPresentationStyleCustom and use UIPresentationController (I'm trying to do it now, but I haven't done it before). Am I missing something? Could there be other way to do it? Sorry, I cannot post images here yet. Many thanks in advance!
Ok, so I've set the modalPresentationStile to UIModalPresentationCustom, and used UIPresentationController - I've just copied code from WWDC-14's LookInside project and modified it a bit.
I'm not sure if it was the best solution, but it worked in my case.

UIKeyboard in iOS7

I'm using Xcode 5 and the iOS7 SDK to build my app. I am wanting to make a sign in page very similar to that of the iOS7 eBay app.
So what I would like to do is this:
When the ViewController loads, I would like two UIButtons just above the keyboard
Once the user has finished entering their information and hitting the done button - the keyboard disappears and background animates very slightly to show a logo at the top.
I'm thinking I should be listening for UIKeyboard notifications and then do things based on that.
Here are my questions:
I am sure I can change the background image, based on the UIKeyboard notification status - how do I make it animate ? I don't want it to just appear?
How do I position the UIButtons correctly to sit by the keyboard ?
You should use the UIToolBar and set it as inputaccessoryview to the textFields.
Here is one clean & clear solution for this problem.
Blog Post here
For backGround animation please use this.
May be you can set the background logo alpha = 0 initially.
[UIView animateWithDuration:0.7 animations:^{
self.view.logoImage.alpha = 1;
// make some more movements for anything that suits to your need.
// set frame of your textFields & any thing else that you need.
}
completion:^(BOOL finished){
// may be you can load a new view controller here.
}];
Hope that helps.

presentModalViewController slides a new view too far up and goes above the top of the screen

-(void)reviewClicked:(id)sender
{
ReviewViewController *newView = [[ReviewViewController alloc] init];
newView.delegate = self;
UINavigationController *navCon = [[UINavigationController alloc] initWithRootViewController:newView];
[self presentModalViewController:navCon animated:YES];
}
I have a splitViewController setup, which is what is probably causing some issues. Within the detail view controller, I have a button that when clicked calls the above code.
The goal is to slide a view from the bottom of the screen upwards so the user can review their selections, and then click a button to return back to the original detail view. This code is working and you can click back and forth between the modal view and original detail view.
The problem is, after it slides up the screen, it continues sliding past where it should stop, and finally stops a good 10-15 pixels too far up. Basically, this modal view slides in so far up that a good chunk of the view goes above the top of the screen. Meanwhile, that same amount of space is "empty black space" at the bottom of the screen, just further suggesting that the view just simply moved too far up.
Complicating matters, it slides in just fine in landscape mode.
So the question is, does anyone know why this bug is occurring to make the modal view slide too far up and past the top of the screen?
-=-=-=-=-=-=-
Edit:
Sorry about that, I meant to type navCon in that spot. I fixed it above.
-=-=-=-=-=-=-
Solution:
-(void)reviewClicked:(id)sender
{
ReviewViewController *newView = [[ReviewViewController alloc] init];
newView.delegate = self;
UINavigationController *navCon = [[UINavigationController alloc] initWithRootViewController:newView];
navCon.view.frame = CGRectMake(0, 0, 768, 1080);
[self presentModalViewController:navCon animated:YES];
}
After some trial and error, I realized I had never actually set the frame of the view! A solution as simple as that...I had been running through examples that included .xib files, and since those files created the frame automatically, I totally overlooked it!
Keep in mind for anyone looking at this in the future. This frame is for portrait mode only. If you want landscape mode, just modify the frame accordingly:
navCon.view.frame = CGRectMake(0, 0, 1080, 768);
Although I had found a quick solution to the problem as described in the question. The fact is, there were many problems still around. Upon further inspection, I called upon the appDelegate to call these methods:
[self.splitViewController presentModalViewController:navCon animated:YES];
[self.splitViewController dismissModalViewControllerAnimated:YES];
Basically, I had the root view class call the modal view which solved ALL of my issues. Apparently calling a modal view from within the detail view of a splitview is NOT the same as calling a modal view from the root view (which happens to be the splitViewController). I hope this helps anyone in the future. Cheers.
-=-=-=-=-=-=-=-
For more reference, see this post I stumbled upon:
UISplitViewController - Pushing Modal View

Possible to manually rotate UIPopoverController's view?

The view system in my app is highly customized and uses a number of views that are manually rotated from portrait to landscape based on user interactions (the rotation is done by applying an affine transform to the view/layer).
I want to present a popover inside one of these rotated views, but the orientation of the popover always appears relative to the orientation of the device (i.e., not relative to the view). I'm guessing the answer is no, but just in case someone has a clever idea: is there any way to manually rotate the view that is presented by UIPopoverController?
Sean, I just tested it for kicks, yes it works.
It has to be done (in my case at least) in viewDidAppear (if done in viewWillAppear, it gets knocked back to the original setting.)
This worked just fine (just tested now) to have a popover at a 90 degree angle. i.e in my case my main view is in portrait mode and the popover is turned 90 deg.
self.navigationController.view.superview.superview.transform = CGAffineTransformMakeRotation (M_PI/2.0);
Are you trying to rotate the popover or just the content shown in the popover? You can control some of the former by setting which arrow orientations are possible. I'm interested in the latter, and it seems to work just by grabbing the content view controller. E.g.:
aPopoverController.contentViewController.view.transform = CGAffineTransformMakeRotation(M_PI);
DISCLAIMER: If you're at all interested in trying to get your app into the store, this code is almost certainly grounds for rejection. It dives into UIKit's private API's which is a big no-no as far as apple is concerned.
#RunningPink had the right idea. Depending on how the view hierarchy is set up, the popover may be back up farther than two superviews. The popover itself it an instance of the (private) class _UIPopover (at least in iOS 5). You can find this view by doing:
UIView *possiblePopover = popoverController.contentViewController.view;
while (possiblePopover != nil) {
// Climb up the view hierarchy
possiblePopover = possiblePopover.superview;
if ( [NSStringFromClass([possiblePopover class]) isEqualToString:#"_UIPopoverView"] ) {
// We found the popover, break out of the loop
break;
}
}
if (nil != possiblePopover) {
// Do whatever you want with the popover
}
In doing this, I found that transforming the view often ended up making the popover look blurry. I found the reason was that the popover's superview was an instance of another private class called UIDimmingView which is responsible for accepting touches outside of the popover and causing the popover to dismiss. Performing the rotation on the dimming view removed the blurriness I was seeing in the popover.
However, transforming the dimming can result in weirdness where certain parts of the window are not "covered" by the dimming view so the popover will not dismiss if these parts of the window are tapped. To get around this, I applied the rotation to the dimming view, reset the dimming view's frame to cover the screen, and then translated the popover view into place.
if (nil != possiblePopover) {
// Found the popover view
CGAffineTransform rotation = CGAffineTransformMakeRotation(-M_PI_2);
CGAffineTransform translation = // Whatever translation in necessary here
// Rotate the UIDimming View and reset its frame
[possiblePopover.superview setTransform:rotation];
[possiblePopover.superview setFrame:CGRectMake(0, 0, possiblePopover.superview.frame.size.height, possiblePopover.superview.frame.size.width)];
// Translate the popover view
[possiblePopover setTransform:translation];
}

UISplitView new slide-in popover becomes fullscreen after memory warning in iOS 5.1

I'm quite new here.
I have a problem with the new iOS 5.1 slide-in popover in UISplitView.
(Before 5.1 the master view controller was presented in a popover, but now it simply slides in form the left.)
When my device is in portrait mode and it receives a memory warning, the master view controller unloads; and when I press the toolbar button to slide in the master view, it loads again.
However after the memory warning it is presented in fullscreen and not only the size of the original master view. (When I rotate the device to landscape and back to portrait, it gets its correct size back.)
Before iOS 5.1 it was always presented in the popover with the correct size.
Anyone has an idea, how to correct this?
I've tried to set the master view's frame size, but it doesn't solve the problem.
Any help is much appreciated!
I had the same problem, but I used this code to solve the problem:
-(void)splitViewController:(UISplitViewController *)svc popoverController:(UIPopoverController *)pc willPresentViewController:(UIViewController *)aViewController
{
aViewController.view.frame = CGRectMake(0, 0, 320, self.view.frame.size.height);
}
Apparently when a memory warning is received, the view controller gets released, so when it presents itself again, it gets it's size from it's parent view, which is full screen. So you just have to reset the frame every time it gets loaded.
I had the same trouble.
You should add below code to AppDelegate.
splitViewController.presentsWithGesture = NO;