如何使用 UIButton 正确切​​换 JSON 颜色?

How to correctly switch JSON colours using UIButton?

问题: 我有 JSON 文件,其中包含一些颜色的名称和值(例如: “aliceblue”:[240, 248, 255, 1],“antiquewhite”:[250, 235, 215, 1],“aqua”:[0, 255, 255, 1],等等)。我正在尝试解码这个并在按当前顺序按下按钮后将颜色值应用于背景颜色。如果 Xcode 按顺序解码文件,例如 4、9、1... 并且颜色必须按顺序排列 4、9、1...,我认为。但是当我按下按钮时,颜色会完全随机变化(某些颜色可能会连续多次变化)。部分代码:

 @IBAction func changeColor(_ sender: UIButton) {
    
    let path = Bundle.main.path(forResource: "colors",
                                     ofType: "json")
    let url = URL(fileURLWithPath: path!)
    
    do {
        let data = try Data(contentsOf: url)
        let colors: [String:[Int]] = try JSONDecoder()
                                         .decode([String:[Int]].self,
                                                  from: data)
        
        for i in colors.enumerated() {
            
            print(i.element.key)
            let rgbaArray = colors[i.element.key]
            let r = CGFloat(rgbaArray![0]) / 255
            let g = CGFloat(rgbaArray![1]) / 255
            let b = CGFloat(rgbaArray![2]) / 255
            let a = CGFloat(rgbaArray![3])
            
            label.text = i.element.key
            
            self.view.backgroundColor = UIColor(red: r,
                                              green: g,
                                               blue: b,
                                              alpha: a)
        }
    } catch {
        print("Error")
    }    
}

问题:我必须更改代码中的哪些内容才能使其正常工作?

我相信你可以尝试声明一个struct,对应你实际的数据结构,然后使用标准的Codable协议。该结构可以是这样的:

struct Color: Codable {
    var name: String
    var values: [Int]
}

稍后在您的代码中尝试这样的事情:

@IBAction func changeColor(_ sender: UIButton) {
    
    let path = Bundle.main.path(forResource: "colors",
                                     ofType: "json")
    let url = URL(fileURLWithPath: path!)
    
    do {
        let data = try Data(contentsOf: url)
        let colors = try JSONDecoder().decode([Color].self,
                                 from: data)
        
        for color in colors {
            
            let r = CGFloat(color.values[0]) / 255
            let g = CGFloat(color.values[1]) / 255
            let b = CGFloat(color.values[2]) / 255
            let a = CGFloat(color.values[3])
            
            
            self.view.backgroundColor =
                                    UIColor(red: r,
                                          green: g,
                                           blue: b,
                                          alpha: a)
        }
    } catch {
        print("Error")
    }
}

使用以下方法:

(注意 % 运算符——它允许在这里循环 5 种颜色的序列)

import UIKit

class ViewController: UIViewController {
    
    @IBOutlet var label: UILabel!
    var colors = [String: [Int]]()
    var counter: Int = 0
    var arrayOfNames: [ String ] = []
    var arrayOfRGBAs: [ [Int] ] = []
    
    @IBAction func changeColor(_ sender: UIButton) {

        let r = CGFloat(arrayOfRGBAs[counter % 5][0]) / 255
        let g = CGFloat(arrayOfRGBAs[counter % 5][1]) / 255
        let b = CGFloat(arrayOfRGBAs[counter % 5][2]) / 255
        let a = CGFloat(arrayOfRGBAs[counter % 5][3])

        self.view.backgroundColor = UIColor(red: r,
                                          green: g,
                                           blue: b,
                                          alpha: a)
        
        self.label.text = arrayOfNames[counter % 5]
        
        self.counter += 1
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.label.text = "Choose a color"
            
        self.view.backgroundColor = .systemGray5
        
        let path = Bundle.main.path(forResource: "colors",
                                         ofType: "json")
        
        let url = URL(fileURLWithPath: path!)
            
        do {
            let data = try Data(contentsOf: url)
            
            self.colors = try JSONDecoder().decode([String:[Int]].self,
                                                    from: data)

            self.arrayOfNames.append(contentsOf: colors.keys)
            self.arrayOfRGBAs.append(contentsOf: colors.values)

        } catch {
            print("Error of decoding")
        }
    }
}

这里是 JSON 文件的内容:

{
  "red": [128, 0, 0, 1],
  "green": [0, 128, 0, 1],
  "blue": [0, 0, 128, 1],
  "purple": [128, 0, 128, 1],
  "teal": [0, 128, 128, 1]
}