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

6
我正在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];

在这里可以看到ActivityIndicatorWithLabelViewController类:

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

正如您所见,这里有一些调试代码。当我将设备从竖屏旋转到横屏时,会出现ENTERING SUPPORTE ORIENTATION!以及LADNSCAPE NSLog。移除标签的工作正常,但是当我添加新标签时,文本仍然以错误的方向呈现。我做错了什么?

3个回答

4

UIWindow应该只有一个子视图,用于定义根UIViewController。我相信UIWindow只会将旋转事件传递给它的第一个子视图。

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


恐怕这个解决方案也不起作用。这是我的新代码,它的行为与我在帖子中描述的相同: UIView *containerView = [[UIView alloc] initWithFrame:[navController.view frame]]; [containerView addSubview:navController.view];ActivityIndicatorWithLabelViewController *aiWithLabel = [[[ActivityIndicatorWithLabelViewController alloc] init] autorelease]; aiWithLabel.textOfTheLabel = @"test"; [containerView addSubview:aiWithLabel.view]; [window addSubview:containerView]; - Ertai
请上传您的整个项目目录。 - lorean
2
我不行。但是我通过像这样做来解决了这个问题:[[[[[UIApplication sharedApplication] keyWindow] subviews] objectAtIndex:0] addSubview:self.view]; 这里的self.view是ActivityIndicatorWithLabelViewController中的一个视图。 - Ertai
听起来你已经在某个地方向窗口添加了一个子视图。这可以在MainWindow.xib中完成。 - lorean

0

窗口子视图本身不会旋转,通常需要通过视图控制器来实现旋转。

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


我尝试按照你提供的方式去做,但问题仍然存在。我会更新我的帖子并发布完整的代码。 - Ertai

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;

现在是时候在子视图中使用上面添加的代码来处理方向变化了。

在窗口或 self.view 中添加子视图的时候,可以像这样做:
[objAppDelegate.window addSubview:objViewController.view];

// 在添加时添加此方法以根据方向旋转子视图
[objViewController rotateAccordingToStatusBarOrientationAndSupportedOrientations];

参考AGWindowView


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接