[SWIFT] Développement d'applications iOS: application Timer (9. Personnalisez la couleur de la barre de progression)

スクリーンショット 2020-10-28 11.20.58.png

article

Les points pour créer une application de minuterie sont publiés dans plusieurs articles. Dans cet article, je vais vous montrer comment appliquer votre propre couleur de gradation à la barre de progression et changer la teinte au fil du temps.

environnement

Dépôt Git

Vous pouvez voir l'exemple de code à partir de l'URL du référentiel Git suivante. https://github.com/msnsk/Qiita_Timer.git

procédure

  1. Considérez la couleur de la barre de progression
  2. Créez une propriété dans ProgressBarView pour stocker la valeur de la teinte changeante (Hue).
  3. Créez une méthode pour générer un dégradé dans ProgressBarView
  4. Ajoutez une méthode à l'argument de couleur du modificateur .stroke dans Circle () sur la barre de progression.
  5. Ajoutez le modificateur .onReceive à ProgressBarView pour que la couleur de la barre de progression continue à changer

1. Considérez la couleur de la barre de progression

Pensez à la façon d'exprimer magnifiquement la couleur de la barre de progression. Cela peut varier d'une personne à l'autre. Dans mon cas, je pensais que les deux points suivants étaient importants. La première consiste à afficher en dégradé au lieu d'une seule couleur. L'autre est que la couleur change avec le temps. Mettez en œuvre ces deux éléments pour améliorer l'impression visuelle de votre application.

2. Créez une propriété dans ProgressBarView pour stocker la valeur de la teinte changeante (Hue).

Vous avez besoin d'au moins deux couleurs pour créer un dégradé. Je vais faire ces deux couleurs moi-même.

Dans Swift, il existe plusieurs façons de spécifier une couleur. Il répond également aux normes de couleur courantes. Par exemple, RVB, CMJN, TSL.

En termes simples, RVB exprime la couleur par la quantité de chacune des trois couleurs primaires de lumière rouge, verte et bleue. Les trois couleurs sont 100% blanc et 0% noir.

CMJN est les trois couleurs primaires + K: noir, et contrairement à RVB, les trois couleurs sont 100% noir et 0% blanc. Je pense que c'est facile à comprendre si vous imaginez une imprimante à jet d'encre.

Et HSB représente une couleur par Teinte, Saturation et Luminosité. La teinte indique le nombre de couleurs, la saturation correspond à la quantité de couleur (0 est monotone), la luminosité est à 100% de blanc, donc la couleur n'est pas trouble.

Étant donné que la couleur est toujours changée à la fin, s'il s'agit de TSL, il semble qu'il soit facile de l'ajuster si seule la valeur de la teinte est modifiée et que la saturation et la luminosité sont fixes, nous adoptons donc ici la spécification de couleur en HSB. Faire.

Maintenant, ajoutez deux propriétés à ProgressBarView pour stocker la teinte (Hue). Appelons-le respectivement customHueA et customHueB.

Lorsque vous spécifiez une couleur dans TSL, Color () requiert les arguments suivants. Chaque type de données est CGFloat, avec une valeur minimale de 0,0 et une valeur maximale de 1,0.

Color(hue:, saturation:, brightness:)

Par conséquent, pour le moment, remplacez 0,5 et 0,3 comme valeurs initiales des valeurs de propriété Hue nouvellement ajoutées. Gardez les nuances relativement proches, 0,5 étant vert bleuâtre et 0,3 étant vert jaunâtre.

Par exemple, s'il est de 0,0 et 0,5, les teintes seront opposées et le milieu aura tendance à être boueux lorsque la gradation finale sera faite. Par conséquent, la différence de teinte est ici limitée à 0,2. À propos, Hue 0.0 et Hue 1.0 font le tour et ont la même couleur.

ProgressBarView


struct ProgressBarView: View {
    @EnvironmentObject var timeManager: TimeManager
    
    @State var costomHueA = 0.5
    @State var costomHueB = 0.3

    var body: some View {
        //(réduction)
    }
}

3. Créez une méthode pour générer un dégradé dans ProgressBarView

Ensuite, à partir des deux propriétés qui stockent la valeur Hue, nous allons créer une méthode qui crée une gradation adaptée à une barre de progression circulaire.

Le nom de la méthode est makeGradientColor.

Les arguments sont hueA et hueB, qui prennent des données de type double. J'ai l'intention de mettre la propriété que j'ai créée plus tôt ici.

Et le type de données de la valeur de retour est AngularGradient avec une gradation conique. À propos, il existe d'autres gradations Swift telles que LinearGradient et RadialGradient. Le gradient angulaire est une gradation qui est appliquée dans le sens du tour du cercle.

func makeGradientColor(hueA: Double, hueB: Double) -> AngularGradient {}

Ensuite, écrivez dans le {} de la méthode makeGradientColor. Tout d'abord, dans le {} de la méthode, préparez la propriété qui crée les deux couleurs requises pour la gradation.

ColorA crée une couleur à partir de la valeur de l'argument hueA. Celui-ci contiendra la propriété ProgressBarView costomHueA. De même, ColorB crée une couleur à partir de la valeur de l'argument hueB. CostomHueB sera inclus ici.

ColorA et ColorB ont les mêmes valeurs de saturation et de luminosité. C'est encore un peu plus élevé et la luminosité est beaucoup plus élevée.

func makeGradientColor(hueA: Double, hueB: Double) -> AngularGradient {
let colorA = Color(hue: hueA, saturation: 0.75, brightness: 0.9)
let colorB = Color(hue: hueB, saturation: 0.75, brightness: 0.9)
}

Et enfin, créez une gradation conique à partir des deux couleurs que vous avez créées. Vous créez une instance de la structure AngularGradient, où vous placez l'initialiseur .init () dans l'argument gradient, et dans cet argument, vous placez les couleurs du début à la fin du dégradé dans Array.

Si vous procédez comme suit ici, les couleurs seront clairement séparées là où les points de début et de fin du cercle se chevauchent.

[colorA, colorB]

Par conséquent, appliquez à nouveau une gradation de couleurB à couleurA comme indiqué ci-dessous.

[colorA, colorB, colorA]

Vous pouvez également placer des couleurs au milieu pour effectuer des ajustements plus fins. Par exemple, c'est comme suit. Ici, je vais le limiter à une gradation à deux couleurs.

[colorA, colorB, colorC, colorD, colorA]

func makeGradientColor(hueA: Double, hueB: Double) -> AngularGradient {
let colorA = Color(hue: hueA, saturation: 0.75, brightness: 0.9)
let colorB = Color(hue: hueB, saturation: 0.75, brightness: 0.9)
let gradient = AngularGradient(gradient: .init(colors: [colorA, colorB, colorA]), center: .center, startAngle: .zero, endAngle: .init(degrees: 360))
return gradient
}

La méthode est décrite sous body {}.

ProgressBarView


struct ProgressBarView: View {
    @EnvironmentObject var timeManager: TimeManager
    
    @State var costomHueA = 1.0
    @State var costomHueB = 0.5

    var body: some View {
        //(réduction)
    }

    func makeGradientColor(hueA: Double, hueB: Double) -> AngularGradient {
        let colorA = Color(hue: hueA, saturation: 0.75, brightness: 0.9)
        let colorB = Color(hue: hueB, saturation: 0.75, brightness: 0.9)
        let gradient = AngularGradient(gradient: .init(colors: [colorA, colorB, colorA]), center: .center, startAngle: .zero, endAngle: .init(degrees: 360))
        return gradient
    }
}

4. Ajoutez une méthode à l'argument de couleur du modificateur .stroke dans Circle () sur la barre de progression.

Auparavant, la couleur du cercle dans la barre de progression spécifiait une seule couleur cyan dans l'argument du modificateur .stroke.

.stroke(Color(.cyan), style: StrokeStyle(lineWidth: 20, lineCap: .round, lineJoin: .round))

Maintenant, mettez la méthode que vous venez de créer comme argument au lieu de Color (.cyan). Dans les arguments de méthode hueA et hueB, mettez respectivement les propriétés costomHueA et costomHueB préparées plus tôt.

.stroke(self.makeGradientColor(hueA: costomHueA, hueB: costomHueB), style: StrokeStyle(lineWidth: 20, lineCap: .round, lineJoin: .round))

Le code entier ressemble à ceci:

ProgressBarView


struct ProgressBarView: View {
    @EnvironmentObject var timeManager: TimeManager
    
    @State var costomHueA = 1.0
    @State var costomHueB = 0.5

    var body: some View {
        ZStack {
            //(Cercle pour l'arrière-plan omis)
            
            //Cercle pour la barre de progression
            Circle()
                .trim(from: 0, to: CGFloat(self.timeManager.duration / self.timeManager.maxValue))
                //Appliquer la couleur de dégradé générée par la méthode
                .stroke(self.makeGradientColor(hueA: costomHueA, hueB: costomHueB), style: StrokeStyle(lineWidth: 20, lineCap: .round, lineJoin: .round))
                .scaledToFit()
                //Réglez la position de départ de la ligne de contour dans le sens 12 heures
                .rotationEffect(Angle(degrees: -90))
                .padding(15)
        }
    }

    func makeGradientColor(hueA: Double, hueB: Double) -> AngularGradient {
        let colorA = Color(hue: hueA, saturation: 0.75, brightness: 0.9)
        let colorB = Color(hue: hueB, saturation: 0.75, brightness: 0.9)
        let gradient = AngularGradient(gradient: .init(colors: [colorA, colorB, colorA]), center: .center, startAngle: .zero, endAngle: .init(degrees: 360))
        return gradient
    }
}

5. Ajoutez le modificateur .onReceive à ProgressBarView pour que la couleur de la barre de progression continue à changer

À l'étape 4, vous avez pu afficher la barre de progression en dégradé en la spécifiant à partir de la teinte de la propriété.

De plus, le modificateur onReceive déclenche la propriété timer (méthode Timer.publish ()) de la classe TimeManager pour modifier les valeurs des propriétés de teinte costomHueA et costomHueB toutes les 0,05 secondes pour changer la couleur de la barre de progression. Je vais continuer à changer.

Ajoutez la valeur de teinte de 0,005 toutes les 0,05 secondes. Si vous voulez changer la couleur plus lentement, 0,001 est mieux, et si vous voulez changer la couleur plus lentement, 0,01 est mieux. Si vous augmentez davantage la valeur, la couleur clignotera et le mouvement vous blessera les yeux.

De plus, puisque 1.0 est la valeur maximale de la teinte, décrivez-la avec une instruction if afin qu'elle revienne à 0.0 quand elle atteint 1.0.

.onReceive(timeManager.timer) { _ in
    self.costomHueA += 0.005
    if self.costomHueA >= 1.0 {
        self.costomHueA = 0.0
    }

Écrivez ceci pour costomHueB de la même manière. Le code entier ressemble à ceci:

ProgressBarView


struct ProgressBarView: View {
    @EnvironmentObject var timeManager: TimeManager
    
    @State var costomHueA = 0.5
    @State var costomHueB = 0.3
    
    var body: some View {
        ZStack {
            //Cercle pour le fond
            Circle()
                .stroke(Color(.darkGray), style: StrokeStyle(lineWidth: 20))
                .scaledToFit()
                .padding(15)
            
            //Cercle pour la barre de progression
            Circle()
                .trim(from: 0, to: CGFloat(self.timeManager.duration / self.timeManager.maxValue))
                //Appliquer la couleur de dégradé générée par la méthode
                .stroke(self.makeGradientColor(hueA: costomHueA, hueB: costomHueB), style: StrokeStyle(lineWidth: 20, lineCap: .round, lineJoin: .round))
                .scaledToFit()
                //Réglez la position de départ de la ligne de contour dans le sens 12 heures
                .rotationEffect(Angle(degrees: -90))
                .padding(15)
        }
        //Tous les 0.Activé toutes les 05 secondes
        .onReceive(timeManager.timer) { _ in
            self.costomHueA += 0.005
            if self.costomHueA >= 1.0 {
                self.costomHueA = 0.0
            }
            self.costomHueB += 0.005
            if self.costomHueB >= 1.0 {
                self.costomHueB = 0.0
            }
        }
    }
    
    func makeGradientColor(hueA: Double, hueB: Double) -> AngularGradient {
        let colorA = Color(hue: hueA, saturation: 0.75, brightness: 0.9)
        let colorB = Color(hue: hueB, saturation: 0.75, brightness: 0.9)
        let gradient = AngularGradient(gradient: .init(colors: [colorA, colorB, colorA]), center: .center, startAngle: .zero, endAngle: .init(degrees: 360))
        return gradient
    }
}

Vous avez maintenant une barre de progression circulaire avec une belle gradation et une teinte en constante évolution.

Recommended Posts

Développement d'applications iOS: application Timer (9. Personnalisez la couleur de la barre de progression)
Développement d'applications iOS: application Timer (8. Implémentation de la barre de progression)
Développement d'applications iOS: application Timer (6. Création de l'écran de réglage)
Développement d'applications iOS: application Timer (résumé)
Développement d'applications iOS: application Timer (7. Mise en œuvre de la sélection du son d'alarme)
Développement d'applications iOS: application Timer (5. Implémentation d'alarme et de vibration)
Développement d'applications iOS: application Timer (4. Implémentation du compte à rebours)
Développement d'applications iOS: application Timer (1. réglage de l'heure de la minuterie)
Développement d'applications iOS: application Timer (10. Créer une animation)
Développement d'applications iOS: application Timer (3. bouton Démarrer / Arrêter, bouton Réinitialiser)
[Swift] La couleur de NavigationBar est différente (plus claire) de la couleur spécifiée.
À propos des bases du développement Android
Journal complet de développement d'applications IOS pour l'auto-apprentissage
Feuille de route des compétences de développement d'applications iOS (introduction)
[Eclipse] Changer la couleur de la règle verticale
Bootstrap4 Changer la couleur du menu hamburger
[Swift] Changer la couleur du nœud SCN