3
votes

Comment animer le changement de mode sombre sous iOS?

Les utilisateurs peuvent changer de thème dans une section des paramètres de l'application, comme indiqué ci-dessous.

Cela se fait en modifiant window.overrideUserInterfaceStyle .

Bien que cela fonctionne comme prévu, le changement n'a aucune animation. L'ensemble de l'application passe immédiatement au style sélectionné, par opposition aux modifications fluides dans l'application Paramètres iOS.

Placez simplement l'affectation dans la completion de UIView.animate(withDuration duration: TimeInterval, animations: @escaping () -> Void, completion: ((Bool) -> Void)? = nil) ne fonctionnera pas.

réglage de l'application


4 commentaires

quelle animation, quel composant et vous êtes dans le réglage du thème alors pourquoi ne pas animer uniquement le réglage du thème?


Oui. Mais même seul le contrôleur de vue de table de réglage semble trop nombreux. Il est intégré dans un contrôleur de navigation, qui est intégré dans un contrôleur de barre d'onglets.


trop ? UIApperiance vous UIApperiance que ces quelques composants, vous pouvez essayer UIApperiance


S'il vous plaît voir le commentaire que j'ai laissé dans la réponse de Finebel. Je ne pense pas que UIAppearance puisse réduire beaucoup de travail.


4 Réponses :


0
votes

Vous pouvez faire quelque chose comme ceci:

var toggleVar = true

@IBAction func buttonDidTap(_ sender: UIButton) {
    
    UIView.animate(withDuration: 0.5, animations: {
        self.overrideUserInterfaceStyle = self.toggleVar ? .dark : .light
        self.view.backgroundColor = .systemBackground
    }) { (_) in
        //set overrideUserInterfaceStyle app wide
        UIApplication.shared.windows.first?.overrideUserInterfaceStyle = self.overrideUserInterfaceStyle
        self.toggleVar.toggle()
    }
}

Ainsi, pour animer le changement d'arrière-plan, vous devez animer self.view.backgroundColor = .systemBackground . Dans le gestionnaire de complétion, vous pouvez définir le nouveau overrideUserInterfaceStyle pour l'ensemble de l'application ...


1 commentaires

J'ai eu l'idée. Mais est-ce la seule voie à suivre? L'animation manuelle de toutes les couleurs UIViews visibles actuelles semble trop difficile à maintenir. Par exemple, j'ai besoin d'animer la barre de navigation, la vue de table, dont les sous-vues visibles incluent une vue d'en-tête, des étiquettes de texte, des vues de séparation et des vues d'accessoires. Aussi la barre d'onglets.



0
votes

J'ai eu le même problème. Après des tentatives infructueuses avec les UIView/UIWindow.animate/transition et animation, j'ai contourné le problème comme suit:

  • Capturez tout l'écran
  • Ajouter une UIImageView plein écran avec l'image capturée
  • Changer le style de l'interface utilisateur en arrière-plan (qui ne s'anime pas)
  • Faire disparaître l'UIImageView

En supposant que vous travaillez également avec un UITableViewController dans un UINavigationController, un exemple:

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    // Disable all checkmarks
    tableView.visibleCells.forEach { (cell) in
        cell.accessoryType = .none
    }
    
    // Set checkmark
    let cell = tableView.cellForRow(at: indexPath)
    cell?.accessoryType = .checkmark
    
    // Capture and add screenshot of current screen
    let imageView = UIImageView()
    imageView.image = UIApplication.shared.makeSnapshot()
    imageView.addTo(self.navigationController!.view).snp.makeConstraints { (maker) in
        maker.edges.equalToSuperview()
    }
    
    // Set new dark mode setting and fade out screenshot
    UIView.animate(withDuration: 0.5, animations: {
        // Important to set it within the animations closure, so that the status bar will animate
        UIApplication.shared.windows.first?.overrideUserInterfaceStyle = .dark
        imageView.alpha = 0
    }) { (_) in
        imageView.removeFromSuperview()
    }
    
    // Deselect row
    tableView.deselectRow(at: indexPath, animated: true)
}

Remarques:

  • La méthode makeSnapshot() provient de ce post: https://stackoverflow.com/a/40953026/4489859
  • J'utilise SnapKit pour ajouter / mettre en page des vues, vous devez donc probablement modifier cette ligne en conséquence pour votre projet
  • Remplacez .dark par la valeur dynamique correcte pour votre projet

Résultat:

Sur l'appareil lui-même, c'est encore plus fluide que l'animation de changement du système pour moi!


1 commentaires

Je n'ai pas encore essayé. Mais c'est une manière intelligente de procéder!



0
votes

J'utilise Xamarin et pour moi la solution est:

UIView TempView = Window.SnapshotView(true);    

Window.Add(TempView);

Window.OverrideUserInterfaceStyle = UIUserInterfaceStyle.Light;

UIView.Animate(0.5,
() => { 
    TempView.Alpha = 0;
},
() => {
    TempView.RemoveFromSuperview();
    TempView.Dispose();
});


0 commentaires

2
votes

Il existe un moyen simple de changer le thème du mode sombre de l'application avec une animation

if let window = UIApplication.shared.keyWindow {
    UIView.transition (with: window, duration: 0.3, options: .transitionCrossDissolve, animations: {
        window.overrideUserInterfaceStyle = .dark //.light or .unspecified
    }, completion: nil)
}


0 commentaires