【问题标题】:How to access the content of a custom cell in swift using button tag?如何使用按钮标签快速访问自定义单元格的内容?
【发布时间】:2015-07-06 22:17:24
【问题描述】:

我有一个在自定义单元格中有自定义按钮的应用。如果您选择单元格,它会转到详细视图,这是完美的。如果我在单元格中选择一个按钮,下面的代码会将单元格索引打印到控制台中。

我需要访问所选单元格的内容(使用按钮)并将它们添加到数组或字典中。我是新手,所以很难找到如何访问单元格的内容。我尝试使用 didselectrowatindexpath,但我不知道如何强制索引成为标签的索引...

所以基本上,如果有 3 个单元格,每个单元格中都有 'Dog'、'Cat'、'Bird' 作为 cell.repeatLabel.text,然后我选择第 1 行和第 3 行(索引 0 和 2)中的按钮,它应该将 'Dog' 和 'Bird' 添加到数组/字典中。

    // MARK: - Table View

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return postsCollection.count
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell: CustomCell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! CustomCell

    // Configure the cell...
    var currentRepeat = postsCollection[indexPath.row]
    cell.repeatLabel?.text = currentRepeat.product
    cell.repeatCount?.text = "Repeat: " + String(currentRepeat.currentrepeat) + " of " + String(currentRepeat.totalrepeat)

    cell.accessoryType = UITableViewCellAccessoryType.DetailDisclosureButton

    cell.checkButton.tag = indexPath.row;

    cell.checkButton.addTarget(self, action: Selector("selectItem:"), forControlEvents: UIControlEvents.TouchUpInside)


    return cell

}

func selectItem(sender:UIButton){

    println("Selected item in row \(sender.tag)")

 }

【问题讨论】:

    标签: uitableview swift uibutton tags tableviewcell


    【解决方案1】:

    选项 1.delegation

    处理它

    处理从单元格的子视图触发的事件的正确方法是使用委托

    因此您可以按照以下步骤操作:

    1. 在您的类定义上方编写一个协议,在您的自定义单元格中使用单个实例方法:

    protocol CustomCellDelegate {
        func cellButtonTapped(cell: CustomCell)
    } 
    

    2. 在你的类定义中声明一个委托变量并在委托上调用协议方法:

    var delegate: CustomCellDelegate?
    
    @IBAction func buttonTapped(sender: AnyObject) {
        delegate?.cellButtonTapped(self)
    }
    

    3. 符合你的表格视图所在类中的CustomCellDelegate:

     class ViewController: CustomCellDelegate
    

    4.设置您的单元格的代表

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as CustomCell
        cell.delegate = self
    
        return cell
    }
    

    5. 在您的视图控制器类中实现所需的方法。

    编辑:先定义一个空数组,然后修改如下:

    private var selectedItems = [String]()
    
    func cellButtonTapped(cell: CustomCell) {
        let indexPath = self.tableView.indexPathForRowAtPoint(cell.center)!
        let selectedItem = items[indexPath.row]
    
        if let selectedItemIndex = find(selectedItems, selectedItem) {
            selectedItems.removeAtIndex(selectedItemIndex)
        } else {
            selectedItems.append(selectedItem)
        }
    }
    

    items 是在我的视图控制器中定义的数组:

    private let items = ["Dog", "Cat", "Elephant", "Fox", "Ant", "Dolphin", "Donkey", "Horse", "Frog", "Cow", "Goose", "Turtle", "Sheep"] 
    

    选项 2. 使用 闭包

    处理它

    我决定回来向您展示处理此类情况的另一种方法。在这种情况下使用闭包将减少代码并实现您的目标。

    1. 在你的单元格类中声明一个闭包变量:

    var tapped: ((CustomCell) -> Void)?
    

    2. 在您的按钮处理程序中调用闭包。

    @IBAction func buttonTapped(sender: AnyObject) {
        tapped?(self)
    }
    

    3. 在包含视图控制器类的tableView(_:cellForRowAtIndexPath:) 中:

    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! CustomCell       
    cell.tapped = { [unowned self] (selectedCell) -> Void in
        let path = tableView.indexPathForRowAtPoint(selectedCell.center)!
        let selectedItem = self.items[path.row]
    
        println("the selected item is \(selectedItem)")
    }
    

    【讨论】:

    • 我比上面的更喜欢这个解决方案。不过,您忘了提到他必须实际设置委托。除此之外,解决方案是可靠的。
    • 我当然应该有,我的错。将编辑它。谢谢。
    • 非常感谢大家。它的作用就像一种魅力,让我对代表有了一点了解……仍然是一个新手。
    • 我知道我现在正在推动它,但我一直在绕圈子。我需要能够将 selectedItem 添加到数组中,但我不知道如何。我已经尝试将它添加到 cellButtonTapped 基金,但这不起作用。如果我选择了某些东西,它必须将它添加到数组中,如果我取消选择它,它必须从数组中删除它。这个想法是,一旦我有了数组,我将在用户单击“发送”按钮时将所选项目的结果发布到 mySQL 数据库......
    • 非常感谢。你是明星。效果很好。
    【解决方案2】:

    由于您在表格视图中有 1 个部分,您可以获取单元格对象,如下所示。

    let indexPath = NSIndexPath(forRow: tag, inSection: 0)
    let cell = tableView.cellForRowAtIndexPath(indexPath) as! CustomCell!
    

    您将从按钮标签获得的标签。

    【讨论】:

    • 即使只有一个部分,它也不会每次都起作用。假设您从 tableview 中删除了一个单元格,并且如果您将标签作为 indexPath 访问,它将给您错误的索引。所以请注意...
    【解决方案3】:

    斯威夫特 3 我只是使用按钮标签的超级视图在@IBAction 函数中获取访问单元格的解决方案。

    let cell = sender.superview?.superview as! ProductCell
    var intQty = Int(cell.txtQty.text!);
    intQty = intQty! + 1
    let  strQty = String(describing: intQty!);
    cell.txtQty.text = strQty
    

    【讨论】:

      【解决方案4】:
      @IBAction func buttonTap(sender: UIButton) {
              let button = sender as UIButton
              let indexPath = self.tableView.indexPathForRowAtPoint(sender.center)!
      }
      

      【讨论】:

        【解决方案5】:

        我更新了 Vasil Garov 为 Swift 3

        提供的答案选项 1

        1.为您的CustomCell 创建一个协议:

        protocol CustomCellDelegate {
            func cellButtonTapped(cell: CustomCell)
        } 
        

        2. 为您的TableViewCell 声明一个delegate 变量并在其上调用协议方法:

        var delegate: CustomCellDelegate?
        
        @IBAction func buttonTapped(sender: AnyObject) {
            delegate?.cellButtonTapped(self)
        }
        

        3. 符合你的tableView所在类中的CustomCellDelegate

         class ViewController: CustomCellDelegate
        

        4.设置你的单元格的delegate

        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)  as CustomCell
            cell.delegate = self
        
            return cell
        }
        

        5. 在您的ViewController 中实现所需的方法。

        【讨论】:

          【解决方案6】:

          根据曹的回答,这里是处理集合视图单元格中按钮的解决方案。

              @IBAction func actionButton(sender: UIButton) {
                  let point = collectionView.convertPoint(sender.center, fromView: sender.superview)
                  let indexPath = collectionView.indexPathForItemAtPoint(point)
          }
          

          请注意,convertPoint() 函数调用将转换集合视图空间中的按钮点坐标。 如果没有,indexPath 将始终引用同一个单元格编号 0

          【讨论】:

            【解决方案7】:

            XCODE 8:重要说明

            不要忘记将标签设置为不同于 0 的值。

            如果您尝试使用 tag = 0 投射对象,它可能会起作用,但在某些奇怪的情况下它不会。

            解决方法是将标签设置为不同的值。 希望它可以帮助某人。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-05-07
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多