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 ...

    }
}

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.


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.


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.


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
    {

    }
}

-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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.