【发布时间】:2017-01-22 12:53:42
【问题描述】:
一点上下文 - 我有一个名为 SelectedListItemsViewController 的 ViewController,它的 TableView 由一组名为 selectedListItems 的领域模型对象填充。有一个添加栏按钮项,它导航到另一个名为 AllListItemsViewController 的 ViewController,它的 TableView 由名为 allListItems 的领域模型对象数组填充,每个单元格都包含一个 UISwitch。
上述两个数组都基于同一个类,该类具有一个名为isSelected 的布尔属性。在我的代码中,我目前对其进行了设置,以便当我在 AllListItemsViewController 的单元格中切换 UISwitch 时,如果它“打开”indexPath.row 的 isSelected 属性 allListItems 更改为 true并且该对象被附加到selectedListItems 数组中。这部分似乎工作正常。
将开关切换到“关闭”会导致allListItems 的indexPath.row 的isSelected 属性更改为false,并且该对象在其索引处从selectedListItems 中删除。这在大多数情况下都有效,但有时会以错误的顺序将单元格的 UISwitch 切换为“关闭”(如果它们在索引 0、1、2 处“打开”,然后我尝试打开索引 1 ' off') 然后它会使模拟崩溃,可能是由于索引超出范围。
我在编程方面非常业余,所以我确信下面的代码很草率,我怀疑我是否以最好/最有效的方式实现了我的目标。
// The following arrays are for use with UISegmentedControl (other three removed for brevity)
// This is an array of 'Appearance' list items created from allListItems
let appearanceArray = allListItems.filter{
$0.category.rangeOfString("Appearance") != nil
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath:
NSIndexPath) -> UITableViewCell {
let cellIdentifier = "Cell"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! AllListItemsTableViewCell
// This is a string value for the cell at indexPath.row
var listItemInCell = ""
// This is an array of all listItems in allListItems, and used with indexOf to check boolean status of isSelected inside of allListItems array
let arrayAll = allListItems.map{($0.listItem)}
// This is an array of all listItems in selectedListItems, and used to track remove indexes
let arraySelected = selectedListItems.map{($0.listItem)}
switch(segmentedControl.selectedSegmentIndex)
{
case 0: // Case 0 of 4, the others removed for brevity of this question
listItemInCell = appearanceArray[indexPath.row].listItem
// Index of listItemInCell inside of the array of allListItems' listItems
let indexOf = arrayAll.indexOf(listItemInCell)!
cell.listItemLabel.text = listItemInCell
// Tracks UISwitch activity
cell.callback = { (tableViewCell, switchState) in
if self.tableView.indexPathForCell(tableViewCell) != nil {
// do something with index path and switch state
if switchState == true {
allListItems[indexOf].isSelected = true
selectedListItems.append(self.appearanceArray[indexPath.row])
} else {
allListItems[indexOf].isSelected = false
let indexInSelected = arraySelected.indexOf(listItemInCell)!
selectedListItems.removeAtIndex(indexInSelected)
}
}
}
if appearanceArray[indexPath.row].isSelected {
cell.toggleIsSelected.on = true
} else {
cell.toggleIsSelected.on = false
}
break
有没有更好的方法来解决这个问题,不会出现导致运行时错误的边缘情况?我的一个想法是记录selectedListItems 的索引可能不是最好的方法,因为它是一个全局变量并且是延迟计算的,所以它并不总是最新的。另一个想法是,当我创建对象属性的数组来跟踪索引时,翻译中会丢失一些东西,而不是能够在对象数组本身中找到给定点的索引。
【问题讨论】: