I found the ECSlidingViewController when rotate to landscape, the size of the view is not adjusted. so there is a big blank background shown. it works great in portrait.
this only happen on right side menu.
Please find the screen capture here :
landscape!
portrait!
update on 20-May-2014, sub class the ECSlidingViewController, add these 2 method. but the problem still there.
MyECSlidingViewController.m
-(BOOL)shouldAutorotate
{
return [self.topViewController shouldAutorotate];
}
-(NSUInteger)supportedInterfaceOrientations
{
return [self.topViewController supportedInterfaceOrientations];
}
MenuLeftViewController.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *menuItem = self.menuItems[indexPath.row];
self.slidingViewController.topViewController.view.layer.transform = CATransform3DMakeScale(1, 1, 1);
switch (indexPath.row)
{
case 0: // Home
self.slidingViewController.topViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"MainPageNavigationController"];
break;
case 1: // News
self.slidingViewController.topViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"NewsNavigationController"];
break;
case 2: // Songs
self.slidingViewController.topViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"SongsNavigationController"];
break;
case 3: // Notifications
self.slidingViewController.topViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"PushNotificationNavigationController"];
break;
}
[self.slidingViewController resetTopViewAnimated:YES];
}
Try to set shouldAutorotate supportedInterfaceOrientations
If you are trying to set orientation for different pages differently then its a different matter.
To me it seems like this is not possible to EC at the moment. For example the frame of portrait is different that frame of landscape. But when the topviewcontroller is replaced the old frame is just applied to the new topviewcontroller.
This is not a problem when all view controllers supports the same modes. But if some are limited compared to others then entering one of those gives wrong presentation
Hope its fixed in EC 2.0.
Related
i have problem: there is an oriantable (rotatable) navigationcontroller with a viewcontroller. I want to change to a new navigationcontroller of viewcontroller, that is not orientable.
I tried to change only the Viewcontroller with the old navigationcontroller, but in this case, the application was still rotatable.
Thanks for the help and sorry for my english.
You have to redefine an other NavigationController and block the rotation you want. And when you want to push your view controller , call the other Navigation Controller.
YourCustomNavigationController *kiwappNav = [[YourCustomNavigationController alloc] initWithRootViewController:yourViewController];
[self.navigationController pushViewController:kiwappNav animated:YES];
and your custom navigationController for example :
#pragma mark - Orientation
- (BOOL) shouldAutorotate
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations{
switch ([Device getDeviceFormat])
{
case DF_IPAD:
return UIInterfaceOrientationMaskAll;
break;
case DF_IPOD:
return UIInterfaceOrientationMaskPortrait;
break;
default:
return UIInterfaceOrientationMaskAll;
break;
}
}
Hope it will help you.
I am developing ios application that uses two viewcontrollers A and B. A supports both orientations landscape and portrait, when B is only in portrait mode. my goal is B viewcontroller always to be only in portrait mode when I navigate from A to B .I make restrictions on B viewcontroller in the navigationcontroller.
- (BOOL)shouldAutorotate
{
_navigation = (MBNavigationController *) self.frontViewController;
id currentViewController = [_navigation visibleViewController];
if ([currentViewController isKindOfClass:[MBViewController class]])
return NO;
return YES;
}
when A is in portrait orientation and I navigate to B everything works fine. but when A is in landscape mode and I do the same, part of the B controller view is out scenes. please help me to find the right solution.
One possible solution is present the B viewController with another navigationController in which
// sysversion>=ios6
- (BOOL)shouldAutorotate
{
return NO;
}
// sysversion<=ios5
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return NO;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
I know this has been asked and discussed a lot here, but I've spent the last few days scouring the internet for different solutions, and no matter what I try - nothing seems to work.
EDIT:
Tried this solution as well, still no luck...
I have an iOS7 app (I currently don't care for support for iOS6, but it'll be nice to have) that has a root view controller with a menu that slides from the side (this one, to be specific) and lets you switch between different screens. The selected screen is loaded into a navigation controller, and there's a "modal" type segue between the navigation controller and the screens' view controllers (except for the screen that appears first, which has a relationship with the root view controller). I also tried this with "push" segues, same result.
one of these screens has to display only in landscape mode, the others only in portrait.
for this purpose, in my root view controller I've implemented the following:
- (void)awakeFromNib
{
self.contentViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"contentController"];
self.menuViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"menuController"];
}
-(NSUInteger)supportedInterfaceOrientations
{
if (self.contentViewController)
return [self.contentViewController supportedInterfaceOrientations];
return UIInterfaceOrientationMaskPortrait;
}
-(BOOL)shouldAutorotate
{
return YES;
}
In my navigation view controller I have implemented the following:
-(BOOL)shouldAutorotate
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
return [self.topViewController supportedInterfaceOrientations];
}
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [self.topViewController preferredInterfaceOrientationForPresentation];
}
and in each of the portrait screens' view controllers I've implemented:
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait;
}
and in the landscape screen:
- (NSUInteger) supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape;
}
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeLeft;
}
The first screen of the app is a portrait one. So what happens is, the app loads in portrait mode and doesn't rotate to any other orientation (which is great). BUT! Once I load the landscape screen, it loads in portrait mode, and only when I rotate the device to landscape mode, it rotates and locks into landscape mode. And once I switch back to a portrait screen, it loads in landscape mode, and only when I rotate the device to portrait, is rotates and locks into portrait mode, and for some reason makes the screen VERY narrow...
The closest I've ever gotten to a decent solution was implementing this in the landscape screen's view controller:
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
CGRect screenRect = [[UIScreen mainScreen] bounds];
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeLeft];
CGAffineTransform landscapeTransform = CGAffineTransformMakeRotation(degreesToRadian(270));
landscapeTransform = CGAffineTransformTranslate(landscapeTransform, 0.0, 0.0);
[self.navigationController.view setTransform:landscapeTransform];
self.navigationController.view.bounds = CGRectMake(0.0, 0.0, screenRect.size.height, screenRect.size.width);
}
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
CGRect screenRect = [[UIScreen mainScreen] bounds];
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];
CGAffineTransform landscapeTransform = CGAffineTransformMakeRotation(degreesToRadian(0));
landscapeTransform = CGAffineTransformTranslate(landscapeTransform, 0.0, 0.0);
[self.navigationController.view setTransform:landscapeTransform];
self.navigationController.view.bounds = CGRectMake(0.0, 0.0, screenRect.size.width, screenRect.size.height);
}
#define degreesToRadian(x) (M_PI * (x)/180.0)
And changing this view controller's supported and preferred orientations to portrait. Which basically makes the whole app lock in portrait mode.
Although it looks fine, it seems kinda sketchy and I would much rather have a "clean" solution, and support landscape left AND right. Any ideas on what I'm missing here?
If you need me to provide more code, just tell me.
Thanks!! :)
Ok, just in case this interests anyone, this was my solution, using the accepted answer here:
The thing I was missing was in my approach - The landscape VC can't be under the same root VC as the portrait ones, it needs to be or have its own root VC, which is in landscape.
So first, I separated the landscape VC from the rest in the storyboard, now it's completely independent. Next, I created a "view controller switch" method, which basically loads a new controller, sets it to be the root controller, and releases the previous root controller:
+(void)loadController:(UIViewController *)VControllerToLoad andRelease:(UIViewController *)VControllerToRelease
{
//adjust the frame of the new controller
CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
CGRect windowFrame = [[UIScreen mainScreen] bounds];
CGRect firstViewFrame = CGRectMake(statusBarFrame.origin.x, statusBarFrame.size.height, windowFrame.size.width, windowFrame.size.height - statusBarFrame.size.height);
VControllerToLoad.view.frame = firstViewFrame;
//set the new controller as the root controller
[[[UIApplication sharedApplication].delegate window] setRootViewController:VControllerToLoad];
//kill the previous view controller
[VControllerToRelease.view removeFromSuperview];
}
In the landscape VC I added this code:
-(BOOL)shouldAutorotate
{
return YES;
}
And whenever I need to present the landscape VC or go back the the portrait VCs, I just use the VC switch method. For example:
[AppUtils loadController:landscapeViewController andRelease:portraitNavigationController];
That's it! Now everything works like a charm! :)
So I am developing an iPad app that supports only landscape mode except for on one modal view controller. The issue I am having is that once I present the modal view and change the orientation to portrait then dismiss the view, the parent view (which should only support landscape) is in portrait mode until I rotate the device in which it then goes back to landscape and stays that way. I have been beating myself up trying to figure out how to keep the parents view original orientation but haven't been able to find a solution.
I have the following code in my app delegate to allow orientation changes on only that single modal view (GalleryPhotoViewer) :
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
NSUInteger orientations = UIInterfaceOrientationMaskAllButUpsideDown;
if(self.window.rootViewController){
UIViewController *presentedViewController = [[(UINavigationController *)self.window.rootViewController viewControllers] lastObject];
//Support Portrait mode only on Photoviewer
if ([[presentedViewController presentedViewController] isKindOfClass:GalleryPhotoViewController.class] ) {
orientations = UIInterfaceOrientationMaskAll;
}else{
orientations = [presentedViewController supportedInterfaceOrientations];
}
}
return orientations;
}
From the parent class (PhotosViewController) I am calling :
GalleryPhotoViewController *gpView = [GalleryPhotoViewController new];
[self presentViewController:gpView animated:YES completion:nil];
Also in my parent (and other views) I have the following code to disallow portrait mode :
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if(interfaceOrientation == UIInterfaceOrientationPortrait) {
return YES;
} else {
return NO;
}
}
Any ideas on how I can keep the orientation on my parent view? I was thinking about possibly just programmatically changing the orientation on the parent in the viewWillAppear method once the modal is dismissed but then I wouldn't know what the previous orientation was, not to mention I haven't been able to find code to do this regardless for ios6.
EDIT/SOLUTION : So I found a solution and what I ended up doing was leaving the application:supportedInterfaceOrientationsForWindow: code and just adding the UINavigation subclass to the parent view that was presenting the modal view and everything worked as expected and the parent retained its original orientation while the modal was able to change freely.
In my parent :
//To make sure that this view remains in Landscape
#implementation UINavigationController (Rotation_IOS6)
-(BOOL)shouldAutorotate
{
return [[self.viewControllers lastObject] shouldAutorotate];
}
-(NSUInteger)supportedInterfaceOrientations
{
return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}
#end
Thanks #matt for the suggestions.
I think the problem is your use of application:supportedInterfaceOrientationsForWindow:. Instead, get rid of that, and start with a UINavigationController subclass and make that the class of the root view controller that is your navigation interface. Then:
In the UINavigationController subclass, return UIInterfaceOrientationMaskLandscape from supportedInterfaceOrientations.
In the presented (modal) view controller, return UIInterfaceOrientationMaskAll from supportedInterfaceOrientations.
In FirstViewController there is a button. After it is pressed, there is a modal segue that goes to SecondViewController. FirstViewController is Portrait, and SecondViewController is Landscape. In the storyboard file, I set SecondVC to Landscape but the iOS Simulator won't automatically change it's orientation.
Can someone help me find code that automatically turns SecondViewController from Portait to Landscape?
viewDidLoad statement in SecondVC:
-(void)viewDidAppear:(BOOL)animated {
UIDeviceOrientationIsLandscape(YES);
sleep(2);
santaImageTimer = [NSTimer scheduledTimerWithTimeInterval:0.5
target:self
selector:#selector(santaChangeImage)
userInfo:NULL
repeats:YES];
[santaImageTimer fire];
image1 = YES;
}
Any help appreciated.
Sadly, while your attempt to call UIDeviceOrientationIsLandscape(YES); was a valiant attempt, that doesn't actually change orientation. That method is used to confirm whether a variable holding a orientation is landscape or not.
For example, UIInterfaceOrientationIsLandscape(toInterfaceOrientation) will return TRUE if the toInterfaceOrientation holds a landscape orientation, and FALSE if not.
The correct technique for changing orientation is outlined in Handling View Rotations in the UIViewController Class Reference. Specifically, in iOS 6, you should:
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscape;
}
In iOS 5, the necessary method is:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation))
return YES;
else
return NO;
}