【问题标题】:How to access custom UITableViewCell from main ViewController如何从主 ViewController 访问自定义 UITableViewCell
【发布时间】:2018-06-05 06:03:46
【问题描述】:

我有一个带有 UITableView 的主视图控制器。表格视图有 2 个在 IB 中原型化的单元格。

Prototyped Cells

第一个单元格在第 0 节中,第二个单元格在第 1 节中(始终位于表格底部)。

这是我在主 ViewController 中的表定义:

    func numberOfSections(in tableView: UITableView) -> Int {
    return 2
    }

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if section == 0 {
    return itemNames.count
    } else {
    return 1
    }
}

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

// Created additional section where will be the cell for adding items (always at bottom)
    switch indexPath.section {
    case 0:
    let cellIdentifier = "itemCell"
    let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! ItemTableViewCell

    cell.itemNameTextView.text = itemNames[indexPath.row]
    let currentImage = itemImages[indexPath.row]
    cell.itemStateButton.setImage(UIImage(named: currentImage), for: UIControlState.normal)

    return cell

    case 1:
    let cellIdentifier = "addItemCell"
    let addCell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! ItemTableViewCell

    addCell.addItemButton.setImage(UIImage(named: "plus-math-40"), for: UIControlState.normal)

    return addCell

    default:
    return UITableViewCell()
    }
}

所有到单元格的 Outlets 都在自定义 UITableViewCell 中定义:

class ItemTableViewCell: UITableViewCell {

@IBOutlet var itemNameTextView: UITextView!
@IBOutlet var itemStateButton: UIButton!
@IBOutlet var addItemButton: UIButton!
@IBOutlet var addTextView: UITextView!

如何从主 ViewController 访问 ItemTableViewCell 中的 outlets 变量的值(读取和更改)?

例如,当在第二个单元格中按下“+”按钮时,我需要将TextView变成FirstResponder,然后保存TextFiled的值。

我还需要编辑 0 节单元格上的 TextFields,然后从中保存数据。

【问题讨论】:

标签: ios swift uitableview


【解决方案1】:

如果你只有 2 个没有。部分和每个部分中的一行,那么您可以赋予 addItemButton 标记值等于部分编号。然后向该按钮添加操作并定义相应的选择器。在该选择器方法中,从发送者的标签中获取节值,并获取对应于节和行(=0)的索引路径。从那个 indexpath 中,获取 cell,然后你就可以访问主控制器中 Cell 的任何出口。

谢谢

【讨论】:

    【解决方案2】:

    你想要

    1. 在自定义UITableViewCell 上获取按钮按下事件
    2. 从主 UIViewController 更改 IBOutlet 值

    首先要在单元格对象上获得 button press 事件,您有 2 个选项:

    1.1 实例化单元格时附加一个目标:

    // In your tableView cellForRow method
    addCell.addItemButton.addTarget(self, action: #selector(bringUpTextfieldMethod), for: .touchUpInside)
    

    1.2 使用委托结构:让ItemTableViewCell 声明委托协议,通过IBAction 插座捕获此类中的按钮按下事件,并使用委托传递事件。主 ViewController 符合协议并实现委托回调。

    其次 - 访问单元格的 IBOutlets。您需要访问单元格的任何地方:

    let indexPath = IndexPath.init(row: 0, section: 0) // Obviously with the correct row/sec
    let itemCell = tableView.cellForRowAtIndexPath(indexPath) as! ItemTableViewCell  // your tableview must be an IBOutlet on your view controller
    
    // Now you can access properties on itemCell
    // e.g:
    let name = itemCell.itemNameTextView.text 
    

    【讨论】:

      【解决方案3】:

      我已将当前单元格定义为自定义单元格实例(这是在完成单元格中的 TextView 编辑后将数据保存到 CoreData 的代码):

      func textViewDidEndEditing(_ textView: UITextView) {
      
          currentTextView = nil
      
          // Finished edit tex tin text view. Save new values to CoreData
          let currentCell = tableView.cellForRow(at: currentIndexPath) as! ItemTableViewCell
          if let appDelegate = (UIApplication.shared.delegate as? AppDelegate) {
      
              // Add Mode. Adding values from addItemCell to CoreData
              if editMode == false {
                  // In add mode we need to add a new record to CoreData
                  // Check if textview is not empty
                  if currentCell.addTextView.text != "" {
                  shoppingItem = ItemMO(context: appDelegate.persistentContainer.viewContext)
                  shoppingItem.itemName = currentCell.addTextView.text
                  shoppingItem.itemCreatedDate = Date()
                  shoppingItem.itemDone = false
                  currentCell.addTextView.text = ""
                  }
              } else {
                  // In edit mode we need to save current values and save context
                  if currentCell.itemNameTextView.text != "" {
                  shoppingItems[currentIndexPath.row].itemName = currentCell.itemNameTextView.text
                  }
                  }
              appDelegate.saveContext()
              tableView.reloadData()
              }
      
          }
      

      我在开始编辑单元格时采用的 currentIndexPath 值:

      func textViewDidBeginEditing(_ textView: UITextView) {
      
          currentTextView = textView
      
          var superview = textView.superview
          while let view = superview, !(view is UITableViewCell) {
              superview = view.superview
          }
          guard let cell = superview as? UITableViewCell else {
              //print("button is not contained in a table view cell")
              return
          }
          guard let indexPath = tableView.indexPath(for: cell) else {
              //print("failed to get index path for cell containing button")
              return
          }
      
          // Setup current index path value
          self.currentIndexPath = indexPath
      
          // Setup edit mode for data saving in textViewDidEndEditing
          if currentIndexPath.section == 0 {
              editMode = true
          } else {
              if currentIndexPath.section == 1 {
                  editMode = false
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2016-02-03
        • 1970-01-01
        • 2019-06-22
        • 2023-04-11
        • 1970-01-01
        • 1970-01-01
        • 2015-12-02
        • 1970-01-01
        • 2011-05-21
        相关资源
        最近更新 更多