Swift - Facebook聊天气泡:UITextView可以一次性选择整个文本视图,同时启用数据检测

时间:2016-11-13 23:13:20

标签: ios swift uitextview uigesturerecognizer uimenucontroller

这是我想做的事情:

类似于Facebook的聊天气泡:

  1. 点按整个聊天单元格,显示UIMenuController显示自定义菜单项(目前只有一个copyAll项)
  2. 保留数据检测并允许按时间,链接等。但是,我想禁用按以突出显示文字。
  3. 单击以显示
  4. 以下的时间

    我只能实现3中的2个.1)和2)似乎总是冲突。

    现在,我可以点按以显示下面的时间。我还能够保留数据检测,并显示自定义菜单项。 但是,由于显示自定义菜单项和数据检测都使用LongPressGestureRecognizer,因此有时会使用放大镜突出显示文本,而不是我的自定义菜单项。

    这是我的文字观点:

    // Message text view in 
    fileprivate lazy var messageTextView: CustomTextView = {
        var textView = CustomTextView()
        textView.backgroundColor = UIColor.clear
        textView.showsHorizontalScrollIndicator = false
        textView.showsVerticalScrollIndicator = false
        textView.isEditable = false
        textView.isSelectable = true
        textView.tintColor = RED_UICOLOR
        textView.dataDetectorTypes = .all
        textView.isUserInteractionEnabled = true
        textView.delegate = self
    
        // Long press to open custom menu controller
        let longPress = UILongPressGestureRecognizer(target: self, action: #selector(selectAllOfTextView))
        textView.addGestureRecognizer(longPress)
        return textView
    
        // Tap to perform 3) show time below
        let tap = UITapGestureRecognizer(target: self, action:#selector(notifyControllerToExpand))
        self.addGestureRecognizer(tap)
    }()
    

    长按会调用此选择器:

    func selectAllOfTextView(recognizer: UIGestureRecognizer) {
        let loc = recognizer.location(in: self.messageTextView)
        // Pass recognizer press location over to the CustomTextView
        self.messageTextView.showMenu(location: loc)
    }
    

    这是我的CustomTextView课程:

    class CustomTextView: UITextView {
    
    // Override the touches because I don't want any funky behavior from them
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        log.info("Touches began")
    }
    
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        log.info("Touches moved")
    }
    
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        log.info("Touches ended")
    }
    
    override var canBecomeFirstResponder: Bool {
        return true
    }
    
    override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
        if action == #selector(copyAll(_:)) {
            return true
        }
        return false
    }
    
    // Function called by selector in the superclass
    func showMenu(location: CGPoint) {
        self.becomeFirstResponder()
        let menuController = UIMenuController.shared
        let copyItem = UIMenuItem(title: "Copy", action: #selector(CustomTextView.copyAll(_:)))
        menuController.menuItems = [copyItem]
        let rect = CGRect(x: location.x - 35, y: self.frame.origin.y, width: 50, height: self.frame.height)
        menuController.setTargetRect(rect, in: self)
        menuController.setMenuVisible(true, animated: true)
    }
    
    func copyAll(_ sender: Any?) {
        UIPasteboard.general.string = self.text
    }
    }
    

0 个答案:

没有答案
相关问题