【问题标题】:Adding a gesture recognizer to an image view in a table cell将手势识别器添加到表格单元格中的图像视图
【发布时间】:2017-07-12 05:10:56
【问题描述】:

如何将手势识别器添加到表格单元格中的UIImageView?我想要这样,如果用户点击单元格中的图像,图像将会改变并且数据模型将会更新。

我知道这需要在UITableViewController 中进行设置。如果点击单元格中的任何位置,我的代码当前可以执行命令,但我希望它仅在点击图像时执行,而不是单元格中的任何位置。

我在viewDidLoad中设置了手势识别器

override func viewDidLoad() {
    super.viewDidLoad()

    // Load sample data
    loadSampleHabits()

    // Initialize tap gesture recognizer
    var recognizer = UITapGestureRecognizer(target: self, action: #selector(tapEdit(recognizer:)))
    // Add gesture recognizer to the view
    self.tableView.addGestureRecognizer(recognizer)

这就是函数

//action method for gesture recognizer
func tapEdit(recognizer: UITapGestureRecognizer) {
    if recognizer.state == UIGestureRecognizerState.ended {
        let tapLocation = recognizer.location(in: self.tableView)
        if let tapIndexPath = self.tableView.indexPathForRow(at: tapLocation) {
            if let tappedCell = self.tableView.cellForRow(at: tapIndexPath) as? HabitTableViewCell {
                print("Row Selected")

            }
        }
    }

作为第二个问题,如果我想将手势识别器添加到单元格和单元格内的图像视图,是否有任何冲突?

【问题讨论】:

  • 您可以尝试从您的方法中删除 if Recognizer.state == UIGestureRecognizerState.ended 条件。检查我的答案。
  • @b.gibson:我会适应luckyShubhra 的回答。我也在我的一个项目中的某个地方使用了相同的东西,没有遇到任何问题
  • 如果您要在图像视图中使用UITapGestureRecognizer,则无需检查state。这实际上只与连续手势相关(如长按或平移手势)。但对我来说,仅仅使用带有图像的按钮(如iOS Dev suggested)就更有意义了。

标签: ios swift uitableview


【解决方案1】:

您正在根据需要在 tableview 而不是 imageView 上添加手势识别器。您需要将代码从 viewDidLoad 移动到 cellForRowAtIndexPath 并在配置单元格时向每个单元格中的 imageView 添加手势。

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
     var recognizer = UITapGestureRecognizer(target: self, action: #selector(tapEdit(recognizer:)))
     // Add gesture recognizer to your image view
     cell.yourimageview.addGestureRecognizer(recognizer)
}

注意:请确保启用图像视图的userinteraction

cell.yourimageview.userInteractionEnabled = YES;

根据您的要求,我建议使用 UILongPressGestureRecognizer,因为它在手势和 didselect 中发生冲突的可能性较小。您可以在 viewDidLoad 中添加 UILongPressGestureRecognizer 并根据您的要求访问它。

let lpgr = UILongPressGestureRecognizer(target: self, action: #selector(ViewController.handleLongPress(_:)))
lpgr.minimumPressDuration = 1
tableView.addGestureRecognizer(lpgr)

定义方法为

func handleLongPress(_ gesture: UILongPressGestureRecognizer){
if gesture.state != .began { return }
let tapLocation = gesture.location(in: self.tableView)
    if let tapIndexPath = self.tableView.indexPathForRow(at: tapLocation) {
        if let tappedCell = self.tableView.cellForRow(at: tapIndexPath) as? HabitTableViewCell {
            print("Row Selected")

        }
}

您可以尝试从您的方法中删除if recognizer.state == UIGestureRecognizerState.ended 条件。

UITapGestureRecognizer 是一个离散的手势,因此,当手势被识别时,您的事件处理程序只会被调用一次。您根本不必检查状态。当然,您不会收到关于 .Began 状态的调用。有关更多信息,请考虑 @Rob 和 here

【讨论】:

  • 在单元格中的 UIimage 上添加类似点击手势的位置相似,一个好的技巧是最小化 lpgr.minimumPressDuration = 0.01 以复制点击
  • 效果很好!我创建了一个单选按钮组,可以无缘无故快速消除!我在两个 UIImageView 中添加了一个水龙头(两个不同的图像(circle 和 largecircle.fill.circle)。#selector 函数交换两个 UIImageView 的图像并更新链接到 Radio Button Group 状态的 NSManagedObject。函数: func tapEdit(recognizer: UITapGestureRecognizer) 成功了!他们使用相同的函数来交换按钮的状态。谢谢。
【解决方案2】:

在单元格中添加这一行作为索引路径处的行

     var recognizer = UITapGestureRecognizer(target: self, action: #selector(tapEdit(recognizer:)))
        // Add gesture recognizer to the view
        cell.yourimageviewname.addGestureRecognizer(recognizer)

cell.yourimageviewname.userInteractionEnabled = true;

【讨论】:

  • 更改 cell.youtimageviewname.isUserInteractionEnabled = true
【解决方案3】:

对于我的建议,您必须在单元格中使用UIButton,以提高性能 改进,

UIButtons

专门为此而设计,并已被 Apple 针对触控进行了广泛优化。

如果你想在单元格中使用图片,你可以使用UIButton 和里面的图片。

【讨论】:

    【解决方案4】:

    我曾设计过这样的解决方案。我只是在下面写了一个示例代码:

    import UIKit
    
    protocol CellImageTapDelegate {
        func tableCell(didClickedImageOf tableCell: UITableViewCell)
    }
    
    class SampleCell : UITableViewCell {
    
        var delegate : CellImageTapDelegate?
        var tapGestureRecognizer = UITapGestureRecognizer()
    
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
            initialize()
        }
    
        private func initialize() {
            tapGestureRecognizer.addTarget(self, action: #selector(SampleCell.imageTapped(gestureRecgonizer:)))
            self.addGestureRecognizer(tapGestureRecognizer)
        }
    
        func imageTapped(gestureRecgonizer: UITapGestureRecognizer) {
            delegate?.tableCell(didClickedImageOf: self)
        }
    }
    
    class ViewController: UITableViewController, CellImageTapDelegate {
    
        // CellImageTapDelegate
        func tableCell(didClickedImageOf tableCell: UITableViewCell) {
            if let rowIndexPath = tableView.indexPath(for: tableCell) {
                print("Row Selected of indexPath: \(rowIndexPath)")
            }
        }
    
        override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return 10
        }
    
        override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCell(withIdentifier: "SampleCellID", for: indexPath) as! SampleCell
            cell.delegate = self
            return cell
        }
    }
    

    记得在情节提要中进行以下操作 1.启用imageview的用户交互 2.设置tableviewcell的类 3.设置tableviewcell的复用标识

    【讨论】:

    • 此解决方案的测试项目。 zip project on google drive
    • 它只检测单元格是否被点击,但手势识别器没有附加到任何控件,例如 UIImageView 或 UIButton 。
    【解决方案5】:
    // create an instance of UITapGestureRecognizer and tell it to run 
    // an action we'll call "handleTap:"
    let tap = UITapGestureRecognizer(target: self, action: Selector("handleTap:"))
    // we use our delegate
    tap.delegate = self
    // allow for user interaction
    cell.imageViewName.userInteractionEnabled = true
    // add tap as a gestureRecognizer to tapView
    cell.imageViewName.addGestureRecognizer(tap)
    

    【讨论】:

      【解决方案6】:
      import UIKit
      
      class UserInfoCell: UITableViewCell{
      
          @IBOutlet weak var imagePlaceholder: UIImageView!
      }
      
      class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource,UIImagePickerControllerDelegate,UINavigationControllerDelegate {
      
          @IBOutlet weak var tableView: UITableView!
      
      
          let imagePicker = UIImagePickerController()
          func numberOfSections(in tableView: UITableView) -> Int {
              return 1
          }
          func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
                  return 1
      
      
          }
      
          func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
      
                  let cell = tableView.dequeueReusableCell(withIdentifier: "UserInfoCell" ,for: indexPath ) as! UserInfoCell
                  let recognizer = UITapGestureRecognizer(target: self, action: #selector(self.openGallery))
      
                  cell.imagePlaceholder.addGestureRecognizer(recognizer)
                  recognizer.numberOfTapsRequired = 1
                  cell.imagePlaceholder.isUserInteractionEnabled = true
                  cell.name.text = "Akshay"
      
                  if let data = UserDefaults.standard.data(forKey: "savedImage") {
                      cell.imagePlaceholder.image = UIImage(data: data as Data)
                  }
      
                  return cell
      
      
      
      
          }
          @objc func openGallery(){
              imagePicker.sourceType = .photoLibrary
              present(imagePicker,animated:  true, completion: nil)
          }
          func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
      
              let userimage = info[UIImagePickerController.InfoKey.originalImage] as! UIImage
              let imageData = userimage.jpegData(compressionQuality: 1)!
              UserDefaults.standard.setValue(imageData, forKey: "savedImage")
              print("image found")
              self.imagePicker.dismiss(animated: true, completion: nil)
      
              self.tableView.reloadData()
          }
      
          override func viewDidLoad() {
              super.viewDidLoad()
      
              imagePicker.delegate = self
      tableView.tableFooterView = UIView()
      
          }
      }
      

      此代码使用 TableViewCell 内 ImageView 的 Tapgesture 从图库中选择图像

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-18
        相关资源
        最近更新 更多