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.