【问题标题】:Passing parameter in selector (UIMenuController)在选择器中传递参数(UIMenuController)
【发布时间】:2018-08-01 00:29:00
【问题描述】:

我有一个UIMenuController,在集合视图单元格顶部有一个“删除”菜单项,当用户长按第 1 节的单元格时会显示该菜单项:

@IBAction func handleLongPressOnCell(_ sender: UILongPressGestureRecognizer) {
    let p = sender.location(in: collectionView)
    guard sender.state == .began, let indexPath = self.collectionView.indexPathForItem(at: p), let cell = self.collectionView.cellForItem(at: indexPath) else { return }

    if indexPath.section == 1 {
        let frameInSuperView = collectionView.convert(cell.frame, to: view)
        let deleteItem = UIMenuItem(title: "Delete", action: #selector(deleteCell))
        UIMenuController.shared.menuItems = [deleteItem]
        UIMenuController.shared.setTargetRect(frameInSuperView, in: view)
        becomeFirstResponder()
        UIMenuController.shared.setMenuVisible(true, animated: true)
    }
}

如何将单元格的索引路径传递给下面的函数?我需要这些信息才能从服务器中删除对象。

@objc internal func deleteCell(sender: UIMenuItem) {
    print("delete menu item tapped! print index path of selected collection view cell?")
}

【问题讨论】:

    标签: ios swift uimenucontroller


    【解决方案1】:

    您不能将信息与selector 操作一起直接传递;相反,您应该将索引路径存储在您在长按处理程序中设置并在删除处理程序中使用的成员变量中。

    private var indexPathForDeleting: IndexPath? = nil
    

    不要忘记做家务,并在不再需要变量时清除它。

    【讨论】:

    • 谢谢,我试图避免使用成员变量,因为它不太干净
    • psst: = nil 是多余的
    • 另一种方法是扩展 UIMenuItem 并为其附加一个处理程序块......但根据我的经验,如果你只需要它一次,那是不值得的,子类化 UIKit 类也可能更棘手比乍一看。
    • 不需要用nil初始化,但有时显式代码比短代码更好......不知道为什么,但我更喜欢在那里,给我一种温暖的控制感: )
    • 其实是的,这是迄今为止解决这个问题的最简单最简单的方法:)
    【解决方案2】:

    您可以子类化菜单项以获取必要的对象。

    这里已经回答了一个例子:

    Pass value through UIMenuItem of UIMenuController

    【讨论】:

      【解决方案3】:

      正如@mkeremkeskin 所指出的,在他链接的地方有一个答案。但这个答案在 Objective-C 中,在这里你会找到一个 Swift 4 版本。

      您可以继承 UIMenuItem 并将 indexPath 添加到它! 我必须删除一些代码才能在我的操场上工作,但你明白了 :)

      class CustomMenuItem: UIMenuItem {
          var indexPath: IndexPath?
      
          convenience init(title: String, action: Selector, indexPath: IndexPath? = nil) {
              self.init(title: title, action: action)
      
              self.indexPath = indexPath
          }
      }
      
      class ViewController {
      
          func handleLongPressOnCell(_ sender: UILongPressGestureRecognizer) {
      
              let indexPath = IndexPath(item: 0, section: 1)
      
              if indexPath.section == 1 {
                  let deleteItem = CustomMenuItem(title: "Delete", action: #selector(deleteCell), indexPath: indexPath)
                  UIMenuController.shared.menuItems = [deleteItem]
                  UIMenuController.shared.setMenuVisible(true, animated: true)
              }
          }
      
          @objc internal func deleteCell(sender: CustomMenuItem) {
              guard let indexPath = sender.indexPath else { return }
      
              // Delete item based on indexPath
          }
      }
      

      【讨论】:

        【解决方案4】:

        我是这样解决这类问题的:

        let menuController = UIMenuController.shared
        menuController.accessibilityHint = String(indexPath.row)
        
        
        @objc func deleteCell(_ sender: UIMenuController) {
             print("delete menu item tapped! index path? \(sender.accessibilityHint)")
        }
        

        我使用过 swift 4。希望它会有所帮助。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-09-01
          • 2012-08-31
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多