【问题标题】:Removing items from array in custom tableViewCell从自定义uitableViewCell中的数组中删除项目
【发布时间】:2019-07-01 02:56:20
【问题描述】:

我有一个自定义tableviewHeaderFooterView,我在其中为自定义tableViewCell 类中的按钮设置了一个目标事件(checkButton 是按钮,当用户单击它时,它的背景图像会变为复选标记)。

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {

    let userModel = Data.userModels[section]
    let cell = tableView.dequeueReusableCell(withIdentifier: "cellId") as! SectionHeader

    cell.setup(model: userModel)
    cell.checkButton.tag = section
    cell.checkButton.addTarget(self, action: #selector(handleTap), for: .touchUpInside) 

    return cell.contentView
}

在该函数中,我想根据用户是否点击单元格来创建或删除数组中的项目(即,如果他们点击按钮,然后向数组中添加一些内容,但如果他们点击那个再次按钮,然后从数组中删除该对象。)

@objc func handleTap(sender: UIButton) {
    sender.isSelected = !sender.isSelected

    if sender.isSelected == true {
        let model = ItemModel(itemName: item, price: price)
        ItemModelFunctions.createItem(for: sender.tag, using: model)
    }
    if sender.isSelected == false {
        ItemModelFunctions.removeFromUser(from: sender.tag)
    }
    print(sender.tag)
}

这里是createItemremoveFromUser 函数:

  struct ItemModelFunctions {
    static func createItem(for userIndex: Int, using itemModel: ItemModel) {
        Data.userModels[userIndex].itemModels.append(itemModel)

    }
    static func removeFromUser(from userIndex: Int) {
        Data.itemModels.remove(at: userIndex)
    }
}

当我点击按钮两次以将其从数组中删除时,我收到一条错误消息,提示 Data.itemModels.remove(at: userIndex) 超出范围。

我知道为tableViewHeaderFooterView 使用原型单元格并不完全正确,但我已经看到其他程序员和 YouTube 用户成功地做到了这一点。我的问题来自使用原型单元吗?还是我以错误的方式从数组中删除了该项目?谢谢大家的帮助!

【问题讨论】:

    标签: arrays swift uitableview


    【解决方案1】:
       // Please maintain one more array i.e selectedIndexArray and follow below code.
    
         var  selectedIndexArray  = [Integer]()
    
            @IBAction func buttonTapped(_ sender: UIButton) {
    
                let button = sender
                if selectedIndexArray.contains(button.tag) {
                    button.tag --> Remove this tag from  selectedIndexArray
                    let model = ItemModel(itemName: item, price: price)
                    ItemModelFunctions.createItem(for: sender.tag, using: model)
                } else
                {
                    selectedIndexArray.append(button.tag)
                    ItemModelFunctions.removeFromUser(from: sender.tag)
                }
                //reload tableview.
    self.tableView.reloadData()
            }
    

    【讨论】:

      【解决方案2】:

      checkButton.addTarget 函数将在每次重用节标题时运行。 然后它会在多次重复使用时为单元格复制事件。 我认为你不应该使用这个解决方案。相反,我认为您应该编写委托方式来解决您的问题。 例如:

      protocol SectionHeaderDelegate: class {
          func checkButtonDidTap(section: SectionHeader)
      }
      
      class SectionHeader: UITableViewCell {
          weak var delegate: SectionHeaderDelegate
          @IBOutlet weak var checkButton: UIButton!
      
          override func awakeFromNib() {
              super.awakeFromNib()
      
              checkButton.addTarget(self, action: #selector(handleTap), for: .touchUpInside) 
          }
      
          func handleTap() {
              self.delegate.checkButtonDidTap(section: self)
          }
      }
      

      然后你在viewForHeaderInSection 函数中设置了 cell.delegate = self。并实现协议SectionHeaderDelegate。

      【讨论】:

      • 这很有帮助,但你能帮我理解吗?那么在协议方法中我将在哪里编写我最初在handleTap函数中拥有的代码?
      • 是的,当点击 checkButton 将事件传递给 viewController 时,SectionHeader 调用委托。您需要在 SectionHeaderDelegate 中实现方法来处理。在该方法中,您将编写类似@objc func handleTap(sender: UIButton) 函数的代码。 :D。 section 变量可帮助您找到已点击的单元格的 indexPath。
      • 您可以参考这里:fluffy.es/…
      • 我尝试了这个解决方案并尝试打印一个字符串只是为了查看它是否被调用,并且似乎没有调用我的 ViewController 中的协议函数。
      • 您是否忘记了通过委托变量调用函数?或者忘记设置委托属性
      【解决方案3】:

      Thanh Vu 的解决方案有效。另一种解决方案是将 IBAction 添加到您的 ViewController:

      @IBAction func buttonTapped(_ sender: UIButton) {
          sender.isSelected = !sender.isSelected
          let cell = sender.superview?.superview as! SectionHeader
          if let indexPath = mainTableView.indexPath(for: cell) {
              // if sender.isSelected etc...
          }
      }
      

      【讨论】:

      • 即使在我的所有单元格中重复使用该按钮,这种方法是否有效?像我可以更改某些单元格的按钮属性吗?抱歉,我是 swift 新手,正在努力理解。
      • 是的,即使在您的所有单元格中重复使用该按钮,这也会起作用。要更改单个按钮的属性,只需在 cellForRowAt 函数中执行此操作。如果您想知道哪个按钮是发送者,请使用 tag 属性。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-03
      • 2021-10-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多