2010-08-21 18 views
12

W mojej aplikacji dostałem UINavigationController. Niestety, po obróceniu urządzenia i zmianie orientacji interfejsu, UINavigationBar nie zmienia swojej wysokości. W innych aplikacjach na iPhone'a, takich jak Contacts.app, pasek nawigacyjny staje się nieco mniejszy w trybie poziomym. Musi być wbudowany, ponieważ jeśli wybierzesz przykładową aplikację nawigacyjną z menu XCode i dodasz do niej orientację interfejsu, zmieni ona odpowiednio wysokość paska nawigacji.UINavigationBar autoreizing

Jak zmienić rozmiar paska nawigacji, tak jak ma to miejsce we wszystkich innych aplikacjach iPhone, które widziałem?

Odpowiedz

19

Zrobiłem mały test, i mimo że nie podoba mi się sposób, jest dość proste do zrobienia.

Po wyszukaniu prywatnej metody, która mogła zadziałać, nie mogłem jej znaleźć. Wszystko znalazłem:

@property BOOL forceFullHeightInLandscape; 

- (BOOL)isMinibar; 

Nie ma setter dla -isMinibar, więc nie możemy ustawić, że. Przypuszczam, że zwraca wartość na podstawie jej wysokości. Również forceFullHeightInLandscape został ustawiony na NO, jednak wciąż nie dostosował swojej wysokości.

Podczas wymiany autoresizingMask zawierać UIViewAutoresizingFlexibleHeight, widok zrobił Resize być mniejsze, ale teraz to było zbyt małe. Jednak -isMinibar nagle zwrócił YES. To sprawiło, że pomyślałem o tym, żeby zmienić rozmiar widoku, dostosowując go do odpowiedniej wysokości.

Więc nie pójdziemy, to metoda, która działa, nawet bez prywatnych rozmów API:

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { 
    [self.navigationBar performSelector:@selector(sizeToFit) withObject:nil afterDelay:(0.5f * duration)]; 
} 

Jedno będziesz mieć do czynienia z to, że poglądy pod poprzeczkę nie dostanie dostosowany do mniejszego paska, tak aby pojawiła się przerwa między paskiem a widokami poniżej. Najprostszym sposobem rozwiązania tego problemu jest dodanie widoku kontenera, podobnie jak w przypadku UINavigationController. Można by wymyślić coś takiego:

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { 
    [self performSelector:@selector(resizeViewsForNavigationBar) withObject:nil afterDelay:(0.5f * duration)]; 
} 

- (void)resizeViewsForNavigationBar { 
    [self.navigationBar sizeToFit]; 

    // Resize containerView accordingly. 
    CGRect containerViewRect = self.containerView.frame; 
    containerViewRect.origin.y = CGRectGetMaxY(self.navigationBar.frame); 
    containerViewRect.size.height = CGRectGetMaxY(self.view.frame) - containerViewRect.origin.y; 
    self.containerView.frame = containerViewRect; 
} 
+0

+1 za doskonałą odpowiedź – vodkhang

+0

Dzięki za odpowiedź, nie mogę tego teraz przetestować, ale odpowiem, gdy spróbuję. Co ciekawe, widok kontenera jest już poprawnie zmieniany, tak jakby pasek nawigacji stał się krótszy, niż powinien. – ryyst

+0

Wypróbowałem to już teraz i działa idealnie! Ponieważ widok kontenera jest już poprawnie zmieniany, potrzebuję tylko wywołania 'sizeToFit'. – ryyst

0

myślę, że ten jest trochę podobny do ciebie i mają fragment kodu:

iPhone: UINavigationBar with buttons - adjust the height

+0

Czy jesteś pewien, że wysokość pasek nawigacyjny kurczy nie jest wbudowany w somehwere? – ryyst

+0

To musi być wbudowane, ponieważ jeśli weźmiesz przykładową aplikację nawigacyjną z menu XCode i dodasz do niej orientację interfejsu, zmieni ona odpowiednio wysokość paska nawigacji. – ryyst

2

myślę zachowanie chcesz tylko się dzieje, gdy kontroler nawigacyjny (który reprezentuje barów (nawigacja lub paska narzędzi)), jest dodawana do okna w app delegata lub prezentowane przez pasek zakładek, itp.

Możesz dodać pasek nawigacyjny przez IB lub kod, to nie znaczy, że masz kontroler nawigacji. Moim zdaniem, stwórz kontroler nawigacyjny i zainicjuj go za pomocą kontrolera widoku, nad którym pracujesz. Prawdopodobnie po obróceniu widoku pasek nawigacji trochę się skurczy, tak jak lubisz.

Nadzieja to pomaga

+0

Dokładnie to zrobiłem i nie, to nie działa. Dzięki za odpowiedź! – ryyst

0

Próbowałem tylko kilka rzeczy tylko w obrębie interfejsu Builder i Xcode i tak długo, jak korzystać z UINavigationBarController jak RootViewController działa zgodnie z opisem - coraz mniejszy. Czy zmieniłeś coś w samym sterowniku lub w częściach tego, jak ładowany jest kontroler? Zwłaszcza w sprawie wypalania wydarzeń? Miałem kilka złych doświadczeń z UITabBarController pod względem zerwania właściwego przesyłania komunikatów i uzyskałem pewne "interesujące" efekty uboczne widoku. Tylko spróbuj i zgadnij.

+0

Cóż, rzeczywiście używam również kontrolera UITabBarController. Poza tym, tworzę wszystko za pomocą kodu, bez Interface Builder. – ryyst

+0

Ah, ok, widząc, że odpowiedź już została udzielona Ciekaw jestem, co jeśli programistycznie użyjesz UITabBar. Czy nadal nie działa? Zakładam, że wszystko jest zawarte w RootViewController. Może to nie jest błąd, ale nie działa poprawnie z dwoma kontrolerami. Jeśli spróbujesz to zrobić za pomocą Konstruktora interfejsu, to i tak nie pójdzie, nie pozwalając na pomylenie kontrolera NavigationBarController z kontrolerem UITabBarController. – mic

1

Po prostu miałem ten błąd, i choć prawdopodobnie nie z tego samego powodu, chciałbym go tutaj zamieścić, aby pomóc komukolwiek innemu, który się zachowuje.

Jeśli nadrzędne żadnych willRotateToInterface metod pamiętać zadzwonić super

I wygaszone na tym, ale kiedyś widziałem zaakceptowane odpowiedź przyszedł do mnie.

2

Dzięki Joost Dodałem

@property BOOL forceFullHeightInLandscape; 

do mojej klasy niestandardowe UINavigationBar. I ustawić w:

-(id)initWithFrame:(CGRect)frame{ 
forceFullHeightInLandscape = YES; 

Pracował jak czar

+0

Możesz również zastąpić to w kategorii UINavigationBar: '- (BOOL) forceFullHeightInLandscape { return YES; } ' –

2

podobne do odpowiedzi Joost, ale wprowadzenie metody w willAnimateRotationToInterfaceOrientation ma lepszy efekt animacji niż willRotateToInterfaceOrientation. (Nie ma opóźnienie animacja)

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { 
    [self.navigationBar sizeToFit]; 
} 
-1
(void)viewWillLayoutSubviews { 
     self.navigationItem.titleView.bounds = self.navigationController.navigationBar.bounds; 
} 
Powiązane problemy