iOS 长按弹框,菜单栏

重写UIView,UIButton,UIImageView等,实现长按各种控件弹出菜单栏

class MenuView: UIView {
    override var canBecomeFirstResponder: Bool {
        return true
    }
    
    override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
        
        return super.canPerformAction(action, withSender: sender)
    }
}
class MenuPicture: UIImageView {
    override var canBecomeFirstResponder: Bool {
        return true
    }
    
    override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
        
        return super.canPerformAction(action, withSender: sender)
    }
}
class MenuLabel: UILabel {
    override var canBecomeFirstResponder: Bool {
        return true
    }

    override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {

        return super.canPerformAction(action, withSender: sender)
    }
}

值得注意的,也是我常犯的错误是,在继承自定义的View里面,要实现以下方法:

   override var canBecomeFirstResponder: Bool {
        return true
    }
    
    override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
        if !isFirstResponder {
            // 文本框弹出键盘, 文本框才是第一响应者
            if action == #selector(handleCopyMessage(_:)) || action == #selector(handleRecallMessage(_:)) {
                return true
            }
            //如果是文本框,那么这些显示都不返回
        }
        return super.canPerformAction(action, withSender: sender)
    }

handleCopyMessage(_:) 是我自己实现的copy方法

handleRecallMessage(_:) 是我自己实现的撤回方法

    @objc func handleCopyMessage(_ menu: UIMenuController?) {
        let paste = UIPasteboard.general
        paste.string = messageLabel.text
    }
    
    @objc func handleRecallMessage(_ menu: UIMenuController?) {
        
        if recallMessageBlock != nil {
            recallMessageBlock!()
        }
    }

这样,我定义一个label,长按实现copy和撤回就很简单了:

    @IBOutlet weak var messageLabel: MenuLabel!

    override func awakeFromNib() {
        super.awakeFromNib()
        
        messageLabel.isUserInteractionEnabled = true

        let longRecognizer = UILongPressGestureRecognizer.init(target: self, action: #selector(cellLongPress(_:)))
        (messageLabel.superview ?? contentView).addGestureRecognizer(longRecognizer) //messageLabel.superview 可以扩大label的点击范围,而菜单依然在label上哦

   }

    @objc func cellLongPress(_ recognizer: UILongPressGestureRecognizer) {
        if recognizer.state == .began {
            if let message = self.message, message.type == .TextMessageType {
                if let label = messageLabel {
                    label.becomeFirstResponder()
                    let menu = UIMenuController.shared
                    let itCopy = UIMenuItem(title: getTranslation(textCode: "NT001") ?? "", action: #selector(self.handleCopyMessage(_:)))
let itRecall = UIMenuItem(title: getTranslation(textCode: "NT494") ?? "", action: #selector(self.handleRecallMessage(_:)))
                    menu.menuItems = [itCopy, itRecall]
                    menu.setTargetRect(label.frame, in: label.superview!)
                    if menu.isMenuVisible {
                        return
                    }
                    menu.setMenuVisible(true, animated: true)
                }
            }
        }
    }
    

 

你可能感兴趣的:(iOS,iOS,长按,撤回)