Utiliser isKindOfClass avec Swift

231

J'essaye de prendre un peu de langage Swift et je me demande comment convertir l'Objective-C suivant en 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
    }
}

Plus précisément, j'ai besoin de savoir comment utiliser isKindOfClassla nouvelle syntaxe.

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

    ???

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

    }
}
lkemitchll
la source

Réponses:

480

L'opérateur Swift approprié est is:

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

Bien sûr, si vous devez également affecter la vue à une nouvelle constante, la if let ... as? ...syntaxe est votre garçon, comme l'a mentionné Kevin. Mais si vous n'avez pas besoin de la valeur et que vous avez seulement besoin de vérifier le type, vous devez utiliser l' isopérateur.

KPM
la source
2
Fonctionne également avec Swift 3!
footyapps27
Fonctionne également avec Swift 4.2!
Ravi
comment pouvez-vous faire cela dans une instruction switch pour vérifier plusieurs types de classes différents?
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)
    {

    }
}

Éditer

Comme indiqué dans la réponse de @ Kevin , la bonne façon serait d'utiliser l'opérateur de transtypage de type facultatif as?. Vous pouvez en savoir plus à ce sujet dans la Optional Chainingsous-section de la section Downcasting.

Modifier 2

Comme indiqué dans l' autre réponse de l'utilisateur @KPM , utiliser l' isopérateur est la bonne façon de le faire.

Rui Peres
la source
Super oublié dans le mien. Vous pouvez également retirer le : UITouchdans celui-ci, car l'inférence de type saura ce que c'est par le as UITouchcasting
Malcolm Jarvis
@MalcolmJarvis ça ne fait pas de mal de l'avoir.
Rui Peres
4
Voler le représentant d'autres utilisateurs en mettant leur réponse dans la vôtre est de mauvais goût.
devios1
ne fonctionne pas. Suggère UIPickerView.self. Est-ce correct?
Vyachaslav Gerchicov
49

Vous pouvez combiner le chèque et le convertir en une seule instruction:

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

Ensuite, vous pouvez utiliser pickerdans le ifbloc.

Kevin
la source
3
C'est la réponse "plus correcte" car elle utilise le Swift "as?" opérateur. La documentation indique que «Dans Objective-C, vous utilisez la méthode isKindOfClass: pour vérifier si un objet est d'un certain type de classe et la méthode conformsToProtocol: pour vérifier si un objet est conforme à un protocole spécifié. Dans Swift, vous effectuez cette opération en utilisant l'opérateur is pour rechercher un type ou l'opérateur as? pour effectuer une conversion vers ce type. " Documentation Apple
Adam Fox
C'est la bonne façon d'exécuter isKingOfClass rapidement. Vous n'entrerez dans le bloc if que si l'objet est de classe UIPickerView! Très bonne réponse!
Florian Burel
Je voulais juste souligner que si vous avez juste besoin de faire la vérification et de ne pas utiliser 'picker' dans le bloc 'if' suivant, alors vous voudrez utiliser: if let _ = touch.view as? UIPickerView {...}
Adam Freeman
@AdamFreeman dans ce cas, vous feriez mieux d'utiliserif touch.view is UIPickerView {...}
Kevin
Et je ne suis pas sûr non plus isou _n'existait pas au moment où cette question a été posée, quelques jours après l'annonce de la langue.
Kevin
1

J'utiliserais:

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
    {

    }
}
crazyname
la source
-3

Une autre approche utilisant la nouvelle syntaxe Swift 2 consiste à utiliser guard et tout imbriquer dans un conditionnel.

guard let touch = object.AnyObject() as? UITouch, let picker = touch.view as? UIPickerView else {
    return //Do Nothing
}
//Do something with picker
Sam Corder
la source