我最近发现我的代码出错了,在做完所有事情后我都想到了解决它的问题,我能够弄清楚我相信会发生什么。在我的应用程序中,如果用户选择该单元格,我可以更改背景颜色,这样就可以选择多个单元格。但是如果选择了第一个单元格,它将取消选择(更改背景颜色)所有其他单元格。但事实证明我得到以下错误:
致命错误:在解包可选值时意外发现nil
当我尝试更改屏幕上不可见的单元格的背景颜色时。我假设这是因为只有可见的单元格被加载到内存中,而其他所有单元格只有在再次可见时才会被加载。
那么我如何手动加载我知道IndexPath的单元格,但也知道它在视图之外。另外,有没有办法知道IndexPath上的单元格是否已加载?
这是我目前的代码。
func selectAnyList(tableView: UITableView) {
let sections = frc!.sections!
let currentSection = sections[0]
let numRows = currentSection.numberOfObjects
for i in 0...(numRows - 1) {
let indexPath = IndexPath(row: i, section: 0)
let cell = tableView.cellForRow(at: indexPath) as! ItemListTVCell //This is where the error happens if the cell is not visible
if (i == 0) {
cell.backgroundColor = UIColor.activeAqua.withAlphaComponent(0.85)
} else {
cell.backgroundColor = UIColor.white.withAlphaComponent(0.85)
}
}
}
编辑:添加单元格的加载方式
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let list: Ent_Lists = frc!.object(at: indexPath)
let cell = tableView.dequeueReusableCell(withIdentifier: "itemListCell", for: indexPath) as! ItemListTVCell
if (list == Ent_Lists.anyList) {
self.anyCell = cell
}
cell.listName.text = list.name
cell.listImage.image = list.image!.uiImage
if ((indexPath as NSIndexPath).row != 0 && listSet!.contains(list)) {
numLists += 1
}
return cell
}
答案 0 :(得分:0)
我创建了一个小样本文件,您可以在其中动态设置背景颜色,每次选择的颜色都会有不同的bg颜色。
import UIKit
// This is your core data entity
struct Entity {
let title: String
}
// This is a basic viewModel, holding the selected property and the core data entity
class EntityViewModel {
let entity: Entity
// Set the selected property to false
var selected: Bool = false
init(entity: Entity) {
self.entity = entity
}
}
class TableViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
lazy fileprivate var entityViewModels: [EntityViewModel] = self.makeEntityViewModels(count: 20)
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
}
}
extension TableViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return entityViewModels.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")!
// Work with viewModels, instead of the CoreData entities directly
let viewModel = entityViewModels[indexPath.row]
// Set the title of the cell
cell.textLabel?.text = viewModel.entity.title
// Based on the selected property, set the background color
cell.backgroundColor = viewModel.selected ? .black : .yellow
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// Reset the selection for all viewModels
entityViewModels.forEach {
$0.selected = false
}
// Get the viewModel at the right indexPath
let viewModel = entityViewModels[indexPath.row]
// Set its selected state to true
viewModel.selected = true
// Reload the tableView -> this will trigger `cellForRowAt`, and your background colors will be up to date
self.tableView.reloadData()
}
}
extension TableViewController {
// This is where you read up from core data
private func makeEntities(count: Int) -> [Entity] {
var entities: [Entity] = []
for index in 0..<count {
entities.append(Entity(title: "\(index) Some title"))
}
return entities
}
// Just wrap the core data objects into viewModels
func makeEntityViewModels(count: Int) -> [EntityViewModel] {
let entities = makeEntities(count: count)
var viewModels: [EntityViewModel] = []
for (index, entity) in entities.enumerated() {
let viewModel = EntityViewModel(entity: entity)
// Intialy, set the first viewModel to selected
if index == 0 {
viewModel.selected = true
}
viewModels.append(viewModel)
}
return viewModels
}
}