it-swarm.com.de

Wie wende ich eine Perspektiventransformation auf eine UIView an?

Ich möchte eine Perspektiventransformation für ein UIView durchführen (wie im Coverflow)

Weiß jemand, ob dies möglich ist?

Ich habe mit CALayer nachgeforscht und alle pragmatischen Core Animation-Podcasts des Programmierers durchgearbeitet, bin mir aber immer noch nicht sicher, wie man diese Art von Transformation auf einem iPhone erstellt.

Jede Hilfe, Zeiger oder Beispiel-Code-Schnipsel wäre sehr dankbar!

198
Nick Cartwright

Wie Ben sagte, müssen Sie mit der Ebene UIView's Arbeiten und einen CATransform3D Verwenden, um den Befehl layer'srotation auszuführen. Der Trick, um die Perspektive zum Laufen zu bringen, als hier beschrieben , besteht darin, direkt auf eine der Matrizen cells des CATransform3D (M34) zuzugreifen. . Matrixmathematik war noch nie mein Ding, daher kann ich nicht genau erklären, warum dies funktioniert, aber es funktioniert. Sie müssen diesen Wert für Ihre anfängliche Transformation auf einen negativen Bruch setzen und dann Ihre Ebenendrehungstransformationen darauf anwenden. Sie sollten auch in der Lage sein, Folgendes zu tun:

Ziel-C

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;

Swift 5.0

if let myView = self.subviews.first {
    let layer = myView.layer
    var rotationAndPerspectiveTransform = CATransform3DIdentity
    rotationAndPerspectiveTransform.m34 = 1.0 / -500
    rotationAndPerspectiveTransform = CATransform3DRotate(rotationAndPerspectiveTransform, 45.0 * .pi / 180.0, 0.0, 1.0, 0.0)
    layer.transform = rotationAndPerspectiveTransform
}

dadurch wird die Ebenentransformation für jede Drehung von Grund auf neu erstellt.

Ein vollständiges Beispiel (mit Code) finden Sie unter hier , wo ich bei einigen CALayers eine berührungsbasierte Drehung und Skalierung implementiert habe. basierend auf einem Beispiel von Bill Dudney. Die neueste Version des Programms, ganz unten auf der Seite, implementiert diese Art von perspektivischer Operation. Der Code sollte einigermaßen einfach zu lesen sein.

Das sublayerTransform, auf das Sie sich in Ihrer Antwort beziehen, ist eine Transformation, die auf die Unterebenen Ihres UIView'sCALayer angewendet wird. Wenn Sie keine Unterschichten haben, sorgen Sie sich nicht darum. Ich verwende die Unterebene Transformation in meinem Beispiel einfach, weil in der einen Ebene, die ich drehe, zwei CALayers enthalten sind.

325
Brad Larson

Sie können nur Core Graphics-Transformationen (nur Quarz, 2D) verwenden, die direkt auf die Transformationseigenschaft eines UIView angewendet werden. Um die Effekte im Coverflow zu erzielen, müssen Sie CATransform3D verwenden, die im 3D-Raum angewendet werden. Auf diese Weise erhalten Sie die gewünschte perspektivische Ansicht. Sie können CATransform3Ds nur auf Ebenen anwenden, nicht auf Ansichten. Daher müssen Sie hierfür auf Ebenen wechseln.

Schauen Sie sich das mit Xcode gelieferte Beispiel "CovertFlow" an. Es ist nur für Mac (dh nicht für iPhone), aber viele Konzepte lassen sich gut übertragen.

7
Ben Gottlieb

Um Brad's Antwort zu ergänzen und ein konkretes Beispiel zu geben, leihe ich mir meine eigene Antwort in einem anderen Beitrag zu einem ähnlichen Thema aus. In meiner Antwort habe ich einen einfachen Swift Spielplatz erstellt, auf dem Sie herunterladen und damit spielen zeigen können, wie Sie perspektivische Effekte einer UIView mit einer einfachen Hierarchie von Ebenen erstellen Ich zeige unterschiedliche Ergebnisse zwischen der Verwendung von transform und sublayerTransform. Hör zu.

Hier sind einige Bilder aus dem Beitrag:

.sublayerTransform option

.transform option

3
HuaTham

Mit dem iCarousel SDK können Sie genaue Karusselleffekte erzielen.

Mit der wunderbaren und kostenlosen iCarousel-Bibliothek können Sie auf iOS einen sofortigen Cover Flow-Effekt erzielen. Sie können es von https://github.com/nicklockwood/iCarousel herunterladen und ganz einfach in Ihr Xcode-Projekt ablegen, indem Sie einen Überbrückungsheader hinzufügen (in Objective-C geschrieben).

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

  • Laden Sie iCarousel herunter und entpacken Sie es
  • Gehen Sie in den Ordner, den Sie entpackt haben, öffnen Sie seinen iCarousel-Unterordner, wählen Sie iCarousel.h und iCarousel.m aus und ziehen Sie sie in Ihre Projektnavigation - das ist der linke Bereich in Xcode. Nur unter Info.plist ist in Ordnung.
  • Aktivieren Sie "Elemente bei Bedarf kopieren" und klicken Sie auf "Fertig stellen".
  • Xcode wird Sie mit der Meldung "Möchten Sie einen Objective-C-Bridging-Header konfigurieren?" Klicken Sie auf "Create Bridging Header". In Ihrem Projekt sollte eine neue Datei mit dem Namen YourProjectName-Bridging-Header.h angezeigt werden.
  • Fügen Sie diese Zeile 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 die Protokolle iCarouselDelegate und iCarouselDataSource einhalten.

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
    }
0
Tech