窗口子视图在设备方向改变后不旋转

时间:2011-11-15 16:38:41

标签: iphone window subview rotation

我正在AppDelegate中创建一个带有标签的UIView,并显示如下:

    [window addSubview:self.roundedCornerView];

问题是当我旋转设备时,带标签的视图根本不会旋转。标签中的文字也是错误的方向。我的应用程序中的窗口有另一个子视图,它是UIViewControllers子视图,并且旋转正常。

我是否需要在AppDelegate中创建另一个UIViewController并将创建的视图附加到它,然后对其进行子类化并允许接口方向以使roundCornerView旋转?

更新 好的我已经尝试通过创建新的ViewController来实现这一点,并在此处将其转换为我的AppDelegate中的代码:

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

[window addSubview:aiWithLabel.view];

此处可以看到ActivityIndi​​catorWithLabelViewController类:

//
//  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

如您所见,这里有一些调试代码。当我将设备从potrait旋转到横向时,我得到了支持支持方向!以及LADNSCAPE NSLog。删除标签工作正常,但是当我添加新标签时,它仍然以错误的方向呈现(文本)。我做错了什么?

3 个答案:

答案 0 :(得分:4)

UIWindow应该只有一个定义根UIViewController的子视图。我相信UIWindow只会将轮换事件转发到第一个子视图。

创建单个容器UIView并将子视图移动到其中。

答案 1 :(得分:0)

窗口子视图不会自行旋转,它们通常在视图控制器的帮助下旋转。

您可以将想要旋转的视图添加到视图控制器,然后将其添加到窗口,也可以注册设备方向更改通知并自行轮换。

答案 2 :(得分:0)

解决方案步骤下方关注

  • 在subView的.m文件中,在您查看的界面上添加代码:

    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),
    }
    
  • 在subView的.m文件中添加代码

    #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];
    }
    
  • 此外,在subView的.h文件中添加此行。

    - (void)rotateAccordingToStatusBarOrientationAndSupportedOrientations;
    

现在可以在子视图中使用以上添加的代码进行方向更改。

  • 在窗口或self.view中添加子视图,如下所示:

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

参考取自AGWindowView