present - Erklären der Unterschied zwischen automaticallyAdjustScrollViewInsets, extendedLayoutIncludesOpaqueBars, edgesForExtendedLayout in iOS7




uiviewcontroller present (4)

Ich habe viel über iOS7 UI-Übergang gelesen.

Ich bin nicht in der Lage zu bekommen, was diese drei Eigenschaften automaticallyAdjustsScrollViewInsets , extendedLayoutIncludesOpaqueBars , edgesForExtendedLayout ??

Zum Beispiel versuche ich, meine View-Controller unterhalb der Statusleiste zu starten, aber ich kann das nicht erreichen.


Ab iOS7 verwenden die View Controller standardmäßig das Vollbild-Layout. Gleichzeitig haben Sie mehr Kontrolle darüber, wie es seine Ansichten auslegt, und zwar mit diesen Eigenschaften:

kitesForExtendedLayout

Mit dieser Eigenschaft legen Sie fest, welche Seiten Ihrer Ansicht auf den gesamten Bildschirm ausgedehnt werden können. Stellen Sie sich vor, dass Sie einen UIViewController in einen UINavigationController . Wenn die Ansicht dieses Ansichtscontrollers angelegt wird, beginnt sie dort, wo die Navigationsleiste endet, aber diese Eigenschaft legt fest, welche Seiten der Ansicht (oben, links, unten, rechts) erweitert werden können, um den gesamten Bildschirm auszufüllen.

Lass es mit einem Beispiel sehen:

UIViewController *viewController = [[UIViewController alloc] init];
viewController.view.backgroundColor = [UIColor redColor];
UINavigationController *mainNavigationController = [[UINavigationController alloc] initWithRootViewController:viewController];

Hier setzen Sie nicht den Wert von edgesForExtendedLayout , daher wird der Standardwert genommen ( UIRectEdgeAll ), sodass die Ansicht ihr Layout so erweitert, dass sie den gesamten Bildschirm ausfüllt.

Dies ist das Ergebnis:

Wie Sie sehen, erstreckt sich der rote Hintergrund hinter der Navigationsleiste und der Statusleiste.

Jetzt werden Sie diesen Wert auf UIRectEdgeNone , sodass Sie dem View-Controller UIRectEdgeNone , dass er die Ansicht nicht auf den Bildschirm UIRectEdgeNone :

UIViewController *viewController = [[UIViewController alloc] init];
viewController.view.backgroundColor = [UIColor redColor];
viewController.edgesForExtendedLayout = UIRectEdgeNone;
UINavigationController *mainNavigationController = [[UINavigationController alloc] initWithRootViewController:viewController];

Und das Ergebnis:

automaticallyAdjustScrollViewInsets

Diese Eigenschaft wird verwendet, wenn Ihre Ansicht eine UIScrollView oder eine ähnliche ist, wie eine UITableView . Sie möchten, dass Ihre Tabelle an der Stelle beginnt, an der die Navigationsleiste endet, weil Sie sonst nicht den gesamten Inhalt sehen, aber gleichzeitig möchten Sie, dass Ihre Tabelle beim Scrollen den gesamten Bildschirm abdeckt. In diesem Fall wird das Festlegen von edgesForExtendedLayout auf None nicht funktionieren, da Ihre Tabelle an der Stelle beginnt, an der die Navigationsleiste endet, und nicht dahinter.

Hier ist diese Eigenschaft nützlich, wenn Sie den View-Controller automatisch die Einstellungen anpassen lassen (indem Sie diese Eigenschaft auf YES setzen, also auch den Standardwert), werden am oberen Rand der Tabelle neue Einträge hinzugefügt, sodass die Tabelle an der Stelle der Navigation beginnt Der Balken endet, aber die Bildlaufleiste deckt den gesamten Bildschirm ab.

Dies ist, wenn auf NEIN eingestellt ist:

Und JA (standardmäßig):

In beiden Fällen scrollt die Tabelle hinter der Navigationsleiste, aber im zweiten Fall (YES) beginnt sie unterhalb der Navigationsleiste.

extendedLayoutIncludesOpaqueBars

Dieser Wert ist nur eine Ergänzung zu den vorherigen. Standardmäßig ist dieser Parameter auf NO eingestellt. Wenn die Statusleiste undurchsichtig ist, werden die Ansichten nicht um die Statusleiste erweitert, selbst wenn Sie Ihre Ansicht erweitern, um sie zu überdecken ( edgesForExtendedLayout zu UIRectEdgeAll ).

Wenn Sie den Wert auf YES setzen, wird die Ansicht wieder unterhalb der Statusleiste angezeigt.

Wenn etwas nicht klar ist, schreibe einen Kommentar und ich werde es beantworten.

Woher weiß iOS, was UIScrollView verwenden soll?

iOS greift die erste Unteransicht in der Ansicht Ihres ViewControllers auf, die in Index 0, und wenn es eine Unterklasse von UIScrollView ist, wendet sie die erklärten Eigenschaften darauf an.

Dies bedeutet natürlich, dass UITableViewController standardmäßig funktioniert (da UITableView die erste Ansicht ist).


Denken Sie nur daran, dass die Eigenschaft automaticallyAdjustsScrollViewInsets anpassenScrollViewInsets nur dann funktioniert, wenn eine Art von Bildlaufansicht (Tabellenansicht, Auflistungsansicht, ...) dies ist

  • Die Ansicht von VC, oder
  • Erste Unteransicht dieser Ansicht

Andere schlagen vor, dass es funktioniert, auch wenn es die erste Unteransicht ist, aber es gibt andere Bildlaufansichten in der Ansichtshierarchie.

EDIT (Erweiterung DIY)

Wenn Sie ein ähnliches Verhalten wünschen, auch wenn Sie diese Bedingungen nicht erfüllen können (z. B. wenn Sie ein Hintergrundbild unterhalb der Bildlaufansicht haben), können Sie die Bildlaufeinstellungen manuell anpassen. Aber setze es nicht konstant auf 44 oder 64 oder 20, wie viele in der Umgebung von SO vermuten lassen. Sie können die Größe nie wissen. Es kann die incall / gps / audio Benachrichtigung geben, die Navigationsleiste muss nicht immer 44 pts usw. sein.

Ich denke, die beste Lösung ist es, die layoutGuide- length in didLayoutSubviews zu verwenden:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    scrollView.contentInset = UIEdgeInsets(top: topLayoutGuide.length, left: 0, bottom: 0, right: 0)
    scrollView.scrollIndicatorInsets = scrollView.contentInset
}

Sie können den bottomLayoutGuide auf die gleiche Weise verwenden.


Ich verwende Storyboards und die oben genannten Ratschläge funktionierten, aber ich wusste nicht genau, wie ich es implementieren sollte. Im Folgenden finden Sie ein kurzes Beispiel dafür, wie das Problem gelöst wurde, indem die empfohlene Lösung in den ViewController eingefügt wurde.

import Foundation
import UIKit

// This ViewController is connected to a view on a storyboard that 
// has a scrolling sub view.
class TheViewController: UIViewController {

  // Prepares the view prior to loading.  Putting it in viewDidAppear didn't work.
  override func viewWillAppear(animated: Bool) {

    // this method is an extension of the UIViewController 
    // so using self works as you might expect.
    self.automaticallyAdjustsScrollViewInsets = false

    // Default is "true" so this sets it to false tells it to use 
    // the storyboard as you have it placed
    // and not how it thinks it should place it.
  }

}

Mein Problem: Auto Adjust ist standardmäßig auf "true" eingestellt, was zu einem Unterschied zwischen Storyboard-Design und Simulator führt

Gelöst: Der Code oben wurde angewendet und die automatische Anpassung wurde deaktiviert.


Nicht sicher, ob Sie Storyboards verwenden, aber wenn dies der Fall ist, werden Ihre View-Controller unterhalb der Statusleiste (und oberhalb der unteren Leiste) gestartet:

Wählen Sie den View-Controller in IB aus. Deaktivieren Sie im Attribute-Inspektor die Option "Kanten verlängern - unter den oberen Balken" und "Kanten verlängern - unter den unteren Balken".





ios7