Swift - 在 TableView 单元中使用步进器增加标签

Posted

技术标签:

【中文标题】Swift - 在 TableView 单元中使用步进器增加标签【英文标题】:Swift - Increment Label with Stepper in TableView Cell 【发布时间】:2017-08-10 03:29:37 【问题描述】:

这里是另一个 Swift 初学者。我只想在我的每个 TableView 单元格中都有一个步进器,它可以增加同一单元格中的标签。

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

Swift Stepper Action that changes UITextField and UILabel within same cell

Stepper on tableview cell (swift)

到目前为止,我已经为我的标签和步进器连接了 IBOutlets,并为我的单元类中的步进器连接了一个 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 中重用单元格的概念

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)
    

我不知道这是否是我应该尝试采用的方法。我正在寻找最简单的解决方案,但我无法将各个部分组合在一起。

感谢任何帮助。 谢谢。

【问题讨论】:

为什么不使用带有产品型号的单源数组,并添加价格、平均值和类别作为属性?然后,当您更改模型并重新加载更改后的模型时,它应该是持久的。我不确定持久性是否是问题所在。 那么,你想要实现的是让步进器根据categories 的行来增加/减少当前对象的值,对吧? 谢谢两位的回复。我在代码中添加了一些 cmets 以进行澄清。类别、平均和价格都运行良好。 purchaseAmount 是我尝试使用 Stepper 更新的标签。我列表中的每一行都有一个 purchaseAmount 和一个用于加减的 Stepper。 正如@vadian 建议的那样,我建议让数组数据源只有一个,包含模型,而不是从categoriespricesaverages 读取。也许检查this Q&A 会帮助你理解它。 【参考方案1】:

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

使用属性purchaseAmount 创建一个模型BuyStat(作为一个类至关重要)。强烈建议您不要使用多个数组作为数据源

class BuyStat 

    var purchaseAmount = 0.0

    init(purchaseAmount : Double) 
        self.purchaseAmount = purchaseAmount
    

在视图控制器中创建数据源数组

var stats = [BuyStat]()

viewDidLoad 创建几个实例并重新加载表格视图

stats = [BuyStat(purchaseAmount: 12.0), BuyStat(purchaseAmount: 20.0)]
tableView.reloadData()

在自定义单元格中创建属性buyStat 来保存当前数据源项,并在设置buyStat 时使用观察者更新步进器和标签

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)
    

cellForRowAtIndexPath中获取数据源项并传递给单元格

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

神奇的是:当您点击步进器时,标签以及数据源数组将被更新。因此,即使在滚动单元格之后,也将始终获得实际数据。

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

【讨论】:

我认为这种方法比在 ViewController 层处理步进器的动作更好,通过识别当前步进器-通过为每个步进器添加标签-、编辑数组数据源的值并调用reloadData(),我觉得它更解耦和合乎逻辑,对吗? :) 感谢您的出色回答。我相信我将能够在此基础上实施。因此,当您说 'stats = [BuyStat(purchaseAmount: 12.0), BuyStat(purchaseAmount: 20.0)] tableView.reloadData()' 时,这是为 purchaseAmount 创建两个初始值为 12 和 20 的列表行吗?然后使用步进器来增加或减少该数量? 就是,最大的好处是对数据源项的引用,所以视图和模型是同时更新的。 @ithinkthereforeIprogr'am' 是的,没错。 我仍然无法让 Stepper 完全响应。不知道我做错了什么,因为我多次尝试重新连接 Stepper 插座和操作。 :-/ 我在 IBAction 中放了一个打印语句,但它不起作用。这是几个截图i.stack.imgur.com/zpnvt.pngi.stack.imgur.com/J6p7x.png @EmreDeğirmenci 在 Interface Builder 中选择步进器,按 ⌥⌘4 打开 Attributes Inspector 并将 Step 设置为 15【参考方案2】:

注意:我的 Cell 类是正常​​的。所有更改都在 viewcontroller 类中

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数组[Int]()

var countArray = [Int]()

2.append countArray 与你想在 tableview 中填充的数据数量全为零

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

3.in 单元格中的行

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.objc函数

 @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()
 

【讨论】:

以上是关于Swift - 在 TableView 单元中使用步进器增加标签的主要内容,如果未能解决你的问题,请参考以下文章

Swift:如何在 tableView 中模糊点击单元格

错误:在 swift 中使用 xib 文件注册自定义 tableView 单元格

TableView 在 Swift 中使用重复的单元格项目继续向下滚动

swift中tableView的单元格高度扩展时更改标签文本

如何使用 Swift 从 tableview 单元格中获取数据而不显示在标签上?

使用 swift 向 tableview 单元格添加约束