2017-09-19 3 views
38

Ich begann meine App für iPhone X anzupassen und fand ein Problem in Interface Builder. Die Safe Area Layout Guides sollen laut offizieller Apple Videos rückwärtskompatibel sein. Ich fand, dass es in Storyboards gut funktioniert.Safe-Bereich-Layout-Anleitungen in Xib-Dateien - iOS 10

Aber in meiner XIB-Dateien werden die sicheren Bereich Layout Führungen in iOS 10.

Sie für die neue OS-Version, aber die iOS 10 Geräte scheinen einfach davon ausgehen, den sicheren Bereich Abstand als Null funktionieren nicht respektiert (ignoriert die Größe der Statusleiste).

Fehle ich eine erforderliche Konfiguration? Ist es ein Xcode-Bug und falls ja, irgendwelche bekannten Problemumgehungen?

Hier ist ein Screenshot des Problems in einem Testprojekt (iOS 10, iOS 11 vl):

safe area alignment on top of the screen

Antwort

41

einige Probleme mit sicherem Bereich Layout und Rückwärtskompatibilität Es gibt keine. Siehe meinen Kommentar über here.

Sie können die Probleme möglicherweise mit zusätzlichen Einschränkungen umgehen, wie z. B. 1000 priority> = 20.0 to superview.top und 750 priority == safearea.top. Wenn Sie immer eine Statusleiste anzeigen, sollte das Dinge beheben.

Ein besserer Ansatz könnte sein, separate Storyboards/Xibs für iOS 11 und höher zu haben, vor allem, wenn Sie mehr Probleme haben. Der Grund dafür ist, dass Sie vor iOS 11 Layout-Einschränkungen für die oberen/unteren Layout-Guides festlegen sollten, aber für iOS 11 sollten Sie sie in sichere Bereiche legen. Layout-Anleitungen sind weg. Layout-Anleitungen für Pre-iOS 11 zu erstellen, ist stilistisch besser als nur um 20 Pixel zu verkleinern, obwohl die Ergebnisse die gleiche sein werden wie die IFF, die immer eine Statusleiste anzeigt.

Wenn Sie diesen Ansatz verwenden, müssen Sie jede Datei auf das richtige Bereitstellungsziel festlegen, auf dem sie verwendet wird (iOS 11 oder früher), damit Xcode keine Warnungen gibt und Ihnen dies ermöglicht Verwenden Sie dazu Layout-Anleitungen oder sichere Bereiche. Suchen Sie in Ihrem Code zur Laufzeit nach iOS 11 und laden Sie dann das entsprechende Storyboard/xibs. Der Nachteil dieses Ansatzes besteht in der Wartung (Sie müssen zwei Sätze von View-Controllern verwalten und synchronisieren), aber sobald Ihre App nur iOS 11+ unterstützt oder Apple die Rückwärtskompatibilität bei der Generierung von Layoutrichtlinien korrigiert , können Sie die Versionen vor iOS 11 loswerden.

Übrigens, wie zeigen Sie den Controller an, mit dem Sie dies sehen? Ist es nur der root-View-Controller oder hast du es vorgestellt, oder ..? Das Problem, das mir aufgefallen ist, hat damit zu tun, dass Sie die Ansichts-Controller drücken, so dass Sie möglicherweise einen anderen Fall treffen.

+0

Mein spezifisches Problem ist nur auf XIB-Dateien, und scheint sowohl für geschobene und präsentierte Controller passieren. Ihre Problemumgehung mit mehreren Einschränkungen klingt für die meisten Situationen wie eine gute Lösung. Vielen Dank! Ich hoffe immer noch, dass sie diese Probleme lösen werden, bevor das iPhoneX ankommt. –

+0

Vielen Dank für den Prioritätsvorschlag! Funktioniert nun wie ein Zauber auf iOS 9 und iOS 11 unter iPhone X. –

+0

Darf ich dazu Stellung nehmen: "Wenn du immer eine Statusleiste zeigst, sollte das Dinge regeln."? Ich kann den Weg zur Anzeige der Statusleiste auf dem iPhone X-Simulator in der Landschaft nicht sehen. Dann hätte der beschriebene Workaround von "1000 priority> = 20.0 to superview.top und eine 750 priority == safearea.top" für das iPhone X im Querformat eine Lücke von 20px. Meine Lösung war, die Einschränkung von "1000 Priorität> = 20.0" in der ViewDidLoad zu entfernen, wenn iOS <11. Ich vermisse die Möglichkeit, Statusleiste in iPhone X Landschaft erzwingen? –

-3

die simpliest Lösung gefunden - nur safe area deaktivieren und topLayoutGuide verwenden und bottomLayoutGuide + hinzufügen Fixes für iPhone X. erfordert es ist nicht schön Lösung Vielleicht aber als weniger Aufwand wie möglich

0

ich die Einschränkung sicheren Bereich am Ende Löschen was ich in meiner XIB-Datei hatte. Stattdessen habe ich eine Steckdose zu der fraglichen UIView gemacht, und vom Code habe ich es so in viewDidLayoutSubviews angeschlossen.

let constraint = alert.viewContents.topAnchor.constraint(equalTo: self.topLayoutGuide.bottomAnchor, constant: 0) 
constraint.priority = 998 
constraint.isActive = true 

Dies steht einen kleinen „Alarm“, um oben auf dem Bildschirm, sondern sorgt dafür, dass der Inhalt innerhalb des Alarm sieht immer unterhalb dem oberen sicheren Bereich ist (iOS11ish)/topLayoutGuide (iOS10ish)

Einfach und ein einmalige Lösung. Wenn etwas kaputt geht, bin ich zurück.

1

Gegenwärtig funktioniert die Abwärtskompatibilität nicht gut.

Meine Lösung ist 2 Einschränkungen im Interface Builder zu erstellen und ein Entfernen je nach ios Version Sie verwenden:

  • für ios 11: view.top == safe area.top
  • für frühere Versionen: view.top == superview.top + 20

Fügen Sie sie beide als Ausgänge wie myConstraint bzw. myConstraintIOS10 hinzu. Dann:

override func viewDidLoad() { 
    if #available(iOS 11.0, *) { 
     view.removeConstraint(myConstraintIOS10) 
    } else { 
     view.removeConstraint(myConstraint) 
    } 
}