UIViewController zwraca nieprawidłową ramkę?

Kiedy uruchamiam Kontroler ViewController w trybie landscape (Po wywołaniu viewDidLoad), drukuję ramkę, która daje mi rozmiar ramki dla trybu portretowego.

Czy to błąd jakieś sugestie?

- (void)viewDidLoad
{
   [super viewDidLoad];

   NSLog(@"%@", NSStringFromCGRect(self.view.frame));
   // Result is (0, 0 , 768, 1024)
}
Author: aryaxt, 2012-03-03

2 answers

Jest kilka rzeczy, których nie rozumiesz.

Najpierw system wysyła cię viewDidLoad natychmiast po załadowaniu stalówki. Nie dodał jeszcze widoku do hierarchii widoków. Więc nie zmienił rozmiaru widoku na podstawie obrotu urządzenia.

Po Drugie, ramka widoku znajduje się w przestrzeni współrzędnych superwizora. Jeśli jest to twój główny widok, jego superview będzie UIWindow (gdy system faktycznie doda twój widok do hierarchii widoków). Uchwyty UIWindow obracanie przez ustawienie transformacji jego subview. Oznacza to, że ramka widoku niekoniecznie będzie tym, czego oczekujesz.

Oto hierarchia widoków w orientacji pionowej:

(lldb) po [[UIApp keyWindow] recursiveDescription]
(id) $1 = 0x09532dc0 <UIWindow: 0x9632900; frame = (0 0; 768 1024); layer = <UIWindowLayer: 0x96329f0>>
   | <UIView: 0x9634ee0; frame = (0 20; 768 1004); autoresize = W+H; layer = <CALayer: 0x9633b50>>

A oto hierarchia widoków w orientacji poziomej po lewej stronie:

(lldb) po [[UIApp keyWindow] recursiveDescription]
(id) $2 = 0x09635e70 <UIWindow: 0x9632900; frame = (0 0; 768 1024); layer = <UIWindowLayer: 0x96329f0>>
   | <UIView: 0x9634ee0; frame = (20 0; 748 1024); transform = [0, -1, 1, 0, 0, 0]; autoresize = W+H; layer = <CALayer: 0x9633b50>>

Zwróć uwagę, że w orientacji poziomej rozmiar ramki wynosi 748 x 1024, Nie 1024 x 748.

To, co prawdopodobnie chcesz zobaczyć, jeśli jest to twój widok główny, to Widok granice:

(lldb) p (CGRect)[0x9634ee0 bounds]
(CGRect) $3 = {
  (CGPoint) origin = {
    (CGFloat) x = 0
    (CGFloat) y = 0
  }
  (CGSize) size = {
    (CGFloat) width = 1024
    (CGFloat) height = 748
  }
}

Prawdopodobnie chcesz wiedzieć, kiedy transformacja, ramka i granice widoku zostaną zaktualizowane. Jeśli interfejs jest w orientacji poziomej, gdy kontroler widoku ładuje swój widok, otrzymasz wiadomości w tej kolejności:

{{0, 0}, {768, 1004}} viewDidLoad
{{0, 0}, {768, 1004}} shouldAutorotateToInterfaceOrientation:
{{0, 0}, {768, 1004}} shouldAutorotateToInterfaceOrientation:
{{0, 0}, {768, 1004}} viewWillAppear:
{{0, 0}, {768, 1004}} shouldAutorotateToInterfaceOrientation:
{{0, 0}, {768, 1004}} shouldAutorotateToInterfaceOrientation:
{{0, 0}, {768, 1004}} willRotateToInterfaceOrientation:duration:
{{0, 0}, {1024, 748}} viewWillLayoutSubviews
{{0, 0}, {1024, 748}} layoutSubviews
{{0, 0}, {1024, 748}} viewDidLayoutSubviews
{{0, 0}, {1024, 748}} willAnimateRotationToInterfaceOrientation:duration:
{{0, 0}, {1024, 748}} shouldAutorotateToInterfaceOrientation:
{{0, 0}, {1024, 748}} viewDidAppear:

Możesz zobaczyć, że granice Twojego widoku zmieniają się po otrzymujesz willRotateToInterfaceOrientation:duration: i przed otrzymujesz viewWillLayoutSubviews.

Metody viewWillLayoutSubviews i viewDidLayoutSubviews są nowe w systemie iOS 5.0.

layoutSubviews wiadomość jest wysyłana do Widok, Nie kontroler widoku, więc musisz utworzyć własną podklasę UIView, jeśli chcesz jej użyć.

 157
Author: rob mayoff,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-02 22:14:39

Oto czyste rozwiązanie.

Doświadczałem tego samego problemu i nalegam na używanie frame w całej mojej aplikacji. Nie chcę robić wyjątku dla kontrolera widoku głównego. Zauważyłem, że kontroler widoku głównego frame wyświetlał wymiary pionowe, , ale wszystkie podwidywa miały prawidłowe wymiary poziome .

Ponieważ tylko kontroler widoku głównego zachowuje się inaczej, możemy ustawić standardowy, pusty kontroler widoku jako kontroler widoku głównego i dodać nasz Niestandardowy kontroler widoku do tego. (Kod poniżej.)

Możesz następnie użyć frame w swoim niestandardowym kontrolerze widoku.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.

    self.window.rootViewController = [[UIViewController alloc] init];

    [self.window makeKeyAndVisible];

    self.viewController = [[ViewController alloc] initWithNibName:nil bundle:nil];
    [self.window.rootViewController addChildViewController:self.viewController];
    [self.window.rootViewController.view addSubview:self.viewController.view];

    return YES;
}
 2
Author: Timo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-19 11:14:56