Création de tutoriels et d'animations iOS simplifiée avec la bibliothèque Presentation

Le développement d'écrans de bienvenue (onboarding) ou de guides interactifs pour une application iOS peut rapidement devenir complexe lorsqu'il s'agit de gérer les transitions entre pages et les animations synchronisées. La bibliothèque Presentation offre une abstraction élégante au-dessus de UIPageViewController pour simplifier ce processus grâce à un système de positionnement relatif et une gestion intuitive des animations.

Architecture et positionnement par pourcentage

L'un des conecpts phares de Presentation est l'utilisation de coordonnées exprimées en pourcentages. Cela permet de s'affranchir des calculs de frames fixes et de garantir une mise en page adaptative selon la taille de l'écran.

La classe Position

La classe Position définit l'emplacement d'un élément en utilisant des ratios allant de 0.0 à 1.0. Voici différentes manières d'instancier un emplacement :

// Alignement depuis le coin supérieur gauche
let coinSuperieurGris = Position(left: 0.25, top: 0.35)

// Alignement depuis le coin inférieur gauche
let baseGauche = Position(left: 0.25, bottom: 0.70)

// Alignement depuis le coin supérieur droit
let zoneDroiteHaut = Position(right: 0.15, top: 0.35)

// Alignement depuis le coin inférieur droit
let zoneDroiteBas = Position(right: 0.15, bottom: 0.70)

Le conteneur Content

La classe Content fait le lien entre une vue standard (UIView) et sa Position. Elle s'occupe de générer les contraintes Auto Layout nécessaires en arrière-plan.

let monLabel = UILabel()
monLabel.text = "Bienvenue à bord"
monLabel.sizeToFit()

// Élément centré sur son point de position
let texteCentre = Content(view: monLabel, position: Position(left: 0.5, top: 0.5))

// Élément dont l'origine (coin haut-gauche) est fixée à la position
let texteOrigine = Content(view: monLabel, position: Position(left: 0.2, top: 0.2), centered: false)

Système d'animation des transitions

La bibliothèque permet de définir des animations qui se déclenchent lors du défilement entre les pages, offrant un contrôle précis sur le mouvement des éléments.

Utilisation de TransitionAnimation

let logoView = Content(view: monImageView, position: Position(left: 0.1, top: 0.4))
let ciblePosition = Position(left: 0.9, top: 0.4)

let glissementAnimation = TransitionAnimation(
    content: logoView,
    destination: ciblePosition,
    duration: 1.5,           // Durée de l'effet
    damping: 0.75,          // Coefficient d'amortissement (ressort)
    reflective: true,        // Animation réversible au retour
    initial: false           // Jouer immédiatement ou non
)

Comparatif des types d'animations disponibles

Type d'effet Description Usage recommandé
Translation Déplacement d'un point A vers un point B Mouvement d'éléments entre deux pages
Mise à l'échelle Modification de la taille (zoom) Focus sur un élément spécifique
Opacité (Fade) Variation de la transparence Apparition ou disparition fluide
Rotation Pivotement de la vue Indicateurs de chargement ou effets visuels

Mise en œuvre pratique

Pour intégrer Presentation, vous pouvez utiliser CocoaPods (pod 'Presentation') ou Carthage (github "hyperoslo/Presentation").

Exemple de contrôleur de tutoriel

import Presentation

class OnboardingViewController: PresentationController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupGuide()
    }
    
    private func setupGuide() {
        let pageA = construireEcran(titre: "Étape 1", sousTitre: "Découvrez notre interface.")
        let pageB = construireEcran(titre: "Étape 2", sousTitre: "Configurez vos préférences.")
        
        // Ajout des pages au contrôleur principal
        add([pageA, pageB])
    }
    
    private func construireEcran(titre: String, sousTitre: String) -> SlideController {
        let titreLabel = UILabel()
        titreLabel.text = titre
        titreLabel.font = .boldSystemFont(ofSize: 26)
        titreLabel.sizeToFit()
        
        let descLabel = UILabel()
        descLabel.text = sousTitre
        descLabel.numberOfLines = 0
        descLabel.textAlignment = .center
        descLabel.frame = CGRect(x: 0, y: 0, width: 280, height: 80)
        
        let titreContent = Content(view: titreLabel, position: Position(left: 0.5, top: 0.25))
        let descContent = Content(view: descLabel, position: Position(left: 0.5, top: 0.45))
        
        let slide = SlideController(contents: [titreContent, descContent])
        
        // Animation personnalisée pour le titre
        let animTitre = TransitionAnimation(
            content: titreContent,
            destination: Position(left: 0.5, top: 0.35),
            duration: 1.2
        )
        slide.add(animations: [animTitre])
        
        return slide
    }
}

Gestion avancée : L'effet Parallaxe

Le parallaxe donne une impression de profondeur en faisant bouger les éléments de l'arrière-plan à des vitesses différentes de celles du premier plan.

private func appliquerEffetParallaxe() {
    let decors = [
        (image: "nuages", x: -0.3, y: 0.15, vitesse: 0.2),
        (image: "montagnes", x: 0.0, y: 0.4, vitesse: 0.05),
        (image: "foret", x: 0.0, y: 0.7, vitesse: -0.1)
    ]
    
    var listeContenus = [Content]()
    
    for decor in decors {
        let vueImage = UIImageView(image: UIImage(named: decor.image))
        let positionInitiale = Position(left: decor.x, top: decor.y)
        let contenu = Content(view: vueImage, position: positionInitiale, centered: false)
        listeContenus.append(contenu)
    }
    
    addToBackground(listeContenus)
    
    // Application du décalage selon les pages
    for indexPage in 1...3 {
        for (indexElement, decor) in decors.enumerated() {
            let decalageX = decor.x + (CGFloat(indexPage) * decor.vitesse)
            let cible = Position(left: decalageX, top: decor.y)
            
            addAnimation(
                TransitionAnimation(content: listeContenus[indexElement], destination: cible),
                forPage: indexPage
            )
        }
    }
}

Optimisation et bonnes pratiques

Axe d'optimisation Action recommandée Bénéfice
Mémoire Réutilisation des instances de Content Réduction de l'empreinte RAM
Fluidité Limiter le nombre de vues transparentes superposées Maintien de 60 FPS lors du scroll
Architecture Utiliser des méthodes "Factory" pour les éléments récurrents Code plus propre et maintenable

En combinant le positionnement relatif et les animations réactives, Presentation permet de transformer un simple tutoriel statique en une expérience utilisateur immersive et dynamique, tout en conservant une base de code structurée et facile à faire évoluer.

Étiquettes: iOS Swift uikit Animation onboarding

Publié le 25 juin à 00h52