Bounds ändert sich automatisch bei UIScrollView mit Inhaltseinfügungen

7

Ich verwende eine UIScrollView als meine Blätteransicht, pagesScrollView . Darin stecke ich einzelne UIScrollViews, die ausschließlich zum Zoomen verwendet werden. In jedem von diesen habe ich eine Ansicht, die das Seitenelement ist, das zoombar sein sollte. All das befindet sich in einem UINavigationController mit einer transparenten Navigationsleiste.

Mein pagesScrollView hat contentInset.top = 64 und bounds.origin.y = -64 (das scheint mir seltsam, aber das ist das, was das System automatisch für mich einstellt), und das funktioniert ganz gut. Mein Bildschirm sieht gut aus!

Nachdem ich pagesScrollView jedoch noch ein kleines bisschen durchgeblättert habe, beginnt% scrollViewWillEndDragging , sobald pagesScrollView aufgerufen wird, eine animierte Änderung von bounds.origin.y = -64 auf bounds.origin.y = 0 , wodurch meine Seitenelemente verdeckt werden mit der Navigationsleiste.

Auf der linken Seite ist, wie es aussieht, wenn es lädt, auf der rechten Seite ist, wie es aussieht, nachdem ich nur ein paar Pixel ziehen und dann loslassen, es rutscht unter der Navigationsleiste (weil die Grenzen.origin.y geht zu 0).

Das Problem ist, dass ich keinen Code habe, der die Grenzen ändert, und ich habe keinen Code in den verschiedenen Scroll-Delegate-Methoden, die irgendetwas tun. Ich habe eine Reihe von Scroll-Delegate-Methoden hinzugefügt und NSLog () hinzugefügt, damit ich herausfinden kann, wann / wo die Änderung stattfindet, aber das passiert nirgendwo in meinem Code.

Also, ich weiß nicht, welchen Code ich Ihnen zeigen kann, damit Sie mir helfen können.

EDIT: Ich habe ein neues Projekt von Grund auf neu erstellt, um alle anderen Variablen zu entfernen. Ich habe einen leeren UIViewController in einen UINavigationController eingefügt. Ich habe eine UIScrollView in meine View die gesamte Größe der Ansicht. Der folgende Code ist das gesamte Projekt.

Es stellt sich heraus, dass das Problem (unten beschrieben) nur dann auftritt, wenn PAGING auf dem UIScrollView aktiviert ist! WTF? :)

Hier ist ein Link zum Herunterladen eines grundlegenden Projekts mit nur wenigen Codezeilen, die das Problem veranschaulichen. Klicken Sie einfach in den Bildlauf und Sie werden sehen, wie er sich verschiebt, wenn sich die Grenzen ändern. Ссылка

Wie kann ich in meiner Scrollview Paging aktiviert haben, ohne dass die Grenzen während des Scrollens und Verschiebens unter der Navigationsleiste ausbrechen?

Es ist möglich, die Navigationsleiste undurchsichtig zu machen, und das Problem wird vermieden, aber das Ideal ist das Standard-Verhalten von iOS7, so dass der Inhalt nach dem Zoomen der Inhaltsansicht unter der Navigationsleiste sein darf und durch den Transluzenz normalerweise.

%Vor%     
Kenny Wyland 06.05.2014, 06:20
quelle

4 Antworten

11

Es ist ein iOS Bug. Ich habe die folgende Unterklasse von UIScrollView erstellt, um ein Protokoll darüber zu erhalten, was mit y im Laufe der Zeit passiert und wer es getan hat:

%Vor%

(und änderte die Ansichtsklasse im Storyboard)

Wenn Sie Ihren Finger loslassen, beginnt eine Methode namens UIScrollView _smoothScrollDisplayLink: mit der Animation der Bildlaufansicht an ihre endgültige Position. Da im zweiten Protokoll kein CAAnimation enthalten ist, verwendet die Bildlaufansicht ihren eigenen Anzeige-Link, um einen eigenen Übergang durchzuführen. Dieser benutzerdefinierte Code scheint den Fehler zu machen, von y = whatever nach y = 0 zu animieren, wobei der Content-Offset nicht berücksichtigt wird.

Als Proof-of-Concept-Hack habe ich den Code folgendermaßen geändert:

%Vor%

Und, nicht überraschend, ging das Problem weg.

Sie möchten wahrscheinlich nicht -64.0f codieren, aber ich würde schließen:

  • es ist ein iOS Bug;
  • umgehen Sie, indem Sie unsinnige Werte über eine Unterklasse von UIScrollView mit einer geeigneten benutzerdefinierten Implementierung von - setContentOffset: .
  • ablehnen

Eine sinnvolle generische Methode könnte darin bestehen, das state von self.panGestureRecognizer zu überprüfen - damit können Sie zwischen Scrolls, für die der Benutzer verantwortlich ist, und anderen Scrolls unterscheiden, ohne auf eine undokumentierte API oder komplizierte Erfassungen von Delegate-Events angewiesen zu sein. Wenn es nötig ist, wird das korrekte contentOffset.y vom aktuellen Wert gespalten, anstatt es hart zu codieren.

    
Tommy 10.05.2014, 00:04
quelle
15

Schalten Sie einfach Scroll View Insets einstellen

aus

    
Misha Vyrko 12.05.2014 11:43
quelle
1

Ich habe Ihr Beispiel unter dem Code in der Datei viewController.m überprüft

%Vor%

Es funktioniert gut ...

    
user3559963 12.05.2014 11:55
quelle
0
  

Meine pagesScrollView hat contentInset.top = 64 und bounds.origin.y = -64 (das scheint mir seltsam, aber das ist das, was das System automatisch für mich festlegt), und das funktioniert gut. Mein Bildschirm sieht gut aus!

Aufgrund von iOS 7 wird contentInset.top bei allen scrollviews auf 64 gesetzt. Fügen Sie diese Codezeile einfach in Ihren View-Controller ein und alles funktioniert wie erwartet:

%Vor%

}

Ich habe Ihr Beispielprojekt überprüft.

    
hsafarya 09.05.2014 15:56
quelle