Swift - 在TableView单元格中使用Stepper来增加标签值

3

这里是另一个Swift初学者。我想在每个TableView单元格中都放置一个Stepper,它可以递增同一单元格中的标签。

我找到了几个关于此主题的问题,但它们包含其他元素,我无法提取基本概念。

Swift Stepper Action that changes UITextField and UILabel within same cell

Stepper on tableview cell (swift)

到目前为止,我已经在我的单元格类中连接了Label和Stepper的IBOutlets,以及Stepper的IBAction。

class BuyStatsCell: UITableViewCell{

    //these are working fine

    @IBOutlet weak var category: UILabel!
    @IBOutlet weak var average: UILabel!
    @IBOutlet weak var price: UILabel!


    //Outlet for Label and Stepper - How do I make these work?

    @IBOutlet weak var purchaseAmount: UILabel!
    @IBOutlet weak var addSubtract: UIStepper!

    //Action for Stepper - And this?

    @IBAction func stepperAction(_ sender: UIStepper) {
        self.purchaseAmount.text = Int(sender.value).description

    }

}

我理解在cellForRowAt indexPath中重复使用cell的概念。

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "BuyStatsTabCell", for: indexPath) as! BuyStatsCell

        cell.isUserInteractionEnabled = false

 //these are working 

        cell.category.text = categories[indexPath.row]
        cell.price.text = String(prices[indexPath.row])
        cell.average.text = String(averages[indexPath.row])

//but is there something I need to add here to keep the correct Stepper and Label for each class?

    return cell
}

已经有人提出的问题包括在ViewController中添加协议和另一个函数,如下所示

protocol ReviewCellDelegate{
    func stepperButton(sender: ReviewTableViewCell)
}

func stepperButton(sender: ReviewTableViewCell) {
    if let indexPath = tableView.indexPathForCell(sender){
        print(indexPath)
    }
}

我不确定这是否是我应该尝试的方法。我正在寻找最简单的解决方案,但我很难将这些部分组合在一起。

任何帮助都将不胜感激。 谢谢。


为什么不使用单个源数组来存储产品模型,并将价格、平均值和类别作为属性添加呢? 然后,当您更改模型并重新加载更改后的模型时,它应该是持久的。 我不确定持久性是否是问题。 - silentBob
所以,你想要实现的是让步进电机根据“categories”行增加/减少当前对象的值,对吗? - Ahmad F
谢谢你们两位的回复。我为了澄清加了一些代码注释。分类、平均和价格都运行得很好。purchaseAmount是我想要用Stepper更新的标签。我的列表中每一行都有一个purchaseAmount和一个用于添加或减少的Stepper。 - Louis Sankey
正如@vadian建议的那样,我建议只让数组数据源包含模型,而不是从“categories”、“prices”和“averages”读取。也许查看这个Q&A(http://stackoverflow.com/questions/39738518/uitableview-filtering/39740482#39740482)会帮助你理解它。 - Ahmad F
2个回答

7

最简单的解决方案(简化版):

  • Create a model BuyStat with a property purchaseAmount (it's crucial to be a class).
    You are strongly discouraged from using multiple arrays as data source

    class BuyStat {
    
        var purchaseAmount = 0.0
    
        init(purchaseAmount : Double) {
            self.purchaseAmount = purchaseAmount
        }
    }
    
  • In the view controller create a data source array

    var stats = [BuyStat]()
    
  • In viewDidLoad create a few instances and reload the table view

    stats = [BuyStat(purchaseAmount: 12.0), BuyStat(purchaseAmount: 20.0)]
    tableView.reloadData()
    
  • In the custom cell create a property buyStat to hold the current data source item with an observer to update stepper and label when buyStat is set

    class BuyStatsCell: UITableViewCell {
    
        @IBOutlet weak var purchaseAmount: UILabel!
        @IBOutlet weak var addSubtract: UIStepper!
    
        var buyStat : BuyStat! {
            didSet {
                addSubtract.value = buyStat.purchaseAmount
                purchaseAmount.text = String(buyStat.purchaseAmount)
            }
        }
    
        @IBAction func stepperAction(_ sender: UIStepper) {
            buyStat.purchaseAmount = sender.value
            self.purchaseAmount.text = String(sender.value)
        }
    }
    
  • In cellForRowAtIndexPath get the data source item and pass it to the cell

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "BuyStatsTabCell", for: indexPath) as! BuyStatsCell
        cell.buyStat = stats[indexPath.row]
        return cell
    }
    
魔法在于:当您点击步进器时,标签和数据源数组将被更新。因此,即使滚动,单元格也始终会获得实际数据。

通过这种方式,您不需要协议或回调闭包。唯一重要的是模型是一个类来具有引用类型语义。


我仍然无法使步进电机有任何响应。不知道我做错了什么,因为我已经尝试多次重新连接步进电机插座和动作。 :-/ 我在我的IBAction中放置了一个打印语句,但它没有起作用。这里是一些屏幕截图 https://i.stack.imgur.com/zpnvt.png https://i.stack.imgur.com/J6p7x.png - Louis Sankey
如果我有默认值,比如 priceLabel.text = 15,并且想要通过点击 stepper 来增加这个值(例如,2 次点击将 15+15=30 赋值给它),该怎么办? - Emre Değirmenci
@EmreDeğirmenci 调整步进器实例中的 stepValue - vadian
1
在 Interface Builder 中选择步进器,按下 ⌥⌘4 打开属性检查器,并将 Step 设置为 15。 - vadian
@EmreDeğirmenci 请提出一个新问题。 - vadian
显示剩余4条评论

0

注意:我的Cell类只是普通的..所有更改都在视图控制器类中

class cell: UITableViewCell {

    @IBOutlet weak var ibAddButton: UIButton!
    @IBOutlet weak var ibStepper: UIStepper!
    @IBOutlet weak var ibCount: UILabel!
    @IBOutlet weak var ibLbl: UILabel!
}

1. 定义空的整型数组 [Int]()

var countArray = [Int]()

2. 将 countArray 填充为指定数量的零,以便在表格视图中使用

 for arr in self.responseArray{
        self.countArray.append(0)
   }

3.在行的单元格中

func tableView(_ tableView: UITableView, cellForRowAt indexPath:
 IndexPath) -> UITableViewCell {

         let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! cell
         let dict = responseArray[indexPath.row] as? NSDictionary ?? NSDictionary()
         cell.ibLbl.text = dict["name"] as? String ?? String()
         if countArray[indexPath.row] == 0{
             cell.ibAddButton.tag = indexPath.row
             cell.ibStepper.isHidden = true
             cell.ibAddButton.isHidden = false
             cell.ibCount.isHidden = true
             cell.ibAddButton.addTarget(self, action: #selector(addPressed(sender:)), for: .touchUpInside)
         }else{
             cell.ibAddButton.isHidden = true
             cell.ibStepper.isHidden = false
             cell.ibStepper.tag = indexPath.row
             cell.ibCount.isHidden = false
             cell.ibCount.text = "\(countArray[indexPath.row])"
             cell.ibStepper.addTarget(self, action: #selector(stepperValueChanged(sender:)), for: .valueChanged)}
    return cell
     }

4个Objective-C函数

 @objc func stepperValueChanged(sender : UIStepper){
     if sender.stepValue != 0{
         countArray[sender.tag] = Int(sender.value)
     }
     ibTableView.reloadData()
 }
 @objc func addPressed(sender : UIButton){

     countArray[sender.tag] = 1//countArray[sender.tag] + 1
     ibTableView.reloadData()
 }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接