简体   繁体   中英

Window subview not rotating after orientation of the device changes

I'm creating an UIView with a label inside AppDelegate and displaying it like this:

    [window addSubview:self.roundedCornerView];

Problem is when I rotate the device the view with label don't rotate at all. The text in the label is in wrong orientation as well. Window in my application got another subview which is the UIViewControllers subview and it is rotating fine.

Do I need to create another UIViewController in my AppDelegate and attach created view to it, then subclassing it and allowing for interface orientation in order to get roundedCornerView to rotate?

UPDATE Ok I've tried to do this by creating new ViewController and sublcassing it here is code in my AppDelegate:

    ActivityIndicatorWithLabelViewController *aiWithLabel = [[[ActivityIndicatorWithLabelViewController alloc] init] autorelease];
aiWithLabel.textOfTheLabel = text;

[window addSubview:aiWithLabel.view];

The ActivityIndicatorWithLabelViewController class is visible here:

//
//  ActivityIndicatorWithLabelViewController.m
//  LOFT
//
//  Created by Marcin Zyga on 15.11.2011.
//  Copyright (c) 2011 __MyCompanyName__. All rights reserved.
//

#import "ActivityIndicatorWithLabelViewController.h"

@implementation ActivityIndicatorWithLabelViewController
@synthesize roundedCornerView;
@synthesize textActivityIndicatorLabel;
@synthesize textOfTheLabel;


- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)didReceiveMemoryWarning
{
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView
{
}
*/


// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
    [super viewDidLoad];

    UIActivityIndicatorView *mainApplicationActivityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
    mainApplicationActivityIndicatorView.frame = CGRectMake(80, 80, 40, 40);
    mainApplicationActivityIndicatorView.hidesWhenStopped = YES;


    //self.roundedCornerView = [[[UIView alloc] initWithFrame:CGRectMake(280, 400, 200, 200)] autorelease];
    self.roundedCornerView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)] autorelease];
    roundedCornerView.backgroundColor = [UIColor blackColor];
    roundedCornerView.alpha = 0.9f;
    roundedCornerView.layer.cornerRadius = 12.0;
    [roundedCornerView addSubview:mainApplicationActivityIndicatorView];


    [mainApplicationActivityIndicatorView startAnimating];
    //  self.roundedCornerView.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth;
    //self.roundedCornerView.autoresizesSubviews = YES;



    self.textActivityIndicatorLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 150, 200, 50)];
    self.textActivityIndicatorLabel.backgroundColor = [UIColor clearColor];
    self.textActivityIndicatorLabel.textAlignment = UITextAlignmentCenter;
    self.textActivityIndicatorLabel.textColor = [UIColor whiteColor];
    self.textActivityIndicatorLabel.font = [UIFont systemFontOfSize:22];
    self.textActivityIndicatorLabel.text = @"";
    //  self.textActivityIndicatorLabel.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth; 
    [self.roundedCornerView addSubview:textActivityIndicatorLabel]; 
    self.textActivityIndicatorLabel.text = textOfTheLabel;

    self.view.frame = CGRectMake(280, 400, 200, 200);
    [self.view addSubview:self.roundedCornerView];
    //self.view = self.roundedCornerView;

}


- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}



- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    if (UIInterfaceOrientationIsLandscape(interfaceOrientation)) {
        [self.textActivityIndicatorLabel removeFromSuperview];
        [self.textActivityIndicatorLabel release];

        self.textActivityIndicatorLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 50, 50)];
        self.textActivityIndicatorLabel.backgroundColor = [UIColor clearColor];
        self.textActivityIndicatorLabel.textAlignment = UITextAlignmentCenter;
        self.textActivityIndicatorLabel.textColor = [UIColor whiteColor];
        self.textActivityIndicatorLabel.font = [UIFont systemFontOfSize:22];
        self.textActivityIndicatorLabel.text = @"Landscape";
        [self.roundedCornerView addSubview:textActivityIndicatorLabel];         

        NSLog(@"LANDSCAPE");
    }
    NSLog(@"ENTERING SUPPORTED ORIENTATION!");
    return YES;
}

@end

As you see there is some debug code in here. When I'm rotating the device from potrait to landscape I get ENTERING SUPPORTE ORIENTATION! as well as LADNSCAPE NSLog. Removing label is working fine, but when I'm adding new one it is still presented (the text) in wrong orientation. What I am doing wrong?

UIWindow should only have one subview which defines the root UIViewController. I believe that UIWindow only forwards rotation events to its first subview.

Create a single container UIView and move your subviews into it.

Solution is follow below steps :

  • In subView's .m file add code on top of interface of you view:

     typedef NS_OPTIONS(NSUInteger, AGInterfaceOrientationMask) { AGInterfaceOrientationMaskPortrait = (1 << UIInterfaceOrientationPortrait), AGInterfaceOrientationMaskLandscapeLeft = (1 << UIInterfaceOrientationLandscapeLeft), AGInterfaceOrientationMaskLandscapeRight = (1 << UIInterfaceOrientationLandscapeRight), AGInterfaceOrientationMaskPortraitUpsideDown = (1 << UIInterfaceOrientationPortraitUpsideDown), AGInterfaceOrientationMaskLandscape = (AGInterfaceOrientationMaskLandscapeLeft | AGInterfaceOrientationMaskLandscapeRight), AGInterfaceOrientationMaskAll = (AGInterfaceOrientationMaskPortrait | AGInterfaceOrientationMaskLandscapeLeft | AGInterfaceOrientationMaskLandscapeRight | AGInterfaceOrientationMaskPortraitUpsideDown), AGInterfaceOrientationMaskAllButUpsideDown = (AGInterfaceOrientationMaskPortrait | AGInterfaceOrientationMaskLandscapeLeft | AGInterfaceOrientationMaskLandscapeRight), } 
  • In subView's .m file add code

     #pragma mark - Orientation - (void)statusBarFrameOrOrientationChanged:(NSNotification *)notification { /* This notification is most likely triggered inside an animation block, therefore no animation is needed to perform this nice transition. */ [self rotateAccordingToStatusBarOrientationAndSupportedOrientations]; } - (void)rotateAccordingToStatusBarOrientationAndSupportedOrientations { UIInterfaceOrientation orientation = [self desiredOrientation]; CGFloat angle = [self UIInterfaceOrientationAngleOfOrientation:orientation]; CGFloat statusBarHeight = [[self class] getStatusBarHeight]; UIInterfaceOrientation statusBarOrientation = [UIApplication sharedApplication].statusBarOrientation; CGAffineTransform transform = CGAffineTransformMakeRotation(angle); CGRect frame = [[self class] rectInWindowBounds:self.view.window.bounds statusBarOrientation:statusBarOrientation statusBarHeight:statusBarHeight]; [self setIfNotEqualTransform:transform frame:frame]; CGRect rect = btnClose.frame; rect.origin.x = (subView.frame.origin.x+subView.frame.size.width)-(rect.size.width/2); rect.origin.y = subView.frame.origin.y-(rect.size.height/2); btnClose.frame = rect; } - (void)setIfNotEqualTransform:(CGAffineTransform)transform frame:(CGRect)frame { if(!CGAffineTransformEqualToTransform(self.view.transform, transform)) { self.view.transform = transform; } if(!CGRectEqualToRect(self.view.frame, frame)) { self.view.frame = frame; } } + (CGFloat)getStatusBarHeight { UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; if(UIInterfaceOrientationIsLandscape(orientation)) { return [UIApplication sharedApplication].statusBarFrame.size.width; } else { return [UIApplication sharedApplication].statusBarFrame.size.height; } } static BOOL IS_BELOW_IOS_7() { static BOOL answer; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ answer = [[[UIDevice currentDevice] systemVersion] floatValue] < 7.0; }); return answer; } + (CGRect)rectInWindowBounds:(CGRect)windowBounds statusBarOrientation:(UIInterfaceOrientation)statusBarOrientation statusBarHeight:(CGFloat)statusBarHeight { CGRect frame = windowBounds; if(IS_BELOW_IOS_7()) { frame.origin.x += statusBarOrientation == UIInterfaceOrientationLandscapeLeft ? statusBarHeight : 0; frame.origin.y += statusBarOrientation == UIInterfaceOrientationPortrait ? statusBarHeight : 0; frame.size.width -= UIInterfaceOrientationIsLandscape(statusBarOrientation) ? statusBarHeight : 0; frame.size.height -= UIInterfaceOrientationIsPortrait(statusBarOrientation) ? statusBarHeight : 0; } return frame; } - (UIInterfaceOrientation)desiredOrientation { UIInterfaceOrientation statusBarOrientation = [[UIApplication sharedApplication] statusBarOrientation]; AGInterfaceOrientationMask statusBarOrientationAsMask = [self AGInterfaceOrientationMaskFromOrientation:statusBarOrientation]; if(self.supportedInterfaceOrientations & statusBarOrientationAsMask) { return statusBarOrientation; } else { if(self.supportedInterfaceOrientations & AGInterfaceOrientationMaskPortrait) { return UIInterfaceOrientationPortrait; } else if(self.supportedInterfaceOrientations & AGInterfaceOrientationMaskLandscapeLeft) { return UIInterfaceOrientationLandscapeLeft; } else if(self.supportedInterfaceOrientations & AGInterfaceOrientationMaskLandscapeRight) { return UIInterfaceOrientationLandscapeRight; } else { return UIInterfaceOrientationPortraitUpsideDown; } } } -(CGFloat)UIInterfaceOrientationAngleOfOrientation:(UIInterfaceOrientation)orientation { CGFloat angle; switch (orientation) { case UIInterfaceOrientationPortraitUpsideDown: angle = M_PI; break; case UIInterfaceOrientationLandscapeLeft: angle = -M_PI_2; break; case UIInterfaceOrientationLandscapeRight: angle = M_PI_2; break; default: angle = 0.0; break; } return angle; } -(AGInterfaceOrientationMask)AGInterfaceOrientationMaskFromOrientation:(UIInterfaceOrientation)orientation { return 1 << orientation; } //If dealloc is a duplicate method then remove this dealloc method and add the unregisterFromNotifications method in dealloc. - (void)dealloc { [self unregisterFromNotifications]; } -(void)unregisterFromNotifications { //for orientation [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidChangeStatusBarOrientationNotification object:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidChangeStatusBarFrameNotification object:nil]; } 
  • Also In subView's .h file add this line.

     - (void)rotateAccordingToStatusBarOrientationAndSupportedOrientations; 

Now time to use above added code for orientation change in subview.

  • While adding subview in window or self.view like this :

     [objAppDelegate.window addSubview:objViewController.view]; //added this method to rotate subview according to orientation when added [objViewController rotateAccordingToStatusBarOrientationAndSupportedOrientations]; 

Reference taken from AGWindowView

Window subviews don't rotate by themselves, they usually rotate with the help of a view controller.

You could either add the views you want rotated to a view controller and then add that to the window, or you could register for device orientation changes notifications and rotate them yourself.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM