2012-08-24 8 views
5

Zrobiłem aplikację testową, aby zapoznać się z tworzeniem niestandardowego kontrolera widoku kontenera. Jeśli obrócę urządzenie, gdy aplikacja zostanie uruchomiona po raz pierwszy lub po zmianie na inny kontroler widoku, nowy widok zostanie zmieniony tak, aby zajmował cały ekran, tak jak zamierzałem. Jeśli jednak obrócę po uruchomieniu aplikacji, a następnie przejdę do nowego kontrolera widoku, widok zachowa swój rozmiar portretu, zamiast być coraz krótszy (w rzeczywistości jest nieco inny - wynosi od 320,460 do 300,480). Główny kontroler widoku jest przydzielany jako init'd w delegacie aplikacji (bez XIB) i ustawiony jako kontroler widoku głównego okna. Oto kod mam w MasterViewController (kontroler zwyczaj pojemnik):Widoki nie zmieniają rozmiaru po obrocie w niestandardowym kontrolerze kontenerów

- (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)); 
} 

Jakieś pomysły dlaczego tak się dzieje (nie wiem, czy to oznacza, że ​​pogląd Widok główny regulatora nie jest zmiana rozmiaru, ale kiedy dostaję to zachowanie bez zmiany rozmiaru, rozpoznawanie gestów reaguje tylko w wąskim widoku, a nie na całym ekranie)?

+3

Okazało się, że jeśli użyję pliku xib i przydzieli initWithNibName: bundle: zamiast samego init, działa poprawnie. Wydaje się, że ma to coś wspólnego z poglądem, który dostajesz po prostu, gdy robisz init. Kiedy jednak loguję widok, wygląda on tak samo niezależnie od tego, czy w zwykłym pliku init, czy w pliku Xib - oba mają tę samą ramkę i to samo automatyczne przypisywanie = W + H – rdelmar

+0

definiują programowo automatyczne maskowanie 'UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight' – yasirmturk

Odpowiedz

0

Nie wysyłasz komunikatów obrotowych do kontrolerów widoku podrzędnego. Przynajmniej nie w opublikowanym przez ciebie kodzie. Po przełączeniu kontrolera nad dziećmi nawet usunięcie poprzedniego potomka z tablicy ChildViewControllers za pomocą [self.currentController removeFromParentViewController], więc nawet jeśli zaimplementujesz - (BOOL) automatycznieForwardAppearanceAndRotationMethodsToChildViewControllers masz zawsze tylko jeden ChildViewController w swoim ParentViewController.

Mam to działa, więc wkleję ci, jak to robię. Najpierw tworzę wszystkie moje kontrolery ViewController, dodam je jako kontrolery widoku potomnego do ParentViewController. Następnie wywołaj metodę 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 

Potem realizowane

- (BOOL)automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers 
{ 
    return YES; 
} 

Przełączanie do widoku dziecko kontrolera odbywa się za pomocą tego kodu

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; 
     } 
    ]; 
} 

To powinno być wystarczających. Ale mam pewne problemy z tym, więc wysyłam komunikaty rotacyjne do nieaktywnych Childów.

- (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]; 
    } 
} 
+0

automaticallyForwardAppearanceAndRotationMethodsToChildViewController jest amortyzowany w systemie iOS 6, zastąpiony przez metodę shouldAutomaticallyForwardRotationMethods. Ale nie musisz go implementować, ponieważ domyślną wartością jest TAK. To nie jest problem. Znalazłem już odpowiedź, o czym wspomniałem w swoim komentarzu do pytania. – rdelmar

0

ręczne dodanie

wewnątrz

- (void)viewDidLoad 

i rozwiązać problem,

jakiegoś powodu wartość wewnątrz ujęć nie był używany Chyba

Powiązane problemy