Usar isKindOfClass con Swift

231

Estoy tratando de aprender un poco de Swift Lang y me pregunto cómo convertir el siguiente Objective-C 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
    }
}

Más específicamente, necesito saber cómo usar isKindOfClassen la nueva sintaxis.

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

    ???

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

    }
}
lkemitchll
fuente

Respuestas:

480

El operador adecuado de Swift es is:

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

Por supuesto, si también necesita asignar la vista a una nueva constante, entonces la if let ... as? ...sintaxis es su hijo, como mencionó Kevin. Pero si no necesita el valor y solo necesita verificar el tipo, entonces debe usar el isoperador.

KPM
fuente
2
¡Funciona también con Swift 3!
footyapps27
¡Funciona también con Swift 4.2!
Ravi
¿Cómo puede hacer esto en una declaración de cambio para verificar varios tipos de clases diferentes?
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)
    {

    }
}

Editar

Como se señaló en la respuesta de @ Kevin , la forma correcta sería utilizar un operador de conversión de tipo opcional as?. Puede leer más al respecto en la sección Optional Chainingsubsección Downcasting.

Editar 2

Como se señaló en la otra respuesta del usuario @KPM , usar el isoperador es la forma correcta de hacerlo.

Rui Peres
fuente
Olvidé super en la mía. También puede sacar el : UITouchen este, ya que la inferencia de tipos sabrá lo que es por el as UITouchelenco
Malcolm Jarvis
@MalcolmJarvis no hace daño tenerlo.
Rui Peres
44
Robar el representante de otros usuarios poniendo su respuesta en la suya es de mal gusto.
devios1
no funciona Sugiere UIPickerView.self. ¿Es correcto?
Vyachaslav Gerchicov
49

Puede combinar el cheque y emitir en una sola declaración:

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

Entonces puedes usar pickerdentro del ifbloque.

Kevin
fuente
3
Esta es la respuesta "más correcta" porque usa Swift 'como?' operador. La documentación establece que "En Objective-C, usted usa el método isKindOfClass: para verificar si un objeto es de cierto tipo de clase, y el método conformsToProtocol: para verificar si un objeto se ajusta a un protocolo específico. En Swift, logra esto "utilizando el operador is para verificar un tipo, o el operador as? para bajar a ese tipo". Documentación de Apple
Adam Fox
Esta es la forma correcta de realizar isKingOfClass en forma rápida. ¡Ingresará el bloque if solo si el objeto es de la clase UIPickerView! ¡Gran respuesta!
Florian Burel
Solo quería señalar que si solo necesita hacer la verificación y no usar 'selector' en el siguiente bloque 'if', entonces querría usar: if let _ = touch.view as? UIPickerView {...}
Adam Freeman
@AdamFreeman en ese caso, sería mejor usarloif touch.view is UIPickerView {...}
Kevin
Y no estoy seguro, ya sea iso _que existía en el momento se hizo esta pregunta, pocos días después de la lengua fue anunciado por primera vez.
Kevin
1

Yo usaría:

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
    {

    }
}
nombre loco
fuente
-3

Otro enfoque que usa la nueva sintaxis Swift 2 es usar guardia y anidarlo todo en un condicional.

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