Перевизначення методу за допомогою селектора 'touchesBegan: withEvent:' має несумісний тип '(NSSet, UIEvent) -> ()'


77

Xcode 6.3. У класі, що реалізує протокол UITextFieldDelegate, я хотів би замінити метод touchesBegan (), щоб можливо приховати клавіатуру. Якщо я уникаю помилки компілятора у специфікації функції, тоді виникає помилка компілятора, намагаючись прочитати "дотик" із Set або NSSet, або super.touchesBegan (дотики, 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'

Відповіді:


161

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)
}

Дякую Мартіну Р, мені потрібно було лише змінити NSSet на Set <NSObject> і мій код функціонує.
MwcsMac,

1
Привіт @Martin Навіщо super.touchesBegan(touches , withEvent:event)потрібна? Я досі не дуже добре розумію Свіфта.
Zigii Wong

Я відчуваю, що це має бути так: super.touchesBegan (дотики, withEvent: event!) Для xCode 7.2
Євген Гордін

@ EugeneGordin: Чому ти так думаєш? Останній метод все ще компілюється з Xcode 7.2.
Martin R

це скаржилось на мене ... значення необов’язкового типу не розгорнуто
Євген Гордін

10

У 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)
}

Я не можу побудувати проект. Отримання методу помилки не замінює жодного методу з його суперкласу для touchesBeganфункції. Я намагався зробити підклас з UIGestureRecognizerта UTapGestureRecognizer. Xcode 7.1
Борис Ю.

скористайтеся цим stackoverflow.com/questions/30892254/…, щоб перевірити, що відбувається з вашим кодом
Хіманшу Махаджан

10

Використання 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>
}

6

Зараз це є в посиланні на API Apple тут, і для заміни в xCode версії 6.3 та swift 1.2 ви можете використовувати цей код:

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

Цікаво, що онлайн-документи правильні, але версія, включена до довідкової системи Xcode, застаріла. Я думаю, мені потрібно взяти звичку шукати ці речі в Інтернеті.
Duncan C

6

Поточна зараз для останнього оновлення станом на 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.
    }
}

4

У мене спрацювало:

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

        super.touchesBegan(touches , withEvent:event!)
    }

Якщо ви використовуєте Xcode 6.3 та Swift 1.2, ваш код не працюватиме. Цей допис, якщо йдеться про Xcode 6.3 та Swift 1.2.
MwcsMac,

1
Ви маєте рацію, сьогодні я оновив Xcode, і він негайно видав помилку.
jfredsilva

4

Невелике доповнення. Щоб швидко скомпілювати помилку без помилки, потрібно додати

імпортувати UIKit.UIGestureRecognizerSubclass



0
  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)
            }
        }
    }

2
Додайте коментарі, поясніть свою відповідь, прочитайте, як відповісти .
Aksen P
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.