Usando isKindOfClass com Swift

231

Estou tentando pegar um pouco da linguagem Swift e estou pensando em como converter o seguinte Objective-C em 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
    }
}

Mais especificamente, preciso saber como usar isKindOfClassa nova sintaxe.

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

    ???

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

    }
}
lkemitchll
fonte

Respostas:

480

O operador Swift adequado é is:

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

Obviamente, se você também precisar atribuir a visualização a uma nova constante, a if let ... as? ...sintaxe será sua, como Kevin mencionou. Mas se você não precisar do valor e apenas precisar verificar o tipo, use o isoperador

KPM
fonte
2
Também funciona com o Swift 3!
precisa saber é o seguinte
Funciona com o Swift 4.2 também!
Ravi
como você pode fazer isso em uma instrução switch para verificar vários tipos de classe 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

Conforme apontado na resposta de @ Kevin , a maneira correta seria usar o operador de conversão de tipo opcional as?. Você pode ler mais sobre isso na seção Optional Chainingsub-seção Downcasting.

Editar 2

Conforme apontado na outra resposta do usuário @KPM , usar o isoperador é o caminho certo para fazê-lo.

Rui Peres
fonte
Esqueceu super na minha. Você também pode tirar o : UITouchem um presente, como o tipo de inferência vai saber o que é pelo as UITouchelenco
Malcolm Jarvis
@MalcolmJarvis não dói tê-lo.
Rui Peres
4
Roubar o representante de outros usuários colocando a resposta na sua é de mau gosto.
devios1
não funciona Sugere UIPickerView.self. Está correto?
Vyachaslav Gerchicov 28/03
49

Você pode combinar a verificação e converter em uma declaração:

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

Então você pode usar pickerdentro do ifbloco.

Kevin
fonte
3
Esta é a resposta "mais correta" porque usa o Swift 'as?' operador. A documentação afirma que "No Objective-C, você usa o método isKindOfClass: para verificar se um objeto é de um determinado tipo de classe e o método conformmsToProtocol: para verificar se um objeto está em conformidade com um protocolo especificado. No Swift, você faz isso tarefa usando o operador is para verificar um tipo ou o operador as? para fazer downcast para esse tipo ". Documentação da Apple
Adam Fox
Esta é a maneira correta de executar o isKingOfClass rapidamente. Você entrará no bloco if apenas se o objeto for da classe UIPickerView! Ótima resposta!
Florian Burel
Só queria salientar que, se você só precisa fazer a verificação e não usar o 'seletor' no bloco 'se' subsequente, então você gostaria de usar: se deixe _ = touch.view as? UIPickerView {...}
Adam Freeman
@AdamFreeman, nesse caso, você seria melhor fora de usarif touch.view is UIPickerView {...}
Kevin
E não tenho certeza isou _existia no momento em que essa pergunta foi feita, alguns dias depois que o idioma foi anunciado pela primeira vez.
Kevin
1

Eu usaria:

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
fonte
-3

Outra abordagem usando a nova sintaxe do Swift 2 é usar a proteção e aninhar tudo em uma condição.

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