Switching views upon rotation not working properly - ios

I've been trying several approaches to get the rotation working as expected but so far I've been facing some problems.
Now I would like to have one class with one xib file containing the 2 orientation views. One for portrait, one for landscape.
I am trying this in my main ViewController (the root controller set in the app delegate. But somehow it's failing : when I rotate, the view is switched but the outlets are not rotated. For instance a simple label from the landscape view will be shown as if the device was in portrait mode.
Here's bits of code :
In my app delegate
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController_iPhone" bundle:nil];
} else {
//self.viewController = [[ViewController alloc] initWithNibName:#"ViewController_iPad" bundle:nil withOrientation:UIInterfaceOrientationPortrait];
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController_iPad" bundle:nil];
}
self.window.rootViewController = self.viewController;
In Viewcontroller.m
- (void)viewDidLoad
{
[super viewDidLoad];
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification object:nil];
}
- (void)orientationChanged:(NSNotification *)notification
{
[self performSelector:#selector(updateLandscapeView2) withObject:nil afterDelay:0];
}
- (void)updateLandscapeView2
{
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
if (UIDeviceOrientationIsLandscape(deviceOrientation))
{
self.view = self.landscapeView;
[[NSNotificationCenter defaultCenter] postNotificationName:#"landscape" object:nil];
}
else if (deviceOrientation == UIDeviceOrientationPortrait && isShowingLandscapeView)
{
self.view = self.portraitView;
[[NSNotificationCenter defaultCenter] postNotificationName:#"portrait" object:nil];
}
}
I intend to forward the orientation change to the subviews of Viewcontroller by using local notifications.
Anyway, what am I missing here ? I don't understand why this is failing.

What i have found is that when you call
[UIDevice currentDevice].orientation
inside the context of a
[viewController performSelector .....]
It didn't work.
Some body with a solution for these?

Related

NSNotificationCenter doesn't work in popup view(ios objC)

I'm working on a iPad project(xcode 7.21+iOS9) and NSNotificationCenter doesn't work.
When user open my app, the tab bar controller will appear.
- (void)viewWillAppear:(BOOL)animated {
if (false == [[MyClass sharedData] getLoginStatus])
{
LoginViewController *loginViewController = [[UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil] instantiateViewControllerWithIdentifier:#"myCustomPopoverLoginVC"];
loginViewController.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentViewController:loginViewController animated:YES completion:^{
}];
...
}
}
- (void)viewDidLoad
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(notificationLogin:) name:#"afterLogin" object:nil];
[super viewDidLoad];
...
}
-(void)notificationLogin:(NSNotification *)notification{
NSLog(#"OhOhOh");
}
In my loginView,
-(IBAction)login:(id)sender{
...
[[NSNotificationCenter defaultCenter] postNotificationName:#"afterLogin" object:nil];
...
}
First of all:
- (void)viewWillAppear:(BOOL)animated {
if (false == [[MyClass sharedData] getLoginStatus])
{
LoginViewController *loginViewController = [[UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil] instantiateViewControllerWithIdentifier:#"myCustomPopoverLoginVC"];
loginViewController.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentViewController:loginViewController animated:YES completion:^{
}];
...
}
}
- (void)viewDidLoad
{
// Add log here to check when its called
-------> NSLog("Add Observer");
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(notificationLogin:) name:#"afterLogin" object:nil];
[super viewDidLoad];
...
}
-(void)notificationLogin:(NSNotification *)notification{
NSLog(#"OhOhOh");
}
then add another log here :
-(IBAction)login:(id)sender{
...
-------> NSLog("Post notification");
[[NSNotificationCenter defaultCenter] postNotificationName:#"afterLogin" object:nil];
...
}
So you can check what called first. Then refer #Sandeep Kumar comment :))
NSNotificationCenter doesn't work in popup view(ios objC)

How to detect the orientation changing ipad

Im creating an iPad application that should be supported both landscape and portrait. I have set root view controller in AppDelegate like this. This view is my Splash screen view.
Inside
`
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationLandscapeLeft)
{
//Do what you want in Landscape Left
viewController1=[[SplashLandscapeViewController alloc] initWithNibName:#"SplashLandscapeViewController" bundle:nil];
}
else if([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationLandscapeRight)
{
//Do what you want in Landscape Right
viewController1=[[SplashLandscapeViewController alloc] initWithNibName:#"SplashLandscapeViewController" bundle:nil];
}
else if([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortrait)
{
//Do what you want in Portrait
viewController1=[[SplashLandscapeViewController alloc] initWithNibName:#"SplashViewController" bundle:nil];
}
else if([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortraitUpsideDown)
{
//Do what you want in Portrait Upside Down
viewController1=[[SplashLandscapeViewController alloc] initWithNibName:#"SplashViewController" bundle:nil];
}
self.window.rootViewController = viewController1;
[self.window makeKeyAndVisible];
return YES;
}
And this is working fine. And this viewcontroller1 is dissmiss after 4,5 seconds and load another viewcontroller. My problem is while that viewcontroller1 showing on the screen, if user turn the ipad how can I recogniz it and load my landscape .xib after removing the current portrait xib.
Please help me.
Thank you
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(changeOrientation) name:UIDeviceOrientationDidChangeNotification object:nil];
add this method into the app view controller for getting notification.
-(void)changeOrientation {
UIDeviceOrientation orientation = [UIDevice currentDevice].orientation;
if (orientation == UIDeviceOrientationPortrait || orientation == UIDeviceOrientationPortraitUpsideDown) {
[[NSBundle mainBundle] loadNibNamed:#"Portrait" owner:self options:nil];
}
else {
[[NSBundle mainBundle] loadNibNamed:#"Landscape" owner:self options:nil];
}
}

UIDeviceOrientationPortrait , ios 6 & 7 , InterfaceOrientation

i have this code i want to go to another uiview but i want to have showing this view (second view) in portrait mode only and the notification in first view doesn't work in second view ;
is there any way to change the for this
[[NSNotificationCenter defaultCenter] removeObserver:self];
view2 *viewController = [[[view2 alloc] init] autorelease];
UINavigationController *navController = [[[UINavigationController alloc] initWithRootViewController:viewController] autorelease];
viewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:navController animated:NO];
i want exactly one function same this code in ios >6
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return NO;
}
Try subclassing the UINavigationController and override the following methods :
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}

AppDelegate should call the method if the screen orientation has changed

I have a popover, which I present from the TabBarItem thats why I make it in AppDelegate, but I need to reshow popover in new place if the screen orientation has changed. In other places of my app I just use the didRotateFromInterfaceOrientation method, but it doesn't called in AppDelegate. How can I solve this?
I present a popover by this code:
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
{
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
if (viewController == [self.objTabBarController.viewControllers objectAtIndex:2])
{
if (self.settingsPopover == nil) {
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main - iPad" bundle: nil];
SettingsViewController *settingsController = [mainStoryboard instantiateViewControllerWithIdentifier: #"SettingsPopover"];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:settingsController];
self.settingsPopover = [[UIPopoverController alloc] initWithContentViewController:navigationController];
CGSize tabBarSize = self.objTabBarController.tabBar.frame.size;
CGPoint center = [self.window.rootViewController.view convertPoint:self.objTabBarController.tabBar.center fromView:self.objTabBarController.tabBar.superview];
center.x += 105;
center.y -= tabBarSize.height / 2;
CGRect rect = {center, CGSizeZero};
[self.settingsPopover presentPopoverFromRect:rect inView:self.window.rootViewController.view permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];
} else {
[self.settingsPopover dismissPopoverAnimated:NO];
self.settingsPopover = nil;
}
return NO;
}
}
return YES;
}
You can register a Notification as follow:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(handleDidChangeStatusBarOrientationNotification:)
name:UIApplicationDidChangeStatusBarOrientationNotification
object:nil];
Then, implement it in the AppDelegate:
- (void)handleDidChangeStatusBarOrientationNotification:(NSNotification *)notification;
{
NSLog(#"The orientation changed to %#", [notification.userInfo objectForKey: UIApplicationStatusBarOrientationUserInfoKey]);
}
Enjoy. :)

Switch View in XIB based on orientation

I have two views inside my XIB for each orientation. They are similar but different so I cannot rely on the autoresizing. I want to switch these views based on the orientation. When I use the method didRotateFromInterfaceOrientation then when it rotates from Portrait it will show the landscape view, this is a problem when it is rotating to PortraitUpsideDown.
And if I modify the code for willRotateToInterfaceOrientation then in LandscapeView the PortraitView is hidden from the user but when the user clicks the buttons they do not show gray out to show that they were clicked and it app responds as if the user is clicking the buttons that are in the portrait view.
Am I going about this problem in the right manner? What do I need to do to fix these errors. I would prefer to use the method willRotateToInterfaceOrientation.
Thanks,
CODE:
- (void)viewDidLoad {
...
for (UIView *v in self.view.subviews) {
v.autoresizingMask = UIViewAutoresizingNone;
}
...
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
if(fromInterfaceOrientation == UIInterfaceOrientationPortrait
|| fromInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) {
//Add landscape view
if(![landscapeView superview]){
for (UIView *v in landscapeView.subviews) {
v.autoresizingMask = UIViewAutoresizingNone;
}
//No effect after testing
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.33];
[self.view addSubview:landscapeView];
[UIView commitAnimations];
}
}else {
if([landscapeView superview]){
[landscapeView removeFromSuperview];
}
}
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if(toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft
|| toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) {
//Add landscape view
if(![landscapeView superview]){
for (UIView *v in landscapeView.subviews) {
v.autoresizingMask = UIViewAutoresizingNone;
}
//No effect after testing
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.33];
[self.view addSubview:landscapeView];
[UIView commitAnimations];
}
}else {
if([landscapeView superview]){
[landscapeView removeFromSuperview];
}
}
}
In Your View Did Load
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(willRotateToInterfaceOrientation:)
name:#"UIDeviceOrientationDidChangeNotification" object:nil];
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
if ([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeLeft) {
viewControllerName *newView = [[viewControllerName alloc] initWithNibName:nil bundle:nil];
newView.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:newView animated:YES];
[newView release];
}
if ([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeRight) {
viewControllerName *newView = [[viewControllerName alloc] initWithNibName:nil bundle:nil];
newView.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:newView animated:YES];
[newView release];
}
if ([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortrait) {
viewControllerName *newView = [[viewControllerName alloc] initWithNibName:nil bundle:nil];
newView.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:newView animated:YES];
[newView release];
}
if ([[UIDevice currentDevice] orientation] == UIDeviceOrientationPortraitUpsideDown) {
viewControllerName *newView = [[viewControllerName alloc] initWithNibName:nil bundle:nil];
newView.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:newView animated:YES];
[newView release];
}
}

Resources