在自定义容器控制器中旋转后未调整大小的视图

时间:2012-08-24 05:30:39

标签: ios uiviewcontroller

我已经制作了一个测试应用程序来熟悉自定义容器视图控制器。如果我在应用程序首次启动时或切换到其他视图控制器后旋转设备,则新视图会调整大小以占用整个屏幕,正如我所预期的那样。但是,如果我在应用程序启动后旋转,然后切换到新的视图控制器,视图将保持其纵向大小而不是越来越短(实际上它略有不同 - 从320,460到300,480)。主视图控制器在app delegate(no xib)中为init init,并设置为窗口的根视图控制器。这是我在MasterViewController(自定义容器控制器)中的代码:

- (void)viewDidLoad {
    [super viewDidLoad];
    WelcomeController *welcome = [[WelcomeController alloc] initWithNibName:@"ViewController" bundle:nil];
    self.currentController = welcome;
    [self addChildViewController:welcome];
    [self.view addSubview:welcome.view];

    UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeLeft:)];
    swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
    [self.view addGestureRecognizer:swipeLeft];
}


- (void)swipeLeft:(UISwipeGestureRecognizer *)gesture {
    if (gesture.state == UIGestureRecognizerStateRecognized) {
        UIActionSheet *sheet =[[UIActionSheet alloc] initWithTitle:@"Select A Destination" delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle:nil otherButtonTitles:@"welcome",@"Play",@"Scores", nil];
        [sheet showInView:self.view];
    }
}

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
    switch (buttonIndex) {
        case 0:{
            if ([self.currentController class] != [WelcomeController class] ) {
                WelcomeController *welcome = [[WelcomeController alloc] initWithNibName:@"ViewController" bundle:nil];
                [self addChildViewController:welcome];
                [self moveToNewController:welcome];
            }
            break;
        }
        case 1:{
            if ([self.currentController class] != [PlayViewController class] ) {
                PlayViewController *player = [[PlayViewController alloc] initWithNibName:@"PlayViewController" bundle:nil];
                [self addChildViewController:player];
                [self moveToNewController:player];
            }
            break;
        }
        case 2:{
            if ([self.currentController class] != [HighScores class] ) {
                HighScores *scorer = [[HighScores alloc] initWithNibName:@"HighScores" bundle:nil];
                [self addChildViewController:scorer];
                [self moveToNewController:scorer];
            }
            break;
        }
        case 3:
            NSLog(@"Cancelled");
            break;

        default:
            break;
    }
}

-(void)moveToNewController:(id) newController {
    [self.currentController willMoveToParentViewController:nil];
    [self transitionFromViewController:self.currentController toViewController:newController duration:.6 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{}
     completion:^(BOOL finished) {
         [self.currentController removeFromParentViewController];
         [newController didMoveToParentViewController:self];
         self.currentController = newController;
     }];
}


- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return YES;//(interfaceOrientation == (UIInterfaceOrientationPortrait | UIInterfaceOrientationLandscapeLeft));
}

为什么会发生这种情况的任何想法(我不知道这是否意味着主视图控制器的视图没有调整大小,但是当我得到这种非调整大小的行为时,手势识别器仅在窄视图中响应,而不是整个屏幕)?

2 个答案:

答案 0 :(得分:0)

您没有向您的子视图控制器发送轮换消息。至少不在您发布的代码中。在切换Child Controller之后,您甚至可以使用[self.currentController removeFromParentViewController]从ChildViewControllers数组中删除以前的子项,因此即使您实现了 - (BOOL)automaticForwardAppearanceAndRotationMethodsToChildViewControllers ,您的ParentViewController中也只有一个ChildViewController。

我有这个工作,所以我会告诉你我是怎么做的。首先,我创建所有的ViewControllers,将它们作为子视图控制器添加到ParentViewController。然后调用didMoveToParentViewController:方法。

//Controller1
Controller1 *c1 = [[Controller1 alloc] init];
c1.view.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
[self addChildViewController:c1];
[c1 didMoveToParentViewController:self];

//Controller2
Controller2 *c2 = [storyboard instantiateViewControllerWithIdentifier:@"c2"]; 
index.view.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
[self addChildViewController:c2];
[c2 didMoveToParentViewController:self];
c2.view.frame = m_contentView.frame;
[self.view addSubview:c2.view];   //It is in initial screen so set it right away
m_selectedViewController = c2;

//Controller3
Controller3 *c3 = [storyboard instantiateViewControllerWithIdentifier:@"c3"];
compare.view.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
[self addChildViewController:c3];
[c3 didMoveToParentViewController:self];

m_controllers = [NSArray arrayWithObjects:c1, c2, c3, nil];  //Hmm now i think this is not needed, I can access viewController directly from self.childViewControllers array

然后我实施了

- (BOOL)automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers
{
    return YES;
}

使用此代码

切换到子视图控制器
if (value < m_controllers.count)
{
    UIViewController *contentViewController = [m_controllers objectAtIndex:value];

    contentViewController.view.frame = m_contentView.frame;

    [self transitionFromViewController:m_selectedViewController toViewController:contentViewController duration:0 options:UIViewAnimationOptionTransitionNone animations:nil completion:^(BOOL finished) {
        m_selectedViewController = contentViewController;
        }
     ];
}

应该这样做。但是我遇到了一些问题,所以我自己向不活跃的Childs发送轮换消息。

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    for (UIViewController *vc in m_controllers) 
    {
        if(vc != m_selectedViewController)
            [vc willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
    }
}

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    for (UIViewController *vc in m_controllers) 
    {
        if(vc != m_selectedViewController)
            [vc willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
    }
}

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    for (UIViewController *vc in m_controllers) 
    {
        if(vc != m_selectedViewController)
            [vc didRotateFromInterfaceOrientation:fromInterfaceOrientation];
    }
}

答案 1 :(得分:0)

手动添加

self.view.autoresizesSubviews = YES;

里面

- (void)viewDidLoad

它解决了这个问题,

由于某种原因,故事板里面的值没有被使用我猜