问题描述
我制作了一个带有标签的表格视图,该标签在按下按钮和另一个按钮时递增和递减,以在 UItableView 之外的另一个标签中显示文本。一切正常,但是当我滚动 Tableview 时,该值重置为零!
Before Scrolling After Scrolling
我的 ViewController 类
class ViewController: UIViewController{
var numArray = [Value]()
var initialValue = 0
@IBOutlet weak var tableView : UITableView!
@IBOutlet weak var lblOutput : UILabel!
override func viewDidLoad() {
super.viewDidLoad()
for _ in 0 ... 100{
numArray.append(Value(number: initialValue))
}
self.lblOutput.text = "\(initialValue)"
tableView.delegate = self
tableView.dataSource = self
tableView.reloadData()
}
}
extension ViewController : UITableViewDelegate,UITableViewDataSource{
func tableView(_ tableView: UITableView,numberOfRowsInSection section: Int) -> Int {
return numArray.count
}
func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "Cell",for: indexPath) as? ControllerTableViewCell else{fatalError("Error in creating cells")}
cell.delegate = self
cell.data = numArray[indexPath.row]
cell.lblInput.text = "\(cell.data.number)"
return cell
}
}
extension ViewController : MyTableViewCellDelegate{
func DidPrint(Data: String) {
self.lblOutput.text = "\(Data)"
}
}
我的 TableViewCell 类
protocol MyTableViewCellDelegate : AnyObject {
func DidPrint(Data: String)
}
class ControllerTableViewCell: UITableViewCell {
weak var delegate : MyTableViewCellDelegate?
var data : Value!
private var counterValue = 0
@IBOutlet var lblInput : UILabel!
@IBOutlet var btnPrint : UIButton!
@IBOutlet var btnPlus : UIButton!
@IBOutlet var btnMinus : UIButton!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
@IBAction func DidPressprint(){
self.data.number = counterValue
delegate?.DidPrint(Data: "\(data.number)")
print(data.number)
}
@IBAction func DidPressplus(){
counterValue += 1
data.number = counterValue
self.lblInput.text = "\(data.number)"
}
@IBAction func DidPressMinus(){
if(counterValue > 0){
counterValue -= 1
data.number = counterValue
}
else{
counterValue = 0
data.number = 0
}
self.lblInput.text = "\(data.number)"
}
}
我的数据模型
import Foundation
struct Value{
var number : Int
}
解决方法
正如@El Tomato 所建议的那样,您没有更新数据源,这就是为什么您的更改在滚动时被“遗忘”的原因。
尝试在您的 didPressPlus
类中移动您的 didPressMinus
、didPressPrint
和 ViewController
,并重新定义您的表视图委托,如下所示。
通过将 tag
属性传递给按钮,您可以检索在函数中按下的项目的索引并编辑正确的数据源项目。
同时删除不必要的 MyTableViewCellDelegate
。
class ViewController: UIViewController{
var numArray = [Value]()
var initialValue = 0
@IBOutlet weak var tableView : UITableView!
@IBOutlet weak var lblOutput : UILabel!
override func viewDidLoad() {
super.viewDidLoad()
for _ in 0 ... 100 {
numArray.append(Value(number: initialValue))
}
self.lblOutput.text = "\(initialValue)"
tableView.delegate = self
tableView.dataSource = self
}
}
extension ViewController : UITableViewDelegate,UITableViewDataSource
{
func tableView(_ tableView: UITableView,numberOfRowsInSection section: Int) -> Int {
return numArray.count
}
func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "Cell",for: indexPath) as? ControllerTableViewCell else {fatalError("Error in creating cells")}
let indexItem = indexPath.row
let valueItem = numArray[indexItem]
cell.lblInput.text = valueItem.number
cell.btnMinus.tag = indexItem
cell.btnMinus.addTarget(self,action: #selector(didPressMinus(_:)),for: .touchUpInside)
cell.btnPlus.tag = indexItem
cell.btnPlus.addTarget(self,action: #selector(didPressPlus(_:)),for: .touchUpInside)
cell.btnPrint.tag = indexItem
cell.btnPrint.addTarget(self,action: #selector(didPressPrint(_:)),for: .touchUpInside)
return cell
}
@objc private func didPressPlus(_ sender: UIButton) {
let dataIndex = sender.tag
if numArray.count < dataIndex { return }
let numArrayItem = numArray[dataIndex]
if (numArrayItem.number >= 0) {
numArray[dataIndex].number -= 1
}
tableView.reloadData()
}
@objc private func didPressMinus(_ sender: UIButton) {
let dataIndex = sender.tag
if numArray.count < dataIndex { return }
numArray[dataIndex].number += 1
tableView.reloadData()
}
@objc private func didPressPrint(_ sender: UIButton) {
let dataIndex = sender.tag
if numArray.count < dataIndex { return }
self.lblOutput.text = "\(numArray[dataIndex].number)"
}
}
为了移动 ViewController
中的三个方法,您需要从 IBAction
类中删除两个对应的 UITableViewCell
。
此外,删除与 ControllerTableViewCell
操作的链接。
这是结果 ControllerTableViewCell
:
class ControllerTableViewCell: UITableViewCell {
@IBOutlet var lblInput : UILabel!
@IBOutlet var btnPrint : UIButton!
@IBOutlet var btnPlus : UIButton!
@IBOutlet var btnMinus : UIButton!
override func awakeFromNib() {
super.awakeFromNib()
}
}
,
您的 TableView 的 numberOfRowsInSection 使用 numArray 作为源 (numArray.count),您的 cellForRowAt 函数也是如此,但您的单元格函数正在更新您的“数据”变量。您的“数据”变量在本地定义到您的 tableView 并在每次激活时(包括滚动时)重置。 您需要更新 numArray 或其他一些全局资源以使其工作。这涉及在单元格函数内使用单元格值的 indexpath,这意味着您需要一种方法来引用单元格内的 indexPath。本文介绍了如何使用标签或委托,https://fluffy.es/handling-button-tap-inside-uitableviewcell-without-using-tag/。
这是使用现有委托的解决方案。
import UIKit
import Foundation
var initialValue = 0
var numArray = Array(repeating: initialValue,count: 100)
class ViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var lblOutput: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
self.lblOutput.text = "\(initialValue)"
tableView.delegate = self
tableView.dataSource = self
tableView.reloadData()
// Do any additional setup after loading the view.
}
}
extension ViewController : UITableViewDelegate,UITableViewDataSource{
func tableView(_ tableView: UITableView,numberOfRowsInSection section: Int) -> Int {
return numArray.count
}
func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "Cell",for: indexPath) as? ControllerTableViewCell else{fatalError("Error in creating cells")}
cell.indexPath = indexPath
cell.delegate = self
cell.lblInput.text = String(numArray[indexPath.row])
return cell
}
}
extension ViewController : MyTableViewCellDelegate{
func DidPrint(Data: String) {
self.lblOutput.text = "\(Data)"
}
}
protocol MyTableViewCellDelegate : AnyObject {
func DidPrint(Data: String)
}
class ControllerTableViewCell: UITableViewCell {
weak var delegate : MyTableViewCellDelegate?
var indexPath : IndexPath?
private var counterValue = 0
@IBOutlet var lblInput : UILabel!
@IBOutlet var btnPrint : UIButton!
@IBOutlet var btnPlus : UIButton!
@IBOutlet var btnMinus : UIButton!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
@IBAction func DidPressPrint(){
delegate?.DidPrint(Data: "\(numArray[indexPath!.row])")
}
@IBAction func DidPressPlus(){
numArray[indexPath!.row] = numArray[indexPath!.row] + 1
self.lblInput.text = "\(numArray[indexPath!.row])"
}
@IBAction func DidPressMinus(){
if(numArray[indexPath!.row] > 0){
numArray[indexPath!.row] = numArray[indexPath!.row] - 1
}
else{
numArray[indexPath!.row] = 0
}
self.lblInput.text = "\(numArray[indexPath!.row])"
}
}