iOS 7 - Pasek stanu nakłada się na widok


109

Mam, ViewControllerktóry jest wewnątrz a UINavigationcontroller, ale pasek nawigacji jest ukryty. Kiedy uruchamiam aplikację na iOS 7, pasek stanu pojawia się u góry mojego widoku. Czy jest sposób, aby tego uniknąć?

Nie chcę pisać żadnego kodu specyficznego dla systemu operacyjnego.

Tutaj wprowadź opis obrazu

Próbowałem ustawienie View controller-based status bar appearancesię NO, ale to nie rozwiąże problemu.


Opublikowałem swoją odpowiedź, aby wyświetlić pasek stanu, taki jak iOS 6, w iOS 7 stackoverflow.com/questions/18294872/…
— Desert Rose

2
Aby rozwiązać problem z paskiem stanu, musisz również dostosować wartość początkową i delta Y. Może to pomóc w stackoverflow.com/q/18980925/1545180
— Ganapathy

Odpowiedzi:


95

Xcode 5 ma iOS 6/7 Deltasspecjalnie stworzony do rozwiązania tego problemu. W scenorysie przeniosłem moje widoki o 20 pikseli w dół, aby wyglądały dobrze na iOS 7 i aby był kompatybilny z iOS 6, zmieniłem Delta yna -20.

wprowadź opis obrazu tutaj

Ponieważ moja storyboard nie korzysta z automatycznego układu, w celu zmiany rozmiaru wysokość poglądów prawidłowo na iOS 6 musiałem ustawić Delta heightjak również Delta Y.


8
Twoja odpowiedź jest prawidłowa, ale nie działa z wyświetlaczem 4 ". Zaktualizuj swoją odpowiedź, jeśli możesz sprawić, by działała również na wyświetlaczu 4". Z góry dziękuję.

2
@AnkitMehta Nie musiałem robić nic konkretnego dla 4
— calowych iPhone'ów

5
pracował dla mnie. Zauważ, że aby zobaczyć te delty, musisz odznaczyć opcję „Użyj automatycznego układu” w obszarze „Tożsamość i typ” dla scenorysu.
— marsant

2
Dowiedziałem się, że oprócz ustawienia -20 dla ∆Y, musiałem również ustawić +20 na ∆Height
— Toland Hon.

3
Co się stanie, gdy zmieni się wysokość paska stanu? Np .: kiedy użytkownik aktywuje hot-spot, itp .... wtedy wysokość 40px ...
— Łukasz

69

Jeśli po prostu NIE chcesz żadnego paska stanu, musisz zaktualizować plist o te dane: Aby to zrobić, w pliku plist dodaj te 2 ustawienia:

<key>UIStatusBarHidden</key>
<true/>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>

W systemie iOS 7 oczekuje się, że projekt aplikacji zostanie zaprojektowany z uwzględnieniem nałożonego przezroczystego paska stanu. Zobacz na przykład nową aplikację Pogoda na iOS 7.


3
Jest to właściwie jedyna dobra odpowiedź, ponieważ rozwiązuje problem u jego podstaw w sposób, w jaki miał być zrobiony. A więc: potrzebne głosy za!
— jedenaście59

5
Może to być odpowiednie w niektórych sytuacjach, ale chcesz bardzo ostrożnie ukrywać pasek stanu. Tylko w przypadku widoków pełnoekranowych, takich jak odtwarzacze multimedialne lub przeglądarki obrazów.
— smileBot

1
@ eleven59, masz na myśli sposób, w jaki zamierzają autokraci w Apple.
— JohnK

1
Zdecydowanie lepiej niż zmiana przesunięcia kontrolera widoku (który jest naprawdę brudny).
— Benjamin Oman

ukrywanie paska statusu nie jest dobrym pomysłem ... Wiem, że to najłatwiejszy sposób obsługi iOS 7, ale czas jest POTRZEBNY ...
— Fahim Parkar

43

Jest to domyślne zachowanie UIViewControllerw systemie iOS 7. Widok będzie pełnoekranowy, co oznacza, że ​​pasek stanu będzie zakrywał górną część widoku.

Jeśli masz UIViewControllerwewnątrz a, UINavigationControllera navigationBar jest widoczny, możesz mieć następujący kod w swoim viewDidLoadlub mieć obraz tła dla navigationBar.

self.edgesForExtendedLayout = UIRectEdgeNone;

Jeśli masz ukryty NavigationBar, musisz dostosować wszystkie elementy UIView, przesuwając o 20 punktów. Nie widzę innego rozwiązania. Użyj układu automatycznego, aby trochę pomóc.

Oto przykładowy kod do wykrywania wersji systemu iOS, jeśli chcesz zachować zgodność z poprzednimi wersjami.

NSUInteger DeviceSystemMajorVersion() {
    static NSUInteger _deviceSystemMajorVersion = -1;
    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{
        NSString *systemVersion = [UIDevice currentDevice].systemVersion;
        _deviceSystemMajorVersion = [[systemVersion componentsSeparatedByString:@"."][0] intValue];
    });

   return _deviceSystemMajorVersion;
}

18
Zamiast pobierać, analizować i porównywać wersję systemu, zaleca się użycieif ([self respondsToSelector:@selector(edgesForExtendedLayout)])
— Sebastian Hojas

15

Jedyne działające rozwiązanie, które stworzyłem samodzielnie.

Oto moja podklasa UIViewController https://github.com/comonitos/ios7_overlaping

1 Podklasa z UIViewController

2 Utwórz podklasę window.rootViewController z tej klasy.

3 Voila!

- (void) viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
        CGRect screen = [[UIScreen mainScreen] bounds];
        if (self.navigationController) {
            CGRect frame = self.navigationController.view.frame;
            frame.origin.y = 20;
            frame.size.height = screen.size.height - 20;
            self.navigationController.view.frame = frame;
        } else {
            if ([self respondsToSelector: @selector(containerView)]) {
                UIView *containerView = (UIView *)[self performSelector: @selector(containerView)];

                CGRect frame = containerView.frame;
                frame.origin.y = 20;
                frame.size.height = screen.size.height - 20;
                containerView.frame = frame;
            } else {
                CGRect frame = self.view.frame;
                frame.origin.y = 20;
                frame.size.height = screen.size.height - 20;
                self.view.frame = frame;
            }
        }
    }
}

4 Dodaj to, aby pasek stanu był biały Zaraz po [self.window makeKeyAndVisible]; !!!

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
}

ale to nie pokazuje czasu na górze ... Największa wada ... :(
— Fahim Parkar

Działa świetnie, ale w kroku 4 powinieneś użyć preferowanegoStatusBarStyle w kontrolerze widoku, ponieważ setStatusBarStyle jest przestarzały, a jego domyślną akcją jest nic nie robić. stackoverflow.com/a/19014724/1192732
— CpnCrunch,

13
-(UIStatusBarStyle)preferredStatusBarStyle
{
    return UIStatusBarStyleLightContent;
}

-(void)viewWillLayoutSubviews{

 if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) 
  {
    self.view.clipsToBounds = YES;
    CGRect screenRect = [[UIScreen mainScreen] bounds];
    CGFloat screenHeight = 0.0;
    if(UIDeviceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation]))
        screenHeight = screenRect.size.height;
    else
        screenHeight = screenRect.size.width;
    CGRect screenFrame = CGRectMake(0, 20, self.view.frame.size.width,screenHeight-20);
    CGRect viewFrame1 = [self.view convertRect:self.view.frame toView:nil];
    if (!CGRectEqualToRect(screenFrame, viewFrame1))
    {
        self.view.frame = screenFrame;
        self.view.bounds = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
    }
  }
}

Dodaj klucz w plist --- Wyświetl wygląd paska stanu opartego na kontrolerze: NIE


w razie
— potrzeby

Dzięki, to rozwiązało mój nakładający się problem. Ale wciąż jest jeden problem - Wyświetl wygląd paska stanu opartego na kontrolerze: Myślę, że NIE jest to ukrycie paska stanu. Ale kiedy ustawię go na TAK, to nie wyświetla paska stanu, a kiedy ustawię go na NIE, pokazuje pasek stanu. Więc proszę, powiedz mi, czy mylę się z koncepcją, czy co?
— Nayan,

1
Myślę, ponieważ weź domyślny półprzezroczysty kolor ustawiony w didFinishLaunchingWithOptions 'self.window.backgroundColor = [UIColor blueColor];' i ustaw w plist Wyświetl wygląd paska stanu na podstawie kontrolera TAK
— Darshit Shah

Fajnie dzięki! Ponadto wystarczy zaznaczyć, że dokumentacja firmy Apple zaleca sprawdzanie za pomocą if (NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_6_1) {} else {}. Twoje zdrowie!
— Joel Balmer

Dziękuję bardzo. Twój kod jest dla nas bardzo pomocny. Proszę o wyjaśnienie funkcji viewWillLayoutSubviews.
— user3182143

4

Aby ukryć pasek stanu w ios7, wykonaj następujące proste kroki:

W Xcode przejdź do Resourcesfolderu „ ” i otwórz „ (app name)-Info.plist file”.

  • sprawdź View controller based status bar appearanceklucz „ ” i ustaw jego wartość „ NO”
  • sprawdź Status bar is initially hiddenklucz „ ” i ustaw jego wartość „ YES”

Jeśli nie ma tam kluczy, możesz je dodać, wybierając „ information property list” u góry i klikając ikonę +


Przeczytaj wyraźnie pytanie, nie prosił o całkowite ukrycie paska stanu.
— ShayanK

1
@AspersionCast: Zapytał: „Czy jest sposób, aby tego uniknąć?” i jest to jeden ze sposobów uniknięcia tego.
— Mandeep Pasbola


3

Jeśli używasz xibs, bardzo prostą implementacją jest hermetyzacja wszystkich podglądów podrzędnych w widoku kontenera z flagami zmiany rozmiaru (których będziesz już używać do zgodności 3,5 "i 4") , aby hierarchia widoku wyglądała mniej więcej tak

heirarchia xib

a potem viewDidLoadzrób coś takiego:

- (void)viewDidLoad
{
  [super viewDidLoad];
  // initializations
  if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) // only for iOS 7 and above
  {
    CGRect frame = containerView.frame;
    frame.origin.y += 20;
    frame.size.height -= 20;
    containerView.frame = frame;
  }
}

W ten sposób końcówki nie muszą być modyfikowane w celu zapewnienia zgodności z systemem iOS 7. Jeśli masz tło, możesz je trzymać na zewnątrz containerViewi pozwolić, aby obejmowało cały ekran.


3

To wszystko, co jest potrzebne, aby usunąć pasek stanu. wprowadź opis obrazu tutaj


2

W przypadku paska nawigacji:

Pisanie tego kodu:

self.navigationController.navigationBar.translucent = NO;

właśnie załatwił mi sprawę.


1

Odpowiedzi Vincenta na krawędzie ForExtendedLayout zadziałały dla mnie.

Te makra pomagają w określaniu wersji systemu operacyjnego, ułatwiając to

// 7.0 and above 
#define IS_DEVICE_RUNNING_IOS_7_AND_ABOVE() ([[[UIDevice currentDevice] systemVersion] compare:@"7.0" options:NSNumericSearch] != NSOrderedAscending) 

// 6.0, 6.0.x, 6.1, 6.1.x
#define IS_DEVICE_RUNNING_IOS_6_OR_BELOW() ([[[UIDevice currentDevice] systemVersion] compare:@"6.2" options:NSNumericSearch] != NSOrderedDescending) 

dodaj te makra do pliku prefix.pch projektu i możesz uzyskać do nich dostęp w dowolnym miejscu

if(IS_DEVICE_RUNNING_IOS_7_AND_ABOVE())
{
 //some iOS 7 stuff
 self.edgesForExtendedLayout = UIRectEdgeNone;
}

if(IS_DEVICE_RUNNING_IOS_6_OR_BELOW())
{
 // some old iOS stuff
}

1
dla mnie self.edgesForExtendedLayout = UIRectEdgeNone; nie działa ... z jakiegoś powodu?
— Fahim Parkar


0

Jeśli chcesz, aby opcja „Użyj automatycznego układu” była włączona za wszelką cenę, umieść następujący kod w pliku viewdidload.

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) 
{
        self.edgesForExtendedLayout = UIRectEdgeNone;
        self.extendedLayoutIncludesOpaqueBars = NO;
        self.automaticallyAdjustsScrollViewInsets = NO;
}

0

Mój pasek stanu i pasek nawigacji nakładają się na siebie po powrocie z widoku poziomego YTPlayer. Oto moje rozwiązanie po wypróbowaniu wersji @comonitos, ale nie działa na moim iOS 8

- (void)fixNavigationBarPosition {
    if (self.navigationController) {
        CGRect frame = self.navigationController.navigationBar.frame;
        if (frame.origin.y != 20.f) {
            frame.origin.y = 20.f;
            self.navigationController.navigationBar.frame = frame;
        }
    }
}

Po prostu wywołaj tę funkcję, gdy chcesz naprawić pozycję paska nawigacji. Zadzwoniłem na YTPlayerViewDelegate'splayerView:didChangeToState:

- (void)playerView:(YTPlayerView *)playerView didChangeToState:(YTPlayerState)state {
    switch (state) {
        case kYTPlayerStatePaused:
        case kYTPlayerStateEnded:
            [self fixNavigationBarPosition];
            break;
        default:
    }
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.