我在视图控制器中有一个表视图,我想要实现的结果是,如果选择了该行,则为 1...4 的行var mytotal
加 5,如果取消选择该行,则减去 5。
对于第 5 行(最后一行),如果选择了该行,我想加 10,如果取消选择该行,则减去 10。每次选择一行时,都会在单元格的右侧添加一个复选标记,当取消选择该行时,将删除复选标记。
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var mytotal: UILabel!
var total = 0
@IBOutlet weak var tableView: UITableView!
var items = ["Inside Cabinets", "Inside Fridge", "Inside Oven", "Interior windows","Laundry wash & dry"]
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "myCell")
}
// number of rows in table
func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
return self.items.count
}
// create the cells
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
var cell = self.tableView.dequeueReusableCellWithIdentifier("myCell")!
cell.textLabel!.text = self.items[indexPath.row]
cell.accessoryType = UITableViewCellAccessoryType.None
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
var theCell = tableView.cellForRowAtIndexPath(indexPath)!
if theCell.accessoryType == .None {
theCell.accessoryType = .Checkmark
total += 5
self.mytotal.text = String(total)
}
else if theCell.accessoryType == .Checkmark {
theCell.accessoryType = .None
total -= 5
self.mytotal.text = String(total)
}
}
}
我对您的代码进行了一些更改以实现您所描述的内容。
首先,您可以创建一个结构并将每个元素的数据存储在其中,而不是简单地拥有String
项的数组。
struct Item {
var name: String // Name of the row (e.g. "Inside cabinets")
var isSelected: Bool // Whether or now this item has been selected
var value: Int // How much you increase your total when selecting this row
}
然后在视图控制器中,您将按如下方式定义[Item]
数组:
var items = [
Item(name: "Inside Cabinets", isSelected: false, value: 5),
Item(name: "Inside Fridge", isSelected: false, value: 5),
Item(name: "Inside Oven", isSelected: false, value: 5),
Item(name: "Interior windows", isSelected: false, value: 5),
Item(name: "Laundry wash & dry", isSelected: false, value: 10)
]
在 tableView:cellForRowAtIndexPath
方法中对单元格进行出列时,如果项目列表变得足够长,则将重复使用取消排队的单元格。因此,在检查和取消选中单元格时需要小心。一旦单元格滚动出屏幕,您将失去其选中/未选中状态。此外,由于重复使用新的已取消排队的单元格,因此可能会意外选择该单元格。
这就是为什么items
数组也保持isSelected
状态的原因。我们将使用此值来确定当单元格取消排队以显示在屏幕上时,该行之前是否已被选中。
因此,当我们选择一行时,我们将更新数据模型( [Item]
),然后告诉 tableView 在该 indexPath 处重新加载单元格。您也可以使用 tableView.reloadData()
,但它的成本更高,因为它会重新加载所有可见单元格。
重新加载选定/取消选择的单元格调用tableView:numberOfRowsInSection
并使用更改的数据模型(items
数组)刷新 tableView 中的该行,然后该单元格将显示为选中或未选中。
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
// Remove the following line. This will create a NEW cell. It is not the same cell that is visible currently on the screen.
// var theCell = tableView.cellForRowAtIndexPath(indexPath)!
// Toggle the selected state of this cell (e.g. if it was selected, it will be deselected)
items[indexPath.row].isSelected = !items[indexPath.row].isSelected
// Update your stored total based on the value of this item
if items[indexPath.row].isSelected {
total = total + items[indexPath.row].value
self.mytotal.text = String(total)
} else {
total = total - items[indexPath.row].value
self.mytotal.text = String(total)
}
// Tell the table to reload the cell that has changed
tableView.beginUpdates()
tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.None)
tableView.endUpdates()
}
另请注意,每个项目的 +/- 5 和 +/- 10 值也存储在数据模型中。这样,如果您创建具有不同值的未来项,则只需将它们添加到items
数组并设置该项的value
变量即可。
还有一件事。如果不希望单元格在选择时变暗,可以将行cell.selectionStyle = .None
添加到tableView:cellForRowAtIndexPath
方法中。
希望对您有所帮助!
更新 1:
我将selected
固定在上面的答案中isSelected
。对不起,错别字。不要忘记在tableView:cellForRowAtIndexPath
中包括指示是否已检查单元格:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier("myCell")!
cell.textLabel!.text = self.items[indexPath.row].name // Get name
// When the the cell scrolls back on screen, you will need to make sure it is checked if this cell was selected before going off the screen,
// and you need to remove the checkmark on a cell if it is being reused
if items[indexPath.row].isSelected {
cell.accessoryType = UITableViewCellAccessoryType.Checkmark
} else {
cell.accessoryType = UITableViewCellAccessoryType.None
}
cell.selectionStyle = .None
return cell
}