IOS7: UIScrollView-Offset in UINavigationController

126

Ich migriere derzeit meine App auf iOS 7 und bin stundenlang mit dem neuen Navigationscontroller / Bar-Management beschäftigt.

Früher, als wir einen Navigationscontroller hatten, hatten wir einen Ausschnitt wie diesen:

UINavigationController *navController = [[UINavigationController alloc]initWithRootViewController:[[MainViewController alloc]init]];

Im Interface Builder hatten wir die Wahl, eine vorhandene Navigationsleiste für die Ansicht festzulegen, und alles entspricht dem Inhalt der realen Ansicht.

OK, jetzt habe ich keine Ahnung, wie ich mit dem Interface Builder richtig entwerfen soll. Ich habe immer noch mein Snippet, um meinen Navcontroller zu initialisieren. Wenn ich jedoch im Interface Builder für meinen MainViewController eine Statusleiste auf eine durchscheinende oder undurchsichtige Navigationsleiste setze, habe ich oben einen Versatz von 44 Pixel (siehe unten).


Interface Builder_________________________Und das Ergebnis


Wenn ich nun die Statusleiste auf keine setze, gibt es oben keinen Versatz, aber da die Ansicht im Simulator aufgrund der Navigationsleiste kleiner ist, wird der untere Rand der Ansicht im Interface Builder abgeschnitten.

Interface Builder_________________________Und das Ergebnis

Ich denke, ich vermisse hier wirklich etwas, aber ich kann kein Thema oder Apple-Informationen im iOS7 Transitions Guide dazu finden.

Danke für Ihre Hilfe


BEARBEITEN

Wie wir auf den Bildern sehen können, ist das erste untergeordnete Element der Ansicht eine UIScrollView, die beide Beschriftungen enthält. Das Problem tritt nicht auf, wenn keine Bildlaufansicht vorhanden ist. Es wird auch angezeigt, wenn es sich um eine UITableView handelt. Befindet sich eine Beschriftung außerhalb von UIScrollView, gibt es keinen Versatz zu dieser Beschriftung.

Streem
quelle
Sie können Autolayout verwenden, wenn Sie dies nicht tun, damit Sie sicherstellen können, dass bestimmte Ansichten einen festgelegten Abstand von der Ober- / Unterseite / Seite des Bildschirms haben
erdekhayser
Ich verwende zwar kein Autolayout, aber wenn Sie es verwenden (Aktivieren des Kontrollkästchens), wird das Problem nicht gelöst.
Streem
Bei Autolayout müssen Sie Einschränkungen festlegen, damit die Ansichten erhalten bleiben. Xcode weiß nicht automatisch, was Sie wollen.
Erdekhayser
Als ich Ihre vorherige Bearbeitung sah, habe ich gerade Ihr Problem entdeckt. Leider ist es nicht die naheliegendste Lösung. Anstatt zu versuchen, alles noch einmal zu erklären, habe ich dieses Video auf Youtube verwendet, um zu lernen, wie man Bildlaufansichten einrichtet. youtube.com/watch?v=PgeNPRBrB18&feature=youtu.be Viel Glück. Ich habe ein paar Mal gebraucht, um zu sehen, was er tut.
Erdekhayser

Antworten:

286

OK, also habe ich die Lösung gefunden, ich habe in meinem Controller die Eigenschaft festgelegt:

self.automaticallyAdjustsScrollViewInsets = false

Ich verstehe den wahren Nutzen dieser Eigenschaft jedoch nicht wirklich (oder warum der Standardwert wahr ist).

Die einzige Dokumentation, die ich gefunden habe, war dort:

Aktualisieren

In iOS 11 automaticallyAdjustsScrollViewInsetsist veraltet

Sie sollten jetzt verwenden:

self.tableView.contentInsetAdjustmentBehavior = .never

Ich empfehle Ihnen auch, diese Frage und ihre Antwort zu überprüfen , um ein besseres Verständnis dieser Eigenschaften zu erhalten

Streem
quelle
12
Toller Fund. UIScrollView im Storyboard ist wirklich kompliziert. Ich wünschte, Apple macht es in zukünftigen Versionen von Xcode ein bisschen nahtlos.
p0lAris
4
Dieser Code verhindert, dass ich UIScrollViewscrolle. Aber ohne das kann ich den Offset nicht loswerden. Weired ...
Scaryguy
9
Dieses Flag kann auch in Ihrem Storyboard / Ihrer Feder deaktiviert werden. Der View Controller verfügt über ein Kontrollkästchen "Scroll View Insets anpassen". Ich habe meinen Kopf schon so lange gegen eine Wand geschlagen und versucht, meine Probleme mit Bildlaufansichten und automatischem Layout zu lösen. Dies wird durch die Unterstützung von iOS 6 und 7 noch komplizierter. Vielen Dank, dass Sie endlich eine Lösung gefunden haben!
Newtz
2
Das App-Dokument würde Ihnen sagen, dass das Setzen von navigationbar.translucent = YES verhindern würde, dass die Navigationsleiste den Inhalt nach unten drückt. Es ist die größte Lüge und hat mich bis zu diesem Beitrag viele Stunden Arbeit gekostet. Darüber hinaus müssen Sie self.automaticallyAdjustsScrollViewInsets = NO festlegen. Vielen Dank für diesen Beitrag !!!!!!! Apfel und Apfel?
user779764
Ich stellte fest, dass sich dadurch die Grenzen meines UIScrollView um die Höhe der Navigationsleiste (-64 Punkte) verschoben. Ich habe dies manuell auf 0 überschrieben, aber festgestellt, dass UISrollView immer noch in der y-Achse scrollen und bei -64 an einer imaginären Linie "fangen" würde. Ihre Lösung hat dies gelöst.
GDBJ
92

@ Justafingers Antwort hat auch für mich wie ein Zauber gewirkt.

Ich wollte nur hinzufügen, dass diese Einstellung auch einfach über den Interface Builder angepasst werden kann.

  1. Wählen Sie Ihren View Controller
  2. Klicken Sie auf die Registerkarte "Attributes Inspector"
  3. Deaktivieren Sie "Bildlaufansichten anpassen".
  4. Genießen!

Geben Sie hier die Bildbeschreibung ein

Myxtic
quelle
Wir haben lange nach dieser Option in den UIScrollView-Eigenschaften gesucht und nicht im View Controller! Vielen Dank!
Dominic Williams
11

Ich bin auf dasselbe Problem gestoßen, habe aber im ViewController im Interface Builder eine ziemlich seltsame Eigenschaft gefunden, die dies für mich verursacht zu haben scheint. Es gibt eine Reihe von Kontrollkästchen "Kanten verlängern". Ich habe den Check "Under Top Bars" entfernt und alles begann für mich richtig zu gestalten.

Ben Nicholas
quelle
Ja, dieser hat bei mir besser funktioniert als "Adjust Scroll View Insets"
Dmytro
2

Wenn automatischAdjustsScrollViewInsets auf YES (Standardeinstellung) gesetzt ist, stimmt die Position der Bildlaufansicht zwischen ios6 und ios7 nicht überein. Um sie konsistent zu machen, müssen Sie diese Einstellung deaktivieren. Ios6 stürzt jedoch ab, wenn es automatisch auf AdjustsScrollViewInsets stößt. Daher müssen Sie entweder eine programmgesteuerte Änderung von automaticAdjustsScrollViewInsets von ios7 abhängig machen oder die Option über das Storyboard / die NIB deaktivieren

dawid
quelle
2

Ich hatte ein ähnliches Problem, nachdem ich einen viewController geschlossen hatte, wurde das contentOffset aus meiner tableView in (0, -64) geändert.

Meine Lösung war etwas seltsam. Ich habe alle anderen Antworten ausprobiert, aber keinen Erfolg gehabt. Das einzige, was mein Problem behoben hat, war das Ändern der tableView-Position im Steuerelementbaum der .xib

Es war das erste Steuerelement in der übergeordneten Ansicht wie folgt:

Vor

Ich habe die tableView direkt nach der ImageView verschoben und es hat funktioniert:

nach dem

Es scheint, dass das Versetzen der Tabellenansicht in die erste Position das Problem verursacht hat und das Verschieben der Tabellenansicht in eine andere Position das Problem behoben hat.

PD Ich verwende weder AutoLayout noch Storyboards

hoffe das kann jemandem helfen!

Chuy47
quelle
Ich habe dieses seltsame Verhalten bemerkt. Ich glaube, die Logik dahinter ist, dass die scrollViewInsets automatisch angepasst werden, wenn eine scrollview das erste untergeordnete Element ist. Andernfalls ist es nicht wirklich sinnvoll, da Ihre Bildlaufansicht wahrscheinlich nicht im Vollbildmodus angezeigt wird.
Streem
1

Ich stehe auch vor diesem Problem.

UIScrollView Die Inhaltsgröße wird vom Betriebssystem wie andere Größen berechnet, deren Ursprung vom Einschränkungssystem bereitgestellt wird. Aus diesem Grund hat das Betriebssystem Zweifel.

So beheben Sie das Problem - Sie sollten die Inhaltsgröße explizit definieren für UIScrollView:

  1. Betten Sie scrollbaren Inhalt in ein UIView(ich benenne ihn in umContentView )
  2. Einschränkungen hinzufügen:

ContentView.Weight = View.Weight und ContentView.Height = View.Height

Geben Sie hier die Bildbeschreibung ein

maslovsa
quelle
0

Es scheint, als würde eine Problemumgehung darin bestehen, die Storyboard-Datei als "iOS 6.1 und früher" anzuzeigen (wählen Sie die Storyboard-Datei-> Dateiinspektor-> Interface Builder-Dokument-> Anzeigen als. Wenn Sie Unteransichten in diesem Modus positionieren, wird der Versatz angezeigt.

Swhitman
quelle
Nun, ich benutze kein Storyboard. Ich bin mir jedoch nicht sicher, ob es sich um ein ios6-zu-ios7-Problem handelt. Das obige Beispiel wurde vollständig mit iOS 7 erstellt. Außerdem habe ich meine Frage bearbeitet. Sie wird (soweit ich weiß) nur mit uiscrollview und uitableview angezeigt.
Streem
Hmm interessant ... Wenn Sie dies untersuchen, können Sie varianten = "6xAndEarlier" oben im XIB im Dokumentelement hinzufügen, da dies der Unterschied ist, wenn Sie das oben erwähnte Bit umdrehen. Und zu Ihrer Information, dieses Problem tritt auch bei uiwebview für mich auf.
Swhitman
0

Vielen Dank für die Lösungen! Ich hatte stundenlang Mühe, das Problem zu lösen. Alles war in Ordnung, wenn keine Navigationsleiste beteiligt war, aber es ging durcheinander, als ich den ViewController in einen NavigationController einbettete.

Ich löste es durch die unchecking Ansicht Insets einstellen Scroll und die Unter Top Bars . Beide befinden sich im Attributinspektor des ViewControllers. Tausend Dank!

Jackson Gan
quelle