Pasek stanu i pasek nawigacji pojawiają się nad granicami mojego widoku w systemie iOS 7

Ostatnio pobrałem Xcode 5 DP, aby przetestować moje aplikacje w iOS 7. Pierwszą rzeczą, którą zauważyłem i potwierdziłem, jest to, że granice mojego widoku nie zawsze są zmieniane w celu uwzględnienia paska stanu i paska nawigacji.

W viewDidLayoutSubviews, wypisuję granice widoku:

{{0, 0}, {320, 568}}

Spowoduje to, że moja zawartość pojawi się poniżej paska nawigacji i paska stanu.

Wiem, że sam mógłbym rozliczyć wysokość, zdobywając główną wysokość ekranu, odejmując wysokość paska stanu i wysokość paska nawigacji, ale wydaje się to niepotrzebną dodatkową pracą.

Jak mogę rozwiązać ten problem?

Update:

Znalazłem rozwiązanie tego konkretnego problemu. Ustaw właściwość translucent paska nawigacji na NO:
self.navigationController.navigationBar.translucent = NO;

To naprawi widok z ramki pod paskiem nawigacji i paskiem stanu.

Jednak nie znalazłem poprawki dla Przypadku, Gdy chcesz nawigacji pasek do przezroczystości. Na przykład, przeglądając zdjęcie na pełnym ekranie, chciałbym mieć pasek nawigacyjny półprzezroczysty i widok, który ma być oprawiony pod nim. To działa, ale kiedy przełączam wyświetlanie / ukrywanie paska nawigacyjnego, doświadczyłem jeszcze dziwniejszych wyników. Pierwszy subview (UIScrollView) za każdym razem zmienia swoje granice pochodzenia.

 436
Author: Peter Mortensen, 2013-06-12

20 answers

Można to osiągnąć implementując nową właściwość o nazwie edgesForExtendedLayout w iOS7 SDK. Aby to osiągnąć, dodaj poniższy kod,

if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
        self.edgesForExtendedLayout = UIRectEdgeNone;

Musisz dodać powyższe w swojej metodzie -(void)viewDidLoad.

IOS 7 wprowadza kilka zmian w sposobie układania i dostosowywania wygląd twojego UI . Zmiany w układzie widoku-kontroler, tint kolor i czcionka wpływają na wszystkie obiekty UIKit w aplikacji. W dodanie, ulepszenia interfejsów API rozpoznawania gestów dam ci lepszą kontrola nad interakcjami gestów.

Używanie Kontrolerów Widoku

[20]}w systemie iOS 7 Kontrolery widoku używają układu pełnoekranowego. W tym samym czasie, system iOS 7 zapewnia bardziej szczegółową kontrolę nad sposobem kontrolera widoku przedstawia swoje poglądy. W szczególności koncepcja układu pełnoekranowego został dopracowany tak, aby kontroler widoku określał układ każdego krawędź jego widoku.

Właściwość kontrolera widoku wantsFullScreenLayout jest przestarzała w iOS 7. Jeśli aktualnie podasz wantsFullScreenLayout = NO, widok kontroler może wyświetlać swoją zawartość w nieoczekiwanej lokalizacji ekranu kiedy działa w iOS 7.

Aby dostosować sposób, w jaki kontroler widoku rozkłada swoje widoki, UIViewController zapewnia następujące właściwości:

  • edgesForExtendedLayout

Właściwość edgesForExtendedLayout wykorzystuje typ UIRectEdge, który określa każdą z czterech krawędzi prostokąta, oprócz / align = "left" / Użyj edgesForExtendedLayout, aby określić które krawędzie widoku powinny być rozszerzone, niezależnie od przezroczystości paska. Przez domyślnie wartością tej właściwości jest UIRectEdgeAll.

  • extendedLayoutIncludesOpaqueBars

Jeśli twój projekt wykorzystuje nieprzezroczyste paski, doprecyzuj edgesForExtendedLayout przez również ustawienie właściwości extendedLayoutIncludesOpaqueBars na nie . (Domyślną wartością extendedLayoutIncludesOpaqueBars jest NO.)

  • automaticallyAdjustsScrollViewInsets

If you don 't want a scroll view' s wstawki treści mają być automatycznie adjusted, set automaticallyAdjustsScrollViewInsets to NO . (The domyślną wartością automaticallyAdjustsScrollViewInsets jest YES.)

  • topLayoutGuide, bottomLayoutGuide

Właściwości topLayoutGuide i bottomLayoutGuide wskazują na położenie górnej lub dolnej krawędzi paska w widoku kontrolera widoku. Jeśli paski powinny nakładać się na górną lub dolną część widoku, można użyć Interface Builder, aby ustawić widok względem paska, tworząc ograniczenia w na dole topLayoutGuide lub na górze bottomLayoutGuide. (Jeśli żadne paski nie powinny nakładać się na widok, na dole topLayoutGuide jest tym samym co góra widoku i Góra bottomLayoutGuide jest taki sam jak u dołu widoku.) Zarówno właściwości są leniwie tworzone na żądanie.

Proszę odnieść się, apple doc

 497
Author: Nandha,
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
2015-04-20 14:22:03

Nie musisz obliczać, jak daleko, aby przesunąć wszystko w dół, jest do tego wbudowana nieruchomość. W narzędziu Interface Builder podświetl kontroler widoku, a następnie przejdź do inspektora atrybutów. Tutaj zobaczysz kilka pól wyboru obok słów "Rozszerz krawędzie". Jak widać, na pierwszym zrzucie ekranu domyślnym wyborem jest wyświetlanie zawartości pod paskami u góry i u dołu, ale nie pod nieprzezroczystymi paskami, dlatego ustawienie stylu paska na nieprzezroczysty zadziałało ty.

Jak widać na pierwszym zrzucie ekranu, pod paskiem nawigacyjnym znajdują się dwa elementy interfejsu użytkownika. (Włączyłem wireframes w IB, aby to zilustrować) te elementy, UIButton i UISegmentedControl mają pochodzenie " y " ustawione na zero, a kontroler widoku jest ustawiony na zezwalanie na zawartość poniżej górnego paska.

Tutaj wpisz opis obrazka

Ten drugi zrzut ekranu pokazuje, co się dzieje, gdy odznaczysz pole wyboru "pod górnym paskiem". Jak widać, Kontrolery widoku został odpowiednio przesunięty w dół, aby jego pochodzenie y znajdowało się tuż pod paskiem nawigacyjnym.

Tutaj wpisz opis obrazka

Można to również osiągnąć programowo za pomocą -[UIViewController edgesForExtendedLayout]. Oto link do referencji klasy dla edgeForExtendedLayout , oraz dla UIRectEdge

[self setEdgesForExtendedLayout:UIRectEdgeNone];
 111
Author: Mick MacCallum,
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-09-13 12:14:34

Stworzyłem swój widok programowo i skończyło się na tym, że mi się udało:

- (void) viewDidLayoutSubviews {
    // only works for iOS 7+
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
        CGRect viewBounds = self.view.bounds;
        CGFloat topBarOffset = self.topLayoutGuide.length;

        // snaps the view under the status bar (iOS 6 style)
        viewBounds.origin.y = topBarOffset * -1;

        // shrink the bounds of your view to compensate for the offset
        viewBounds.size.height = viewBounds.size.height + (topBarOffset * -1);
        self.view.bounds = viewBounds;
    }
}

Źródło (w sekcji topLayoutGuide na dole str.39).

 33
Author: Stunner,
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
2014-01-03 22:48:26

Rozwiązanie Swift 3 / Swift 4, które działa również z plikami NIBs / XIB w systemie iOS 10+:

override func viewDidLoad() {
    super.viewDidLoad()

    edgesForExtendedLayout = []
}
 30
Author: flo_23,
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
2018-02-27 12:31:12

Jeśli chcesz, aby Widok miał półprzezroczysty pasek nav (co jest dość miłe), musisz skonfigurować contentInset lub podobny.

Oto Jak to robię:

// Check if we are running on ios7
if([[[[UIDevice currentDevice] systemVersion] componentsSeparatedByString:@"."][0] intValue] >= 7) {
      CGRect statusBarViewRect = [[UIApplication sharedApplication] statusBarFrame];
      float heightPadding = statusBarViewRect.size.height+self.navigationController.navigationBar.frame.size.height;

      myContentView.contentInset = UIEdgeInsetsMake(heightPadding, 0.0, 0.0, 0.0);
}
 10
Author: Magnus,
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-09-13 09:16:08

edgesForExtendedLayout robi sztuczkę dla iOS 7. Jeśli jednak zbudujesz aplikację na zestawie SDK iOS 7 i wdrożysz ją w systemie iOS 6, pasek nawigacji będzie przezroczysty, a widoki będą się pod nim znajdować. Tak więc, aby naprawić to zarówno dla iOS 7, jak i dla iOS 6, zrób to: {]}

self.navigationController.navigationBar.barStyle = UIBarStyleBlackOpaque;
if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
    self.edgesForExtendedLayout = UIRectEdgeNone;   // iOS 7 specific
 9
Author: Raj Pawan Gumdal,
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-09-21 05:18:57

W pliku plist aplikacji Dodaj wiersz, nazwij go "wyświetl wygląd paska stanu opartego na kontrolerze" i ustaw go na NO.

 9
Author: Idan,
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
2014-01-03 21:29:18

Najprostszą sztuczką jest otwarcie pliku stalówka i wykonanie tych dwóch prostych kroków:

  1. Po prostu przełącz to i ustaw na to, co wolisz:

Tutaj wpisz opis obrazka

  1. Wybierz te UIView 's/UIIMageView' s/... że chcesz być przeniesiony w dół. W moim przypadku tylko logo nakładało się na siebie i ustawiłem delta na + 15; (lub -15, jeśli wybrałeś iOS 7 w kroku 1)

Tutaj wpisz opis obrazka

I wynik :

PrzedPo

 7
Author: Riskov,
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
2014-01-07 10:21:52

Szybkie Rozwiązanie:

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    self.edgesForExtendedLayout = UIRectEdge.None
}
 5
Author: fatihyildizhan,
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
2018-08-16 13:50:17

Chciałbym rozszerzyć odpowiedź Stunnera i dodać oświadczenie if, aby sprawdzić, czy jest to iOS-7, ponieważ gdy testowałem go na iOS 6 moja aplikacja się zawiesi.

Dodaniem byłoby dodanie:

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)

Więc sugerowałbym dodanie tej metody do pliku MyViewControler.m:

- (void) viewDidLayoutSubviews {
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
        CGRect viewBounds = self.view.bounds;
        CGFloat topBarOffset = self.topLayoutGuide.length;
        viewBounds.origin.y = topBarOffset * -1;
        self.view.bounds = viewBounds;
    }
}
 4
Author: werdsackjon,
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
2014-01-03 21:39:31

Swift 3

override func viewWillAppear(_ animated: Bool) {
    self.edgesForExtendedLayout = []
}
 4
Author: Shahrukh,
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
2017-07-04 07:27:21

Mam scenariusz, w którym używam BannerViewController napisanego przez Apple do wyświetlania moich reklam i scrollviewcontroller wbudowany w BannerViewController.

Aby zapobiec ukrywaniu mojej zawartości przez pasek nawigacyjny, musiałem wprowadzić dwie zmiany.

1) Zmodyfikuj BannerViewController.m

- (void)viewDidLoad
{
   [super viewDidLoad];
   float systemVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
   if (systemVersion >= 7.0) {
      self.edgesForExtendedLayout = UIRectEdgeNone;
   }
}

2) Modify my ScrollViewContoller

- (void)viewDidLoad
{
    [super viewDidLoad];
    float systemVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
    if (systemVersion >= 7.0) {
        self.edgesForExtendedLayout = UIRectEdgeBottom;
    }
}

Teraz reklamy wyświetlają się poprawnie u dołu widoku, zamiast być zasłonięte przez pasek nawigacyjny i zawartość na górze nie jest odcięta.

 3
Author: Xavier John,
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-10-21 16:35:20

Wystarczy ustawić następujący kod w widoku pojawi się.

  if ([[[UIDevice currentDevice] systemVersion] floatValue]<= 7) {
self.edgesForExtendedLayout = UIRectEdgeNone;
 }
 2
Author: Amit Shelgaonkar,
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
2015-06-30 17:57:56

Zrób taki układ na górze Tutaj wpisz opis obrazka

 2
Author: carmen_munich,
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
2015-09-10 09:00:04

Swift 4.2 - Xcode 10.0 - iOS 12.0:

if #available(iOS 11.0, *) {} else {
  self.edgesForExtendedLayout = []
  self.navigationController?.view.backgroundColor = .white
}
 2
Author: juliancadi,
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
2018-08-25 12:18:23

Dla mnie najprostszym rozwiązaniem jest dodanie dwóch kluczy do plist

Tutaj wpisz opis obrazka

 1
Author: gdm,
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-10-03 10:28:36

Dodaj klucz "View controller-based status bar appearance" z listy rozwijanej jako wiersz w info.plist. Coś takiego:

Tutaj wpisz opis obrazka

 1
Author: alex,
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
2014-01-03 21:36:09

Miałem ten sam problem z moją aplikacją przez iPady (armv7, armv7s, amr64) tylko prezentując inny kontroler UIViewController i po ich zwolnieniu przechodzi nav bar pod paskiem stanu... Spędzam dużo czasu, aby znaleźć jakieś rozwiązanie. Używam storyboard i InterfaceBuilder dla UIViewController co sprawia, że straszne ustawiam prezentację z FullScreen - > bieżący kontekst i to rozwiązać ten problem. Działa w mojej aplikacji tylko dla ipadów => iOS8.0 (testowanie z iOS8.1) i dla iPadów z iOS 7.1 nie działa!! zobacz zrzut ekranu

 1
Author: Alexej W.,
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
2015-01-30 10:00:11

Kroki ukrywania paska stanu w systemie iOS 7:

1.Przejdź do informacji o aplikacji.plik plist.

2.I ustaw, wyświetl wygląd paska stanu opartego na kontrolerze: Boolean NO

Mam nadzieję, że rozwiązałem problem z paskiem stanu.....

 0
Author: chandrika,
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
2014-01-30 11:46:13

W moim przypadku po przerwaniu loadView ()
kod ten: siebie.edgesForExtendedLayout = UIRectEdgeNone

Ale po usunięciu loadView () wszystko działało dobrze

 0
Author: DevB2F,
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
2017-03-01 05:10:32