ios - data - ¿Cómo aplico una transformación de perspectiva a un UIView?
core animation swift (4)
Estoy buscando realizar una transformación de perspectiva en un 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 Animación principal del programador pragmático, pero todavía no tengo claro cómo crear este tipo de transformación en un iPhone.
Cualquier ayuda, punteros o fragmentos de código de ejemplo serían realmente apreciados!
Como dijo Ben, tendrás que trabajar con la capa de UIView, usando una CATransform3D para realizar la rotación de la capa. El truco para que la perspectiva funcione, como se describe aquí , es acceder directamente a una de las celdas de la matriz de CATransform3D (m34). Matrix matemáticas nunca ha sido lo mío, así que no puedo explicar exactamente por qué funciona esto, pero lo hace. Deberá establecer este valor en una fracción negativa para su transformación inicial, luego aplicar las transformaciones de rotación de capa a eso. También deberías 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 capa transformada desde cero para cada rotación.
Un ejemplo completo de esto (con código) se puede encontrar here , donde he implementado la rotación y escalado basado en el tacto en un par de CALayers, basado en un ejemplo de Bill Dudney. La versión más reciente del programa, en la parte inferior de la página, implementa este tipo de operación en perspectiva. El código debe ser razonablemente fácil de leer.
La subcapa Transformación a la que te refieres en tu respuesta es una transformación que se aplica a las subcapas del CALAYER de tu CALayer
. Si no tienes subcapas, no te preocupes. Utilizo el sublayerTransform en mi ejemplo simplemente porque hay dos CALayers contenidos dentro de una capa que estoy rotando.
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 campo de juego Swift simple que puedes descargar y jugar , donde demuestro cómo crear los efectos de perspectiva de una UIView con una simple jerarquía de capas, y muestro diferentes resultados entre el uso de transform
y sublayerTransform
. Echale un vistazo.
Aquí están algunas de las imágenes del post:
Puede obtener un efecto de carrusel preciso con iCarousel SDK.
Puede obtener un efecto Cover Flow instantáneo en iOS utilizando la maravillosa y gratuita biblioteca iCarousel. Puede descargarlo desde https://github.com/nicklockwood/iCarousel y soltarlo en su proyecto Xcode con bastante facilidad agregando un encabezado puente (está escrito en Objective-C).
Si no ha agregado el código Objective-C a un proyecto Swift anteriormente, siga estos pasos:
- Descarga iCarousel y descomprime.
- Vaya a la carpeta que descomprimió, abra su subcarpeta iCarousel, luego seleccione iCarousel.h e iCarousel.m y arrástrelos a la navegación de su proyecto, que 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 indicará el mensaje "¿Desea configurar un encabezado de puente de Objective-C?" Haga clic en "Crear encabezado de puente". Debería ver un nuevo archivo en su proyecto, llamado YourProjectName-Bridging-Header.h.
- Agregue esta línea al archivo: #importar "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.
Código de muestra Swift 3:
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
}
Solo puede usar transformaciones de Core Graphics (solo Quartz, 2D) aplicadas directamente a una 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 3D, y así puede darle la vista en perspectiva que desee. Solo puede aplicar CATransform3Ds a las capas, no a las vistas, por lo que tendrá que cambiar a las capas para esto.
Echa un vistazo a la muestra "CovertFlow" que viene con Xcode. Es solo para mac (es decir, no para iPhone), pero muchos de los conceptos se transfieren bien.