Обнаружение касания в UITextView обнаруживает только отмены

Я изо всех сил пытался обнаружить нажатие на UITextView с Swift.

Мои UITextViews находятся в таблице, я должен быть в состоянии обнаружить ссылки и нажать их, длина этих ссылок неизвестна.

Также, если я нажимаю на ячейку, которую я не нажимаю на ссылку, я хочу вставить новый UIViewController в мой стек контроллера навигации.

Я пытался создать свое собственное текстовое представление, чтобы перезаписать штрихи, но они не увенчались успехом. Он обнаруживает отмену, которая не считается нажатием на реальном устройстве.

Ошибка не возникает в симуляторе, но кажется, что я не могу нажать на реальном устройстве, только долгое нажатие будет работать.

class LinkTextView: UITextView {
    override func touchesCancelled(touches: Set<NSObject>!, withEvent event: UIEvent!) {
         self.textViewWasTapped(self) 
    }
}

Я попытался добавить непосредственно распознаватель жестов. У меня там тоже не было успеха. Он вообще не вызывает распознаватель жестов.

Я добавил делегат UIGestureReconizer в свой UIViewController и эти строки в моем

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
     var singleTap : UIGestureRecognizer = UIGestureRecognizer(target: self, action: "tapTextView:")
        singleTap.delegate = self
             cell.mTextOutlet.attributedText = myMutableString
             cell.mTextOutlet.addGestureRecognizer(singleTap) 

В моем классе LinkTextView:

class LinkTextView: UITextView {
    func tapTextView(stapGesture: UIGestureRecognizer){
        println("TAPPING1")
    }
}

Я посмотрел форумы и нашел этот пост: пост. Он предлагает использовать CHHLinkTextView. Я пытался использовать его, но я хочу автоматически определять ссылку, что обычно делает обычный uitextview.

Я попытался использовать checkBox в конструкторе интерфейсов для разбора ссылок с CHHLinkTextView, но он не работает. Я не видел ничего в документации, предполагающей, что это можно сделать.

Как мне поступить?

Ответ 1

Я сделал, как сказал Ральфонсо без успеха, но это помогло мне понять, что я столкнулся с конфликтом распознавания жестов. Оказывается, мне не пришлось переопределять все 4 метода UITextView, я просто переопределяю touchsBegan. То, что я делал в viewDidLoad, добавляло распознаватель жестов, чтобы отклонить клавиатуру:

      var tapOutTextField: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "dismissKeyboard")
      self.view.addGestureRecognizer(tapOutTextField)

То, что не имело смысла и послало меня в неправильном направлении, заключалось в том, что Touch был вызван после задержки (так был touchCancelled), и я не мог получить то же поведение, что и UIButton. Все это из-за этого конфликта распознавателя жестов.

Ответ 2

Вы очень близки с первой попыткой UITextView подкласса UITextView, но вместо переопределения только touchesCancelled вы захотите переопределить все методы touches*, т.е.

  • touchesBegan
  • touchesMoved
  • touchesEnded
  • touchesCancelled

В переопределенных методах отправьте касание цепочки респондента, получив textView nextResponder(), убедитесь, что он не равен nil, и вызовите метод для следующего респондента.

Причина этого заключается в том, что UITextView будет перехватывать касание, если оно не выполняется по URL-адресу, и методы UIResponder никогда не будут вызываться - попробуйте это сами, реализовав textView:shouldInteractWithURL:inRange в вашем tableViewCell или где угодно, и вы увидите, что он вызывается до того, как будут переданы любые сенсорные события.

Это должно быть минимумом того, что вы пытаетесь сделать (оно повторяется, но коротко):

class PassThroughTextView: UITextView {

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        if let next = next {
            next.touchesBegan(touches, with: event)
        } else {
            super.touchesBegan(touches, with: event)
        }
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        if let next = next {
            next.touchesEnded(touches, with: event)
        } else {
            super.touchesEnded(touches, with: event)
        }
    }

    override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
        if let next = next {
            next.touchesCancelled(touches, with: event)
        } else {
            super.touchesCancelled(touches, with: event)
        }
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        if let next = next {
            next.touchesMoved(touches, with: event)
        } else {
            super.touchesMoved(touches, with: event)
        }
    }
}

// In case you want to do anything with the URL or textView in your tableViewCell...
class TableViewCell: UITableViewCell, UITextViewDelegate {
    @IBOutlet var textView: PassThroughTextView!

    func textView(textView: UITextView, shouldInteractWithURL URL: NSURL, inRange characterRange: NSRange) -> Bool {
        println("textView shouldInteractWithURL")
        return true
    }

}