Переопределение метода с помощью селектора 'touchesBegan:withEvent:' имеет несовместимый тип '(NSSet, UIEvent) -> ()'

Xcode 6.3. Внутри класса, реализующего протокол UITextFieldDelegate, я хотел бы переопределить метод touchesBegan(), чтобы, возможно, скрыть клавиатуру. Если я избегаю ошибки компилятора в спецификации функции, то возникает ошибка компилятора, пытающаяся прочитать "прикосновение" из Set или NSSet, или же super.touchesBegan(touch, withEvent:event) выдает ошибку. Одна из этих комбинаций скомпилирована в Xcode 6.2! (Так где же документация к Swift "Set" и как получить элемент из одного?)

 override func touchesBegan(touches: NSSet, withEvent event: UIEvent) { 
    // Hiding the Keyboard when the User Taps the Background
        if let touch =  touches.anyObject() as? UITouch {
            if nameTF.isFirstResponder() && touch.view != nameTF {
                nameTF.resignFirstResponder();
            }
        }
        super.touchesBegan(touches , withEvent:event)
    }

Пытаться:

override func touchesBegan(touches: NSSet, withEvent event: UIEvent) or
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent) 

Ошибка компилятора: переопределение метода с помощью селектора 'touchesBegan:withEvent:' имеет несовместимый тип '(NSSet, UIEvent) -> ()' и

super.touchesBegan(touches , withEvent:event)

также жалуется

"NSSet" неявно преобразуется в "Set"; Вы хотели использовать "как" для явного преобразования?

Пытаться:

override func touchesBegan(touches: Set<AnyObject>, withEvent event: UIEvent) 

Ошибка компилятора: тип "AnyObject" не соответствует протоколу "Hashable"

Пытаться:

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) 

Ошибка компилятора при

if let touch = touches.anyObject() as? UITouch 

"Set" не имеет члена с именем "anyObject", НО спецификация функции и вызов super() в порядке!

Пытаться:

override func touchesBegan(touches: NSSet<AnyObject>, withEvent event: UIEvent) -> () or
override func touchesBegan(touches: NSSet<NSObject>, withEvent event: UIEvent) 

Ошибка компилятора: невозможно специализировать неуниверсальный тип 'NSSet'

8 ответов

Решение

Swift 1.2 (Xcode 6.3) представил нативный Set типа, что мосты с NSSet, Это упоминается в блоге Swift и в примечаниях к выпуску Xcode 6.3, но, видимо, еще не добавлено в официальную документацию (обновление: как отметил Ахмад Гадири, сейчас это задокументировано).

UIResponder метод теперь объявлен как

func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent)

и вы можете переопределить это так:

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
    if let touch = touches.first as? UITouch {
        // ...
    }
    super.touchesBegan(touches , withEvent:event)
}

Обновление для Swift 2 (Xcode 7): (Сравнение ошибки переопределения функции в Swift 2)

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    if let touch = touches.first {
        // ...
    }
    super.touchesBegan(touches, withEvent:event)
}

Обновление для Swift 3:

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

С xCode 7 и swift 2.0 используйте следующий код:

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {

    if let touch =  touches.first{
        print("\(touch)")
    }
    super.touchesBegan(touches, withEvent: event)
}

override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {

    if let touch = touches.first{
        print("\(touch)")
    }
    super.touchesEnded(touches, withEvent: event)
}

override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {

    if let touch = touches.first{
        print("\(touch)")
    }
    super.touchesMoved(touches, withEvent: event)
}

Использование Swift 3 и Xcode 8

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {

}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {

}

override func touchesCancelled(_ touches: Set<UITouch>?, with event: UIEvent?) {
// Don't forget to add "?" after Set<UITouch>
}

Текущая версия для новейшего обновления xCode 7.2 Swift 2.1 от 19 декабря 2015 г.

В следующий раз, когда вы снова получите такую ​​ошибку, удалите функцию и начните вводить ее снова "touchesBe...", и xCode должен автоматически завершить ее до самой новой, вместо того, чтобы пытаться исправить старую.

override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {

    for touch: AnyObject! in touches {
        let touchLocation = touch.locationInNode(self)

        //Use touchLocation for example: button.containsPoint(touchLocation) meaning the user has pressed the button.
    }
}

Теперь здесь есть ссылка на API Apple, и для переопределения в xCode версии 6.3 и swift 1.2 вы можете использовать этот код:

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
    if let touch =  touches.first as? UITouch {
         // ...
    }
    // ...
}

Небольшое дополнение. Для быстрой компиляции без ошибок, вам нужно добавить

import UIKit.UIGestureRecognizerSubclass

Что сработало для меня:

    override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
        if let touch = touches.first as? UITouch {
            // ...
        }

        super.touchesBegan(touches , withEvent:event!)
    }
  override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

        if let touch = touches.first as? UITouch {

            if touch.view == self.view{
                self.dismiss(animated: true, completion: nil)
            }
        }
    }

Использование Swift 4 и Xcode 9

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

}
Другие вопросы по тегам