it-swarm.com.de

Erklären des Unterschieds zwischen automaticAdjustsScrollViewInsets, extendedLayoutIncludesOpaqueBars, edgesForExtendedLayout in iOS7

Ich habe viel über den Übergang zur iOS7-Benutzeroberfläche gelesen.

Ich kann diese drei Eigenschaften nicht bekommen automaticallyAdjustsScrollViewInsets, extendedLayoutIncludesOpaqueBars, edgesForExtendedLayout ??

Zum Beispiel versuche ich, meine Ansichtscontroller unterhalb der Statusleiste zu starten, aber ich kann es nicht erreichen.

243
user1010819

Ab iOS7 verwenden die Ansichtscontroller standardmäßig das Vollbild-Layout. Gleichzeitig haben Sie mehr Kontrolle darüber, wie die Ansichten angeordnet werden. Dies geschieht mit den folgenden Eigenschaften:

edgesForExtendedLayout

Grundsätzlich legen Sie mit dieser Eigenschaft fest, welche Seiten Ihrer Ansicht so erweitert werden können, dass sie den gesamten Bildschirm abdecken. Stellen Sie sich vor, Sie schieben ein UIViewController in ein UINavigationController. Wenn die Ansicht dieses Ansichtscontrollers angelegt ist, beginnt sie dort, wo die Navigationsleiste endet. Mit dieser Eigenschaft wird jedoch festgelegt, welche Seiten der Ansicht (oben, links, unten, rechts) erweitert werden können, um den gesamten Bildschirm auszufüllen.

Schauen wir uns das an einem Beispiel an:

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

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

Das ist das Ergebnis:

without edges for extended layout, the view fills the whole screen

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

Jetzt setzen Sie diesen Wert auf UIRectEdgeNone, damit der Ansichtscontroller die Ansicht nicht so erweitert, dass sie den Bildschirm abdeckt:

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

Und das Ergebnis:

with edgesForExtendedLayout set, the view is just under the navigation


passt automatischScrollViewInsets an

Diese Eigenschaft wird verwendet, wenn Ihre Ansicht ein UIScrollView oder ähnliches ist, wie ein UITableView. Sie möchten, dass Ihre Tabelle dort beginnt, wo die Navigationsleiste endet, da sonst nicht der gesamte Inhalt angezeigt wird. Gleichzeitig möchten Sie, dass Ihre Tabelle beim Scrollen den gesamten Bildschirm einnimmt. In diesem Fall funktioniert das Setzen von edgesForExtendedLayout auf None nicht, da Ihre Tabelle an der Stelle mit dem Bildlauf beginnt, an der die Navigationsleiste endet und nicht dahinter steht.

Hier bietet sich diese Eigenschaft an. Wenn Sie den Ansichtscontroller die Einfügungen automatisch anpassen lassen (diese Eigenschaft auf JA setzen, auch den Standardwert), werden Einfügungen am oberen Rand der Tabelle hinzugefügt, sodass die Tabelle dort beginnt, wo die Navigation stattfindet Die Leiste endet, aber der Bildlauf deckt den gesamten Bildschirm ab.

Dies ist, wenn auf NEIN gesetzt ist:

the table will scroll over the whole screen, but starts out partially covered

Und JA (standardmäßig):

the table scrolls over the whole screen, and starts just under the navigation

In beiden Fällen scrollt die Tabelle hinter der Navigationsleiste, im zweiten Fall (JA) 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, auch wenn Sie die Ansicht so erweitern, dass sie sie abdeckt (edgesForExtendedLayout bis UIRectEdgeAll).

Wenn Sie den Wert auf YES setzen, wird die Ansicht wieder unter die Statusleiste verschoben.

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

Woher weiß iOS, welches UIScrollView verwendet werden soll?

iOS erfasst die erste Unteransicht in der Ansicht Ihres ViewControllers, die mit dem Index 0, und wendet, wenn es sich um eine Unterklasse von UIScrollView handelt, die erläuterten Eigenschaften darauf an.

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

605
Antonio MG

Sie sind sich nicht sicher, ob Sie Storyboards verwenden, aber wenn Sie möchten, dass Ihre Ansichts-Controller unterhalb der Statusleiste (und oberhalb der unteren Leiste) beginnen:

Wählen Sie den Ansichts-Controller in IB aus. Deaktivieren Sie im Attributinspektor die Optionen "Kanten verlängern - Unter oberen Leisten" und "Kanten verlängern - Unter unteren Leisten".

15
Ali Beadle

Ich benutze Storyboards und die obigen Ratschläge haben funktioniert, aber ich war mir nicht ganz sicher, wie ich sie umsetzen sollte. Nachfolgend finden Sie ein kurzes Beispiel in Swift wie das Problem behoben 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 gesetzt, was zu einem Unterschied zwischen Storyboard-Design und Simulator führt Auto Adjust set to true by default causing a difference between storyboard design and simulator

Behoben: Code oben angewendet, automatische Anpassung deaktiviert. Code above applied, turning off the auto-adjust.

Ich habe dieses Problem durch Hinzufügen dieser Zeile gelöst, aber mein Problem hing mit einem UIView zusammen, nicht mit UIScrollView

self.navigationController.navigationBar.translucent = NO;
5
user3430340

Beachten Sie jedoch, dass die automaticallyAdjustsScrollViewInsets -Eigenschaft nur funktioniert, wenn es sich um eine Bildlaufansicht (Tabellenansicht, Sammlungsansicht, ...) handelt

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

Andere schlugen vor, dass dies auch dann funktioniert, wenn es sich um die erste Unteransicht handelt, die Ansichtshierarchie jedoch andere Bildlaufansichten enthält.

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 Bildlaufansichtseinstellungen manuell anpassen. Aber stellen Sie es bitte nicht auf eine Konstante wie 44 oder 64 oder sogar 20 ein, wie es viele in der Umgebung von SO vorschlagen. Sie können die Größe nie kennen. Es kann Incall/GPS/Audio-Benachrichtigung geben, die Navigationsleiste muss nicht immer 44 Punkte enthalten usw.

Ich denke, die beste Lösung ist die Verwendung von layoutGuide length in didLayoutSubviews:

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.

2
Vojta Rujbr