Używanie isKindOfClass z Swift

231

Próbuję uchwycić trochę Szybkiego języka i zastanawiam się, jak przekonwertować następujący Cel C w Swift:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesBegan:touches withEvent:event];

    UITouch *touch = [touches anyObject];

    if ([touch.view isKindOfClass: UIPickerView.class]) {
      //your touch was in a uipickerview ... do whatever you have to do
    }
}

Mówiąc dokładniej, muszę wiedzieć, jak korzystać isKindOfClass z nowej składni.

override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {

    ???

    if ??? {
        // your touch was in a uipickerview ...

    }
}
lkemitchll
źródło

Odpowiedzi:

480

Właściwym operatorem Swift jest is:

if touch.view is UIPickerView {
    // touch.view is of type UIPickerView
}

Oczywiście, jeśli musisz także przypisać widok do nowej stałej, wówczas if let ... as? ...składnia to twój chłopiec, jak wspomniał Kevin. Ale jeśli nie potrzebujesz wartości i musisz tylko sprawdzić typ, powinieneś użyć isoperatora.

KPM
źródło
2
Działa również z Swift 3!
footyapps27
Działa również z Swift 4.2!
Ravi
jak możesz to zrobić w instrukcji switch, aby sprawdzić kilka różnych typów klas?
BigBoy1337
132
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {

    super.touchesBegan(touches, withEvent: event)
    let touch : UITouch = touches.anyObject() as UITouch

    if touch.view.isKindOfClass(UIPickerView)
    {

    }
}

Edytować

Jak wskazano w odpowiedzi @ Kevina , poprawnym sposobem byłoby użycie opcjonalnego operatora rzutowania as?. Możesz przeczytać więcej na ten temat w Optional Chainingpodsekcji sekcji Downcasting.

Edytuj 2

Jak wskazano w drugiej odpowiedzi użytkownika @KPM , użycie isoperatora jest właściwym sposobem na zrobienie tego.

Rui Peres
źródło
Zapomniałem super w moim. Możesz również wyjąć ten : UITouchw tym, ponieważ wnioskowanie na podstawie typu będzie wiedzieć, co to jest z as UITouchobsadą
Malcolm Jarvis
@MalcolmJarvis nie boli go mieć.
Rui Peres,
4
Kradzież przedstawiciela innych użytkowników poprzez umieszczenie odpowiedzi w twoim jest w złym guście.
devios1
nie działa Sugeruje UIPickerView.self. Czy to jest poprawne?
Vyachaslav Gerchicov
49

Możesz połączyć czek i rzutować w jedną instrukcję:

let touch = object.anyObject() as UITouch
if let picker = touch.view as? UIPickerView {
    ...
}

Następnie możesz użyć pickerw ifbloku.

Kevin
źródło
3
To jest „bardziej poprawna” odpowiedź, ponieważ używa Swift „as?” operator. Dokumentacja stwierdza, że ​​„W Objective-C używasz metody isKindOfClass:, aby sprawdzić, czy obiekt jest określonego typu klasy, a metoda contrsToProtocol:, aby sprawdzić, czy obiekt jest zgodny z określonym protokołem. W Swift osiągasz to zadanie przy użyciu operatora is w celu sprawdzenia typu lub operatora as? w celu sprowadzenia do tego typu. ” Dokumentacja Apple
Adam Fox
Jest to właściwy sposób szybkiego wykonywania isKingOfClass. Wejdziesz do bloku if tylko wtedy, gdy obiekt jest klasy UIPickerView! Świetna odpowiedź!
Florian Burel,
Chciałem tylko zaznaczyć, że jeśli musisz tylko sprawdzić i nie używać „selektora” w kolejnym bloku „if”, to powinieneś użyć: if _ = touch.view as? UIPickerView {...}
Adam Freeman,
@AdamFreeman w takim przypadku lepiej byłoby użyćif touch.view is UIPickerView {...}
Kevin,
I nie jestem pewien, czy islub _istniały w momencie to pytano, kilka dni po raz pierwszy ogłosił języku.
Kevin,
1

Użyłbym:

override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {

    super.touchesBegan(touches, withEvent: event)
    let touch : UITouch = touches.anyObject() as UITouch

    if let touchView = touch.view as? UIPickerView
    {

    }
}
szalone imię
źródło
-3

Innym podejściem wykorzystującym nową składnię Swift 2 jest użycie wartownika i zagnieżdżenie go w jednym warunku.

guard let touch = object.AnyObject() as? UITouch, let picker = touch.view as? UIPickerView else {
    return //Do Nothing
}
//Do something with picker
Sam Corder
źródło