Con la llegada del iPhone 6S, llega a nosotros una nueva funcionalidad hardware muy curiosa, el 3D Touch.
Básicamente, las nuevas pantallas tienen la capacidad para detectar la presión que ejercemos sobre la misma, y dependiendo de dicha presión, se muestran una serie de nuevas opciones.
Las opciones existentes actualmente son las siguientes:
- Acciones rápidas: ejerciendo presión sobre el icono de una app, podemos consultar las acciones rápidas que se hayan habilitado para la misma.
- Peek and Pop: lo cual nos permite consultar una vista detalle de un elemento sin necesidad de acceder mediante navegación a dicha pantalla.
- Sensor de presión personalizado: que nos va a permitir establecer diferentes comportamientos en nuestra app dependiendo de la fuerza con la que el usuario presiona los elementos. Un buen ejemplo sería un videojuego.
En este artículo vamos a ver como implementar fácilmente las dos primeras opciones en nuestra app.
Tenemos ante nosotros dos opciones posibles:
- Acciones estáticas: que pueden definirse a nivel de
Info.plist
. - Acciones dinámicas: que pueden definirse en tiempo de ejecución, haciendo uso de la clase
UIApplicationShortcutItem
y añadirse a nuestraUIApplication
.
Acciones estáticas
Para crear una acción de tipo estática, tenemos que crear en el Info.plist
una estructura de elementos como se muestra a continuación:
Los atributos a cumplimentar para cada acción, representada por un diccionario, son:
UIApplicationShortcutItemTitle
: el titulo que aparecerá en el menú contextual.UIApplicationShortcutItemType
: un identificador único que deberemos asignar a cada acción.UIApplicationShortcutItemIconType
: el icono que deseamos mostrar junto al título de la acción.
Si queremos utilizar un icono personalizado y no uno de los que nos ofrece Apple, deberemos utilizar la clave UIApplicationShortcutItemIconFile
, indicando como valor el nombre la imagen de nuestro icono, en lugar de utilizar UIApplicationShortcutItemIconType
.
Es importante saber que la imagen que utilicemos deberá tener un tamaño de 104×104 en @3x y 70×70 en @2x.
Si ejecutamos nuestra app en un dispositivo compatible con 3D Touch y hacemos una pulsación fuerte sobre el icono de nuestra app, veremos un menú contextual con la opción que acabamos de crear:
Para que dependiendo de la opción que elija el usuario se ejecute una u otra lógica en nuestra app, tenemos una forma de saber qué menú ha sido pulsado. Esto lo haremos a través de un método del AppDelegate
:
1 2 3 4 5 6 7 8 |
func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) { if shortcutItem.type == "com.migueldiazrubio.menu" { print("Ha pulsado la opción Home") } } |
Como se puede observar, estamos utilizando el campo UIApplicationShortcutItemType
para identificar la acción univocamente.
Acciones dinámicas
Acciones dinámicas son aquellas que dependiendo del contexto y la información que tiene la app en cada momento, se muestran unas u otras opciones.
Para generar estas acciones debemos hacer uso de la propiedad shortcutItems
de la clase UIApplication
. Vamos a ver a continuación un ejemplo de cómo crear una acción dinámica en tiempo de ejecución:
1 2 3 4 5 6 |
let dynamicSample = UIApplicationShortcutItem(type: "com.migueldiazrubio.dynamic", localizedTitle: "Dinámica", localizedSubtitle: "Subtitle", icon: UIApplicationShortcutIcon(type: .cloud), userInfo: nil) UIApplication.shared.shortcutItems = [dynamicSample] |
Si ahora ejecutamos la app, veremos que se muestra no solo la opción dinámica que hemos definido, sino que también se muestran todas aquellas que hayamos definido como estáticas.
Peek & Pop
Antes de poder implementar la funcionalidad de Peek & Pop, tenemos que verificar que el dispositivo de nuestro usuario tiene estas capacidades. Esta comprobación podemos hacerla a través de la siguiente línea de código:
1 2 3 4 5 |
if traitCollection.forceTouchCapability == .available { } |
Apple nos recomienda facilitar método alternativo para todos aquellos de nuestros usuarios que no tengan un dispositivo compatible, pero quieran hacer igualmente este gesto tan productivo. Para ello, podemos habilitar la misma funcionalidad a través del UILongPressGestureRecognizer
.
Vamos a empezar añadiendo a nuestra escena un segundo View Controller, al cual no asignaremos una clase concreta, y únicamente cambiaremos su color de fondo al que queráis para diferenciarlo.
A continuación crearemos un IBOutlet
para nuestro botón:
1 2 3 4 |
@IBOutlet weak var peekAndPopButton: UIButton! |
Ahora lo único que tenemos que hacer, es indicarle al sistema que nuestro View Controller se va a encargar de hacer peek and pop. Para ello, debemos implementar la siguiente lógica:
1 2 3 4 5 6 7 8 9 |
if traitCollection.forceTouchCapability == .available { registerForPreviewing(with: self, sourceView: peekAndPopButton) } else { print("El dispositivo no es compatible con 3D Touch") } |
Se mostrará un error sobre la línea que invoca al método registerForPreviewing
debido a que aún no hemos indicado que nuestro View Controller implemente el protocolo adecuado. Toda la lógica de implementación de este protocolo os recomiendo meterla dentro de una extensión con la finalidad de que vuestro código quede mucho mas limpio.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
extension ViewController : UIViewControllerPreviewingDelegate { func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? { let previewView = storyboard?.instantiateViewController(withIdentifier: "peekAndPopVC") return previewView } func previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController) { let previewView = storyboard?.instantiateViewController(withIdentifier: "peekAndPopVC") show(previewView!, sender: self) } } |
El primer método nos permite identificar que vista debe visualizarse cuando se intente previsualizar mediante una presión de intensidad media.
El segundo método se encarga de hacer la carga de la vista final que se mostrará al hacer una presión de intensidad alta.
Para nuestro ejemplo vamos a utilizar la misma vista para la previsualización que para la carga final, pero debéis conocer que es posible utilizar distintas vistas.
Conclusión
Sin lugar a dudas, 3D Touch es una tecnología que nos permite hacer cosas muy interesantes en nuestra app. Implementar funcionalidades como las acciones rápidas sobre el icono de la app, o la funcionalidad de peek and pop es realmente sencillo, por lo que ya podéis levantaros del sofá e ir a implementarlo en vuestras apps.