2008-12-07 8 views
187

Ich suche eine perspektivische Transformation auf einer UIView (wie in coverflow)Wie kann ich eine perspektivische Transformation auf eine UIView anwenden?

Weiß jemand, ob das möglich ist?

Ich habe mit CALayer untersucht und habe alle pragmatischen Programmierer Core Animation Podcasts durchlaufen, aber ich bin immer noch nicht klar, wie diese Art von Transformation auf einem iPhone zu erstellen.

Jede Hilfe, Zeiger oder Beispielcodeausschnitte würde wirklich geschätzt werden!

+0

Ich bin nicht sicher, ob dies für u geeignet ist oder nicht aber wenn ich Animation machen, fand ich m14 für mich besser ist Gerade als Referenz :) – b123400

+0

Vielen Dank! - Welche Werte gibst du? –

+0

Ich setze es auf -1/900; – b123400

Antwort

318

Wie Ben schon gesagt hat, müssen Sie mit der UIView-Ebene arbeiten, indem Sie mit CATransform3D die Drehung der Ebene durchführen. Der Trick, um eine Perspektive zu erhalten, wie described here, ist der direkte Zugriff auf eine der Matrixzellen des CATransform3D (m34). Matrix Mathe war nie mein Ding, also kann ich nicht genau erklären, warum das funktioniert, aber es funktioniert. Sie müssen diesen Wert für Ihre anfängliche Transformation auf einen negativen Bruch setzen und dann die Transformation der Ebenenrotation auf diese anwenden. Sie sollten auch in der Lage sein, Folgendes zu tun:

UIView *myView = [[self subviews] objectAtIndex:0]; 
CALayer *layer = myView.layer; 
CATransform3D rotationAndPerspectiveTransform = CATransform3DIdentity; 
rotationAndPerspectiveTransform.m34 = 1.0/-500; 
rotationAndPerspectiveTransform = CATransform3DRotate(rotationAndPerspectiveTransform, 45.0f * M_PI/180.0f, 0.0f, 1.0f, 0.0f); 
layer.transform = rotationAndPerspectiveTransform; 

, die die Layer-Transformation für jede Umdrehung von Grund auf neu erstellt.

Ein vollständiges Beispiel (mit Code) finden Sie here, wo ich Touch-basierte Rotation und Skalierung auf ein paar CALayers, basierend auf einem Beispiel von Bill Dudney implementiert habe. Die neueste Version des Programms, ganz unten auf der Seite, implementiert diese Art von perspektivischer Operation. Der Code sollte relativ einfach zu lesen sein.

Die SublayerTransformation, auf die Sie in Ihrer Antwort verweisen, ist eine Transformation, die auf die Sublayer Ihrer UIViews CALayer angewendet wird. Wenn Sie keine Unterschichten haben, machen Sie sich keine Sorgen. Ich benutze die sublayerTransform in meinem Beispiel, einfach weil es zwei CALayers in der einen Ebene gibt, die ich rotiere.

+1

Dank Brad - du bist ein Star. PS: Sorry für das späte Ticken Ihrer ausgezeichneten Antwort! Nick. –

+0

Das funktioniert schön für mich, außer ich verliere die Hälfte meines Bildes (entlang einer vertikalen Teilung) - manchmal LHS, manchmal RHS. – iPadDeveloper2011

+16

@ iPadDeveloper2011 - Odds sind, Sie versuchen, eine Ansicht oder eine Ebene zu drehen, wenn es eine andere undurchsichtige Ansicht oder Ebene auf der gleichen Ebene Die Hälfte Ihrer Ansicht oder Ebene, die vom Bildschirm weg projiziert wird, würde dann unter dieser anderen Ansicht liegen und somit ausgeblendet sein Sie können entweder Ihre Ansichtshierarchie neu anordnen, um dies zu verhindern, oder die zPosition-Eigenschaft verwenden Vordergrundblick hoch genug über dem, der es abschneidet –

7

Sie können nur Core-Grafiken (nur Quartz, 2D) verwenden, die direkt auf die Transform-Eigenschaft einer UIView angewendet werden. Um die Effekte in Coverflow zu erhalten, müssen Sie CATransform3D verwenden, die in 3D-Raum angewendet werden und Ihnen so die gewünschte perspektivische Ansicht geben können. Sie können CATransform3Ds nur auf Ebenen und nicht auf Ansichten anwenden. Sie müssen daher zu Ebenen wechseln.

Sehen Sie sich das Beispiel "CovertFlow" an, das mit Xcode geliefert wird. Es ist Mac-only (dh nicht für iPhone), aber viele der Konzepte übertragen sich gut.

+0

Ich suche dieses Coverflow Sample in/Developer/Examples, ohne Erfolg, wo findest du es? – Alex

+0

Es ist tatsächlich "CovertFlow", und es ist in/Entwickler/Beispiele/Quartz/Core Animation/" –

13

Ein sehr, sehr guter Artikel über CALayer 3D-Transformation und Perspektive, eine ausführliche Erklärung des m34 Feld darunter können in diesem ausgezeichneten Artikel:

core-animation-3d-model

+1

+1 Dies erklärt die mysteriöse Eigenschaft m34 im Detail. – bentford

+2

Das ist jetzt ein 404. – zoul

+0

Oh, wie schade. Dies ist der Link zur zwischengespeicherten Seite: http://webcache.googleusercontent.com/search?q=cache:kkpWfR6PETkJ:milen.me/technical/core-animation-3d-model/+&cd=1&hl=de&ct=clnk&gl= de – Markus

2

zu Brad Antwort hinzuzufügen und zu ein konkretes Beispiel liefern, leihe ich mir aus my own answer in einem anderen Beitrag zu einem ähnlichen Thema. In meiner Antwort habe ich einen einfachen Swift-Spielplatz erstellt, den Sie können download and play with, wo ich demonstriere, wie man Perspektiveneffekte eines UIView mit einer einfachen Hierarchie von Ebenen erstellen, und ich zeige verschiedene Ergebnisse zwischen transform und . Hör zu.

Hier einige der Bilder der Post:

.sublayerTransform option

.transform option

0

Sie genauen Carousel Effekt iCarousel SDK erhalten kann.

Sie können einen sofortigen Cover Flow-Effekt auf iOS mit der wunderbaren und kostenlosen iCarousel-Bibliothek erhalten. Sie können es von https://github.com/nicklockwood/iCarousel herunterladen und es ziemlich einfach in Ihr Xcode-Projekt einfügen, indem Sie einen Bridging-Header hinzufügen (in Objective-C geschrieben).

Wenn Sie nicht Objective-C-Code zu einem Swift-Projekt vor hinzugefügt haben, gehen Sie folgendermaßen vor:

  • Herunterladen iCarousel und entpacken Sie es
  • in den Ordner gehen Sie entpackt, öffnen Sie seine iCarousel Unterordner, Wählen Sie dann iCarousel.h und iCarousel.m und ziehen Sie sie in Ihre Projektnavigation - das ist der linke Bereich in Xcode. Direkt unter Info.plist ist in Ordnung.
  • Aktivieren Sie "Elemente bei Bedarf kopieren" und klicken Sie auf "Fertig stellen".
  • Xcode wird Sie mit der Nachricht "Möchten Sie einen Objective-C-Bridging-Header konfigurieren?" Klicken Sie auf "Create Bridging Header" Sie sollten eine neue Datei in Ihrem Projekt namens YourProjectName-Bridging-Header.h sehen.
  • Fügen Sie diese Zeile zu der Datei hinzu: #import "iCarousel.h"
  • Sobald Sie iCarousel zu Ihrem Projekt hinzugefügt haben, können Sie es verwenden.
  • Stellen Sie sicher, dass Sie den Protokollen iCarouselDelegate und iCarouselDataSource entsprechen.

Swift 3 Beispielcode:

override func viewDidLoad() { 
     super.viewDidLoad() 
     let carousel = iCarousel(frame: CGRect(x: 0, y: 0, width: 300, height: 200)) 
     carousel.dataSource = self 
     carousel.type = .coverFlow 
     view.addSubview(carousel) 
    } 

    func numberOfItems(in carousel: iCarousel) -> Int { 
     return 10 
    } 

    func carousel(_ carousel: iCarousel, viewForItemAt index: Int, reusing view: UIView?) -> UIView { 
     let imageView: UIImageView 

     if view != nil { 
      imageView = view as! UIImageView 
     } else { 
      imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 128, height: 128)) 
     } 

     imageView.image = UIImage(named: "example") 

     return imageView 
    }