的問題是,細胞被重用,當您更新一個對號,您要更新單元,但不更新模型。因此,當一個單元格滾動出視圖並且單元格被重用時,您的cellForRowAt
顯然不會重置表格新行的複選標記。
同樣,如果您將單元格滾回到視圖中,cellForRowAt
無法知道是否應該檢查單元格。您必須
因此,首先確保您的模型具有一些值來指示它是否被選中或未選中。在這個例子中,我將使用「項目」,但你會使用一個更有意義的類型名稱:
struct Item {
let name: String
var checked: Bool
}
然後您的視圖控制器可適當cellForRowAt
填充細胞:
class ViewController: UITableViewController {
var items: [Item]!
override func viewDidLoad() {
super.viewDidLoad()
addItems()
}
/// Create a lot of sample data so I have enough for a scrolling view
private func addItems() {
let formatter = NumberFormatter()
formatter.numberStyle = .spellOut
items = (0 ..< 1000).map { Item(name: formatter.string(from: NSNumber(value: $0))!, checked: false) }
}
}
extension ViewController {
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ItemCell", for: indexPath) as! ItemCell
cell.delegate = self
cell.textLabel?.text = items[indexPath.row].name
cell.accessoryType = items[indexPath.row].checked ? .checkmark : .none
return cell
}
}
現在,我通常讓單元格處理諸如識別手勢之類的東西,並相應地通知視圖控制器。因此,創建一個UITableViewCell
子類,並將其指定爲故事板上單元格原型的基類。但細胞需要一些協議,用於向一個長按發生的視圖控制器:
protocol ItemCellDelegate: class {
func didLongPressCell(_ cell: UITableViewCell)
}
而且表視圖控制器可以處理此委託方法,切換它的型號和相應重裝電池:
extension ViewController: ItemCellDelegate {
func didLongPressCell(_ cell: UITableViewCell) {
guard let indexPath = tableView.indexPath(for: cell) else { return }
items[indexPath.row].checked = !items[indexPath.row].checked
tableView.reloadRows(at: [indexPath], with: .fade)
}
}
然後,UITableViewCell
子類只需要一個長按手勢識別,並且在該手勢被識別,通知視圖控制器:
class ItemCell: UITableViewCell {
weak var delegate: CellDelegate?
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
let longPress = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress(_:)))
addGestureRecognizer(longPress)
}
@IBAction func handleLongPress(_ gesture: UILongPressGestureRecognizer) {
if gesture.state == .began {
delegate?.didLongPressCell(self)
}
}
}
順便說一下,通過在手機上設置手勢,它可以避免由於「如果我長時間按在不是手機的東西上會發生什麼」的混淆。單元格是手勢識別器的正確位置。
來源
2017-09-21 19:53:35
Rob
你想讓我幫你格式化嗎?如果你長時間沒有牢房,這也會崩潰,我也可以爲你解決這個問題。 –