Aller au contenu


Photo

[SWIFT 3] Conversion de couleur hexa

couleur hexa swift

  • Please log in to reply
18 réponses à ce sujet

#1 Insou

Insou

    Ecabosseur en fèves

  • Membre
  • PipPipPipPip
  • 226 messages

Posté 07 juillet 2017 - 10:27

Bonjour tout le monde,

 

J'ai un petit soucis qui me parait simple mais pourtant je tourne en rond :/

 

En gros, je récupère via json, une couleur hexa (ex : #FF0000) que je stock comme ça :

let defaults = UserDefaults.standard
defaults.set(recupJSON["Data","Societe","CouleurHexApplication"].stringValue, forKey: "CouleurHex")

Plus loin dans mon code, j'ai une fonction pour récupérer la couleur :

func getColorBox() -> UInt {
        let defaults = UserDefaults.standard
        if let CouleurHex = defaults.value(forKey: "CouleurHex") {
            if(String(describing: CouleurHex) != ""){
                let newCouleurHex = Int((CouleurHex as! String).replacingOccurrences(of:"#", with: "0x"))!
                print(newCouleurHex)
                return UInt(newCouleurHex)
            }
            else{
                return 0xF37612 // couleur par défaut
            }
        }
        return 0xF37612 // couleur par défaut 
    }

et je dois utiliser la couleur récupérée comme ça :

SCLAlertView().showTitle(
    "Congratulations", // Title of view
    subTitle: "Operation successfully completed.", // String of view
    duration: 2.0, // Duration to show before closing automatically, default: 0.0
    completeText: "Done", // Optional button value, default: ""
    style: .Success, // Styles - see below.
    colorStyle: 0xA429FF // example de la couleur ici
)

Sauf que je me retrouve toujours avec une erreur de type "Cannot convert value of type UInt to expected argument type UIColor"

 

J'ai bien compris que j'essayais de mettre du UInt alors qu'il me demande du UIColor donc normal que ça fonctionne pas..

 

J'ai testé beaucoup de bout de code trouvé par ci, par là pour convertir mes valeurs dans tout les sens.. mais ça foire toujours, j'ai l'impression qu'il y a un truc tout bête que je n'ai pas compris..

 

Quelqu'un y voit plus clair que moi ? ^^

 

Merci de votre aide :)



#2 Joanna Carter

Joanna Carter

    Broyeur de fèves

  • Contrôleur d'arômes
  • 1 887 messages
  • LocationPlestin-les-Grèves (22)

Posté 07 juillet 2017 - 11:03

extension UIColor
{
  convenience init(hexValue: UInt)
  {
    let red = Float((hexValue & 0xFF0000) >> 16) / 255.0
    
    let green = Float((hexValue & 0xFF00) >> 8) / 255
    
    let blue  = Float(hexValue & 0xFF) / 255
    
    self.init(colorLiteralRed: red, green: green, blue: blue, alpha: 1.0)
  }
}

en code :

    let color = UIColor(hexValue: 0xF37612)


#3 Insou

Insou

    Ecabosseur en fèves

  • Membre
  • PipPipPipPip
  • 226 messages

Posté 07 juillet 2017 - 11:35

J'ai ajouté ce bout de code (j'en avais testé un similaire ^^)..

 

Par contre, j'ai une erreur dans la fonction getColorBox()

func getColorBox() -> UInt {
        let defaults = UserDefaults.standard
        if let CouleurHex = defaults.value(forKey: "CouleurHex") {
            if(String(describing: CouleurHex) != ""){
                let newCouleurHex = Int((CouleurHex as! String).replacingOccurrences(of:"#", with: "0x"))! // L'ERREUR EST ICI
                print(newCouleurHex)
                return UInt(newCouleurHex)
            }
            else{
                return 0xF37612
            }
        }
        return 0xF37612
    }

"fatal error: unexpectedly found nil while unwrapping an Optional value"

 

J'ai l'impression que je pige pas bien le truc avec # et 0x aussi :s



#4 Draken

Draken

    Mouleur de chocolats

  • Artisan chocolatier
  • PipPipPipPipPipPipPipPip
  • 8 598 messages
  • LocationParis

Posté 07 juillet 2017 - 11:47

func getColorBox() -> UInt {
        let defaults = UserDefaults.standard
        if let CouleurHex = defaults.value(forKey: "CouleurHex") {
            if(String(describing: CouleurHex) != ""){
                let newCouleurHex = Int((CouleurHex as! String).replacingOccurrences(of:"#", with: "0x"))!
                print(newCouleurHex)
                return UInt(newCouleurHex)
            }
            else{
                return 0xF37612 // couleur par défaut
            }
        }
        return 0xF37612 // couleur par défaut 
    }

Il est bien compliqué ton code. Deux return par défaut avec la même valeur ?? Et je ne voit pas l’intérêt de toutes ces conversions dans la lecture de la valeur. Tu devrais faire les conversions en lisant le JSON et stocker en mémoire une information correcte, un Uint dans le cas présent.

 

 

De plus tu forces un casting avec l’opérateur as! au risque d’avoir une fatal error. Tueur de poney !

 

La première chose a faire pour localiser le problème est d’afficher la valeur des paramètres de ta fonction. Le casting de CouleurHex échoue, mais que contient-elle vraiment ? En passant les conventions de nommage en Swift disent qu’on ne doit JAMAIS commencer un nom de variable par une majuscule. C’est réservé aux noms de classes, pour les pouvoir les identifier d’un simple regard sans réfléchir.


  • Joanna Carter aime ceci

Garçon, servez-moi un Covfefe avec du lait de soja, sans OGM ..

Et faites régler la climatisation, il fait bien chaud, ici !

 

 

Éternel Novice !  :baby:

Tueur de poneys !  :(

 

Faire simple .. c'est compliqué !

Faire compliqué .. c'est simple !

 

Un MOOC (cours en ligne - dont je ne suis pas l'auteur) gratuit sur la programmation en Obj-C et en Swift 3, démarrant le 14 Mars 2017 :

https://www.edx.org/...onnex-progios1x

 

Des dizaines d'heures de tutoriels vidéo en français (je ne suis pas l'auteur) pour apprendre à développer en Obj-C et Swift : http://pagesperso-sy...don/5I452-2014/

 

 


#5 Joanna Carter

Joanna Carter

    Broyeur de fèves

  • Contrôleur d'arômes
  • 1 887 messages
  • LocationPlestin-les-Grèves (22)

Posté 07 juillet 2017 - 11:47

Mais non !

 

1. Pourquoi t'as ignoré mon dernier post ?

 

"fatal error: unexpectedly found nil while unwrapping an Optional value"

 

… est toujours le résultat d'utiliser les ! !!!

 

Tu as fait :

let newCouleurHex = Int((CouleurHex as! String).replacingOccurrences(of:"#", with: "0x"))!

Du coup, t'as dit que tu es absolument certain que CouleurHex est un String valid !!!

 

C'est quoi comme type, la valeur récupérée de tes UserDefaults ?

 

S'il est bien un Int ou UInt, pourquoi la transformer en String ?



#6 Insou

Insou

    Ecabosseur en fèves

  • Membre
  • PipPipPipPip
  • 226 messages

Posté 07 juillet 2017 - 12:04

Bon je vais recommencer depuis le début, on y verra surement plus clair ^^

 

Tu devrais faire les conversions en lisant le JSON et stocker en mémoire une information correcte, un Uint dans le cas présent.

 

Dac'..

Alors quand je reçois mon json, voici mon code pour stocker la valeur :

Je reçois une couleur en hexa (ex : #FF0000) en string.

defaults.set(recupJSON["Data","Societe","CouleurHexApplication"].uIntValue, forKey: "CouleurHex")
print("-------")
print(recupJSON["Data","Societe","CouleurHexApplication"].stringValue)
print(recupJSON["Data","Societe","CouleurHexApplication"].uInt)
print("-------")

Sauf que rien que là, je pense que j'ai un soucis.. voici ce qu'affiche la console..

 

-------

#ED6600

nil

-------

 

nil quand je le converti en uInt ? :/

C'est surement pour ça que ça merdouille dans ma fonction..

En même temps, ça me parait normal que ça foire quand j'essaie de converti cette valeur (#ED6600 / String) en UInt..



#7 Joanna Carter

Joanna Carter

    Broyeur de fèves

  • Contrôleur d'arômes
  • 1 887 messages
  • LocationPlestin-les-Grèves (22)

Posté 07 juillet 2017 - 12:13

Que fait :

recupJSON[…] ???

Tu peux nous montrer du code ?



#8 Insou

Insou

    Ecabosseur en fèves

  • Membre
  • PipPipPipPip
  • 226 messages

Posté 07 juillet 2017 - 12:21

j'utilise SwiftyJSON pour traité le json que je reçois..

let recupJsonSync = Alamofire.request(monUrl, method: .post, parameters: parametres).responseJSON()

switch recupJsonSync.result {
case .success:
      if let value = recupJsonSync.result.value {
          let recupJSON = JSON(value)

...


#9 Joanna Carter

Joanna Carter

    Broyeur de fèves

  • Contrôleur d'arômes
  • 1 887 messages
  • LocationPlestin-les-Grèves (22)

Posté 07 juillet 2017 - 12:27

Oui, mais le code :

if let value = recupJsonSync.result.value {
          let recupJSON = JSON(value)

te donne quoi comme type pour value ?

 

Ça devrait te donner un [String: Any] qui est un dictionnaire



#10 Draken

Draken

    Mouleur de chocolats

  • Artisan chocolatier
  • PipPipPipPipPipPipPipPip
  • 8 598 messages
  • LocationParis

Posté 07 juillet 2017 - 12:36

 

j'utilise SwiftyJSON pour traité le json que je reçois..

 

Pour infos, Swift 4, disponible en Septembre/Octobre est capable de traiter directement le Json sans passer par une bibliothèque externe. On peut déjà télécharger Xcode 9 bêta pour commencer à préparer le changement. 


Garçon, servez-moi un Covfefe avec du lait de soja, sans OGM ..

Et faites régler la climatisation, il fait bien chaud, ici !

 

 

Éternel Novice !  :baby:

Tueur de poneys !  :(

 

Faire simple .. c'est compliqué !

Faire compliqué .. c'est simple !

 

Un MOOC (cours en ligne - dont je ne suis pas l'auteur) gratuit sur la programmation en Obj-C et en Swift 3, démarrant le 14 Mars 2017 :

https://www.edx.org/...onnex-progios1x

 

Des dizaines d'heures de tutoriels vidéo en français (je ne suis pas l'auteur) pour apprendre à développer en Obj-C et Swift : http://pagesperso-sy...don/5I452-2014/

 

 


#11 Insou

Insou

    Ecabosseur en fèves

  • Membre
  • PipPipPipPip
  • 226 messages

Posté 07 juillet 2017 - 12:39

let value: Any

let recupJSON: JSON // swiftyJson

 

Après via SwiftyJson, je peux caster les valeurs comme bon me semble..

https://github.com/S...optional-getter

 

D'où mon : 

recupJSON["Data","Societe","CouleurHexApplication"].stringValue

Pour moi, je stock la valeur hexa que je reçois (en string) dans ma clé "CouleurHex"

 

Et quand j'en ai besoin, je comptais appeler ma fonction getColorBox() qui me renverrai ma couleur au bon format (donc pas en string) pour l'utiliser ici :

let maCouleur = getColorBox()

SCLAlertView().showTitle(
    "Congratulations", // Title of view
    subTitle: "Operation successfully completed.", // String of view
    duration: 2.0, // Duration to show before closing automatically, default: 0.0
    completeText: "Done", // Optional button value, default: ""
    style: .Success, // Styles - see below.
    colorStyle: maCouleur // ma couleur ici
)

Je voulais donc convertir mon string "#FF0000" pour avoir le bon format (UInt ou UIColor ?)

 

Pour infos, Swift 4, disponible en Septembre/Octobre est capable de traiter directement le Json sans passer par une bibliothèque externe. On peut déjà télécharger Xcode 9 bêta pour commencer à préparer le changement. 

 

Ouai j'ai vu ça mais je ne peux pas tout changer maintenant juste pour traité directement du json ^^

Pour l'instant la bibliothèque externe ira très bien ^^



#12 Insou

Insou

    Ecabosseur en fèves

  • Membre
  • PipPipPipPip
  • 226 messages

Posté 07 juillet 2017 - 12:44

En fait je viens de me rendre compte qu'il me faut parfois du UInt et parfois du UIColor..

Mais à la base j'ai que ça : "#FF0000" en string..

 

Du coup, c'est la conversion vers UInt et UIColor où j'ai du mal :s



#13 Joanna Carter

Joanna Carter

    Broyeur de fèves

  • Contrôleur d'arômes
  • 1 887 messages
  • LocationPlestin-les-Grèves (22)

Posté 07 juillet 2017 - 13:04

Tu devrais suivre nos conseils si tu veux réussir avec la programmation !!!

 

1. Ne commences pas les noms des vars/lets avec les majuscules ; tu pourras lire et comprendre ton code plus vite (et nous aussi)

 

2. Tu devrais créer les vars/lets intermédiaires pour mieux comprendre où se trouvent les erreurs. Ne fait pas les lignes de code complexe.

 

Côté conversion de String en UIColor :

extension UIColor
{
  convenience init(hex: String)
  {
    let scanner = Scanner(string: hex)
    
    scanner.scanLocation = 0
    
    var rgbValue: UInt64 = 0
    
    scanner.scanHexInt64(&rgbValue)
    
    let red = Float((rgbValue & 0xff0000) >> 16) / 255.0
    
    let green = Float((rgbValue & 0xff00) >> 8) / 255.0
    
    let blue = Float(rgbValue & 0xff) / 255.0
    
    self.init(colorLiteralRed: red, green: green, blue: blue, alpha: 1)
  }
}
    let rawColorString = "#F37612"
    
    let colorString = rawColorString.substring(from: rawColorString.index(after: rawColorString.startIndex))
    
    let color = UIColor(hex: colorString)

  • Insou aime ceci

#14 Joanna Carter

Joanna Carter

    Broyeur de fèves

  • Contrôleur d'arômes
  • 1 887 messages
  • LocationPlestin-les-Grèves (22)

Posté 07 juillet 2017 - 13:09

Ou, tu peux utiliser une extension fait exprès pour les strings hex qui commencent avec un '#'

extension UIColor
{
  convenience init(jsonHex: String)
  {
    let scanner = Scanner(string: JsonHex)
    
    scanner.scanLocation = 1 // pour ignorer le #
    
    var rgbValue: UInt64 = 0
    
    scanner.scanHexInt64(&rgbValue)
    
    let red = Float((rgbValue & 0xff0000) >> 16) / 255.0
    
    let green = Float((rgbValue & 0xff00) >> 8) / 255.0
    
    let blue = Float(rgbValue & 0xff) / 255.0
    
    self.init(colorLiteralRed: red, green: green, blue: blue, alpha: 1)
  }
}
    let colorString = "#F37612"
    
    let color = UIColor(jsonHex: colorString)


#15 Insou

Insou

    Ecabosseur en fèves

  • Membre
  • PipPipPipPip
  • 226 messages

Posté 07 juillet 2017 - 13:51

 

1. Ne commences pas les noms des vars/lets avec les majuscules ; tu pourras lire et comprendre ton code plus vite (et nous aussi)

 

Ouai, c'est une mauvaise habitude que j'dois corriger, j'vais le faire petit à petit quand je repasserai dans mon code..

Par contre, c'est pas ça qui fait que je vais "réussir en programmation"  ???

J'comprends que ça respecte pas vraiment les conventions de nommage mais perso j'me fie pas à une majuscule pour savoir si c'est une variable ou pas ^^

Le code est assez clair pour savoir ce que c'est ^^

 

 

2. Tu devrais créer les vars/lets intermédiaires pour mieux comprendre où se trouvent les erreurs. Ne fait pas les lignes de code complexe.

 

Yes, c'est ce que j'essaie de faire le plus souvent possible..

 

Pour le string vers UIColor, c'est good, ça marche nickel, merci :)

 

Pour le string vers UInt, j'ai fais comme ça : 

let colorString = "0xFF0000"
print(colorString)
if let hexValue = UInt(String(colorString.characters.suffix(6)), radix: 16) {
     print(hexValue)
}

et du coup, c'est bon aussi, j'ai bien les bonnes couleurs aux bons endroits.

 

Merci à vous 2 :)



#16 Joanna Carter

Joanna Carter

    Broyeur de fèves

  • Contrôleur d'arômes
  • 1 887 messages
  • LocationPlestin-les-Grèves (22)

Posté 07 juillet 2017 - 14:01

J'comprends que ça respecte pas vraiment les conventions de nommage mais perso j'me fie pas à une majuscule pour savoir si c'est une variable ou pas ^^

Le code est assez clair pour savoir ce que c'est ^^

 

Mais les majuscules sont utilisés pour les noms des types. Tu dis que c'est facile de différencier entre les noms de types et les noms des var/let ?

 

En plus de 25 ans d'activité comme consultante, je l'ai entendu quelques fois mais c'est toujours eux qui le fassent qui prennent plus de temps pour déboguer son code  ::)

 

Pour le string vers UInt, j'ai fais comme ça : 

let colorString = "0xFF0000"
print(colorString)
if let hexValue = UInt(String(colorString.characters.suffix(6)), radix: 16) {
     print(hexValue)
}

et du coup, c'est bon aussi, j'ai bien les bonnes couleurs aux bons endroits.

 

Mais, pourquoi te veux le couleurs comme UInt ? De mon avis ça ne sert à rien  ???



#17 Insou

Insou

    Ecabosseur en fèves

  • Membre
  • PipPipPipPip
  • 226 messages

Posté 07 juillet 2017 - 14:38

Bah dans tout les cas, si j'ai un doute sur une variable/classe, je peux voir ce que c'est exactement en cliquant dessus avec "alt" nan ? ^^

 

 

En plus de 25 ans d'activité comme consultante, je l'ai entendu quelques fois mais c'est toujours eux qui le fassent qui prennent plus de temps pour déboguer son code ::)

 

ahah, ça m'étonne pas..

D'ailleurs j'dis pas que ça sert à rien de respecter les conventions de nommage.. au contraire, c'est juste que j'suis sur un projet tout seul, il n'y a que moi qui travail sur le code donc bon.. si ma variable a une majuscule, c'est pas la fin du monde non plus ^^

Après j't'avoue que si je travaillais en équipe sur un gros projet, je ferai surement plus attention à  ce genre de détails ^^

Enfin bon, j'vais essayé d'être plus rigoureux pour mes prochaines variable :P

 

 

Mais, pourquoi te veux le couleurs comme UInt ? De mon avis ça ne sert à rien  ???

 

A un moment, SCLAlert me demande une couleur en UInt

Vu que je veux mettre la même couleur que je récupère, j'ai converti le string (0xF00000) en Uint et ça fonctionne très bien.

 

En gros, je recupère une couleur en hexa (String) et j'ai besoin de cette couleur sous 2 formats (UiColor et UInt) pour 2 endroits différents.



#18 Joanna Carter

Joanna Carter

    Broyeur de fèves

  • Contrôleur d'arômes
  • 1 887 messages
  • LocationPlestin-les-Grèves (22)

Posté 07 juillet 2017 - 15:13

A un moment, SCLAlert me demande une couleur en UInt

Vu que je veux mettre la même couleur que je récupère, j'ai converti le string (0xF00000) en Uint et ça fonctionne très bien.

 

En gros, je recupère une couleur en hexa (String) et j'ai besoin de cette couleur sous 2 formats (UiColor et UInt) pour 2 endroits différents.

 

Tu pourrais aussi ajouter encore une extension à UIColor :

extension UIColor
{
  func rgbHex() -> UInt
  {
    var red: CGFloat = 0.0
    var green: CGFloat = 0.0
    var blue: CGFloat = 0.0
    var alpha: CGFloat = 0.0
    
    guard self.getRed(&red, green: &green, blue: &blue, alpha: &alpha) else
    {
      return 0
    }
    
    return UInt((lrintf(Float(red) * 0xFF) << 16) | (lrintf(Float(green) * 0xFF) << 8) | (lrintf(Float(blue) * 0xFF)))
  }
}

Mais je dois dire que je trouve le code de SCLAlert moche et mal écrit. Enfin, il transforme l'UInt en UIColor à l'intérieur, pourquoi pas accepter un UIColor comme paramètre ?



#19 Insou

Insou

    Ecabosseur en fèves

  • Membre
  • PipPipPipPip
  • 226 messages

Posté 07 juillet 2017 - 15:25

Ouai j'aurai pu faire une extension en effet.. mais pour le coup, elle est plus compliqué à comprendre que ma ligne de code ^^

Mais niveau cohérence, c'est vrai que c'est mieux (mettre toute les fonctions de transformation au même endroit sous forme d'extension).

 

 

Mais je dois dire que je trouve le code de SCLAlert moche et mal écrit. Enfin, il transforme l'UInt en UIColor à l'intérieur, pourquoi pas accepter un UIColor comme paramètre ?

 

Faudrait demander au développeur du projet :P

J'ai aussi trouvé ça bizarre de faire comme ça.. on a du UIColor, autant s'en servir partout..

Au début j'avais pas remarqué.. j'm'en suis rendu compte via mon post de 13h44 ^^







Also tagged with one or more of these keywords: couleur, hexa, swift

0 utilisateur(s) li(sen)t ce sujet

0 membre(s), 0 invité(s), 0 utilisateur(s) anonyme(s)