微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 UITableView 中滚动时标签数据丢失

如何解决在 UITableView 中滚动时标签数据丢失

我制作了一个带有标签的表格视图,该标签在按下按钮和另一个按钮时递增和递减,以在 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 类中移动您的 didPressMinusdidPressPrintViewController,并重新定义您的表视图委托,如下所示。
通过将 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])"
}

}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。