I have an app that saves an array of 5 randomly generated colors via CloudKit. They are saved under Field Type of String (list). I'm able to save and retrieve the colors successfully.
In my app, I want to display each record with the array of colors on a different row. Currently, the correct number of rows show when data is retrieved, but only the first row has the array of colors (screenshots below). When I pull down on the table, it refreshes the rows and will show a different color array that was saved.
import UIKit
import CloudKit
class FavoritesController: UIViewController, UITableViewDataSource {
let paletteController = PaletteController()
let favoritesTableView = UITableView()
let reuseIdentifier = "favoritesCell"
let privateDatabase = CKContainer.default().privateCloudDatabase
var retrieveFavoritePalette: [CKRecord] = []
override func viewDidLoad() {
super.viewDidLoad()
setupTableView()
queryDatabase()
}
func setupTableView() {
favoritesTableView.dataSource = self
favoritesTableView.delegate = self
favoritesTableView.register(UITableViewCell.self, forCellReuseIdentifier: reuseIdentifier)
let heightOfCells: CGFloat = 100
favoritesTableView.rowHeight = heightOfCells
view.addSubview(favoritesTableView)
favoritesTableView.anchor(top: view.topAnchor, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor)
}
func queryDatabase() {
let query = CKQuery(recordType: "Favorite", predicate: NSPredicate(value: true))
privateDatabase.perform(query, inZoneWith: nil) { (records, error) in
if error == nil {
print("Record retrieved")
for record in records! {
self.retrieveFavoritePalette.append(record)
}
} else {
print("Record not retrieved: \(String(describing: error))")
}
let sortedRecords = records?.sorted(by: { $0.creationDate! > $1.creationDate! })
self.retrieveFavoritePalette = sortedRecords ?? []
DispatchQueue.main.async {
self.favoritesTableView.reloadData()
}
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return retrieveFavoritePalette.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath)
let paletteRecord: CKRecord = retrieveFavoritePalette[indexPath.row]
var individualColorView: [UIView] = []
// print(paletteRecord.value(forKey: "FavoritePalette"))
let line = paletteRecord.value(forKey: "FavoritePalette") as? [String] ?? []
//Creates the individual boxes where the color goes
for i in 0..<5 {
let xAxis = i * 20
let individualView = UIView(frame: CGRect(x: xAxis, y: 0, width: 20, height: 80))
individualColorView.append(individualView)
}
for j in 0..<line.count {
let allColorsView = individualColorView[j]
print(individualColorView[j])
allColorsView.backgroundColor = UIColor(hexString: line[j])
tableView.addSubview(allColorsView)
}
cell.selectionStyle = .none
return cell
}
}
I tried putting let paletteRecord...
to tableView.addSubview(allColorsView)
into a TableViewCell class, but I got stuck when I couldn't figure out how to have the code compile without indexPath.row
in let paletteRecord: CKRecord = retrieveFavoritePalette[indexPath.row]
.
Output of print(paletteRecord.value(forKey: "FavoritePalette"))
is Optional(<__NSArrayM 0x6000039f98f0>( BBBB88, CCC68D, EEDD99, EEC290, EEAA88 ))
This is what it currently looks like. I need each row to display the string array that was saved to CloudKit.
Any help is appreciated!
I think your issue is on this line:
tableView.addSubview(allColorsView)
You are adding your color boxes to the tableView
, but you probably meant to add them to the cell itself like this:
cell.addSubview(allColorsView)