¿Cómo aplico una transformación de perspectiva a una UIView?

Estoy buscando realizar una transformación de perspectiva en una UIView (como se ve en Coverflow)

¿Alguien sabe si esto es posible?

He investigado el uso de CALayer y he CALayer todos los podcasts de Core Animation del progtwigdor pragmático, pero todavía no tengo claro cómo crear este tipo de transformación en un iPhone.

¡Cualquier ayuda, punteros o ejemplos de fragmentos de código serían realmente apreciados!

Como dijo Ben, necesitarás trabajar con la capa de UIView, usando un CATransform3D para realizar la rotación de la capa. El truco para hacer funcionar la perspectiva, como se describe aquí , es acceder directamente a una de las celdas de matriz del CATransform3D (m34). La matemática matricial nunca ha sido lo mío, así que no puedo explicar exactamente por qué funciona, pero lo hace. Tendrá que establecer este valor en una fracción negativa para su transformación inicial, luego aplique la rotación de la capa se transforma a eso. También debería poder hacer lo siguiente:

 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; 

que reconstruye la transformación de capas desde cero para cada rotación.

Un ejemplo completo de esto (con código) se puede encontrar aquí , donde he implementado la rotación basada en el toque y la escala en un par de CALayers, en base a un ejemplo de Bill Dudney. La última versión del progtwig, en la parte inferior de la página, implementa este tipo de operación de perspectiva. El código debe ser razonablemente simple de leer.

La subcapaTransform a la que se refiere en su respuesta es una transformación que se aplica a las subcapas de su CALayer de CALayer . Si no tiene subcapas, no se preocupe. Uso el sublayerTransform en mi ejemplo simplemente porque hay dos CALayers contenidos dentro de la capa que estoy rotando.

Solo puede usar transformaciones de Core Graphics (Quartz, 2D only) directamente aplicadas a la propiedad de transformación de UIView. Para obtener los efectos en el flujo de cobertura, tendrá que usar CATransform3D, que se aplica en el espacio tridimensional, y así puede darle la vista en perspectiva que desee. Solo puede aplicar CATransform3Ds a capas, no a vistas, por lo que tendrá que cambiar a capas para esto.

Vea la muestra “CovertFlow” que viene con Xcode. Es mac-only (es decir, no para iPhone), pero muchos de los conceptos se transfieren bien.

Para agregar a la respuesta de Brad y proporcionar un ejemplo concreto, tomo prestado de mi propia respuesta en otra publicación sobre un tema similar. En mi respuesta, creé un simple patio Swift con el que puedes descargar y jugar , donde demuestro cómo crear efectos de perspectiva de un UIView con una jerarquía simple de capas, y muestro diferentes resultados entre el uso de transform y sublayerTransform . Echale un vistazo.

Estas son algunas de las imágenes de la publicación:

Opción .sublayerTransform

.transform opción

Puede obtener un efecto de carrusel preciso con iCarousel SDK.

Puede obtener un efecto Cover Flow instantáneo en iOS utilizando la biblioteca iCarousel maravillosa y gratuita. Puede descargarlo desde https://github.com/nicklockwood/iCarousel y soltarlo fácilmente en su proyecto Xcode agregando un encabezado puente (está escrito en Objective-C).

Si no ha agregado antes el código Objective-C a un proyecto Swift, siga estos pasos:

  • Descarga iCarousel y descomprímelo
  • Vaya a la carpeta que descomprimió, abra su subcarpeta iCarousel, luego seleccione iCarousel.h e iCarousel.m y arrástrelos a la navegación del proyecto: ese es el panel izquierdo de Xcode. Justo debajo de Info.plist está bien.
  • Marque “Copiar elementos si es necesario” y luego haga clic en Finalizar.
  • Xcode le preguntará con el mensaje “¿Desea configurar un encabezado puente de Objective-C?” Haga clic en “Crear encabezado puente” Debería ver un nuevo archivo en su proyecto, llamado YourProjectName-Bridging-Header.h.
  • Agregue esta línea al archivo: #import “iCarousel.h”
  • Una vez que haya agregado iCarousel a su proyecto, puede comenzar a usarlo.
  • Asegúrese de cumplir con los protocolos iCarouselDelegate e iCarouselDataSource.

Swift 3 Código de muestra:

  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 }