Bloques en Swift (animateWithDuration: animaciones: finalización :)

102

Tengo problemas para hacer que los bloques funcionen en Swift. Aquí hay un ejemplo que funcionó (sin bloque de finalización):

UIView.animateWithDuration(0.07) {
    self.someButton.alpha = 1
}

o alternativamente sin el cierre final:

UIView.animateWithDuration(0.2, animations: {
    self.someButton.alpha = 1
})

pero una vez que trato de agregar el bloque de finalización, simplemente no funcionará:

UIView.animateWithDuration(0.2, animations: {
    self.blurBg.alpha = 1
}, completion: {
    self.blurBg.hidden = true
})

El autocompletar me da completion: ((Bool) -> Void)?pero no estoy seguro de cómo hacerlo funcionar. También probé con cierre final pero obtuve el mismo error:

! Could not find an overload for 'animateWithDuration that accepts the supplied arguments

Actualización para Swift 3/4:

// This is how I do regular animation blocks
UIView.animate(withDuration: 0.2) {
    <#code#>
}

// Or with a completion block
UIView.animate(withDuration: 0.2, animations: {
    <#code#>
}, completion: { _ in
    <#code#>
})

No uso el cierre final para el bloque de finalización porque creo que carece de claridad, pero si te gusta, puedes ver la respuesta de Trevor a continuación .

manolosavi
fuente
1
"El autocompletar me da la finalización: ((Bool) -> Void)? Pero no estoy seguro de cómo hacerlo funcionar" Exactamente lo que dice. Este debe ser un bloque que toma un Bool y devuelve un Vacío.
Matt
¿Cómo sabes qué es el ((Bool) -> Void)? ¿es para? Ya que he usado esto en ObjC antes de saber que está terminado BOOL. Pero, ¿cómo lo sabría un codificador rápido?
Malhal

Respuestas:

202

el parámetro de finalización en animateWithDuration toma un bloque que toma un parámetro booleano. En swift, como en los bloques Obj C, debes especificar los parámetros que toma un cierre:

UIView.animateWithDuration(0.2, animations: {
    self.blurBg.alpha = 1
}, completion: {
    (value: Bool) in
    self.blurBg.hidden = true
})

La parte importante aquí es el (value: Bool) in. Eso le dice al compilador que este cierre toma un Bool etiquetado como 'valor' y devuelve vacío.

Como referencia, si quisiera escribir un cierre que devolviera un bool, la sintaxis sería

{(value: Bool) -> bool in
    //your stuff
}
Zaksoup
fuente
También se puede resolver usando $0para el primer argumento, simplemente usando la variable dentro del bloque, el compilador se da cuenta de que su bloque acepta un argumento.
Puede el
1
sintaxis del bloque de finalización de dat :(
Chris Allinson
41

La conclusión es correcta, el cierre debe aceptar un Boolparámetro: (Bool) -> (). Tratar

UIView.animate(withDuration: 0.2, animations: {
    self.blurBg.alpha = 1
}, completion: { finished in
    self.blurBg.hidden = true
})
Nicolás H.
fuente
2
Vale la pena señalar que esta versión es correcta. No es necesario que escriba el tipo completo, ya que se puede inferir, por lo que todo lo que necesita es mencionar el parámetro de cierre como se menciona aquí.
Chuck
29

El subrayado solo junto con la inpalabra clave ignorará la entrada

Swift 2

UIView.animateWithDuration(0.2, animations: {
    self.blurBg.alpha = 1
}, completion: { _ in
    self.blurBg.hidden = true
})

Rápido 3, 4, 5

UIView.animate(withDuration: 0.2, animations: {
    self.blurBg.alpha = 1
}, completion: { _ in
    self.blurBg.isHidden = true
})
Dan Greenfield
fuente
8

Existe mi solución anterior basada en la respuesta aceptada anterior. Desvanece una vista y la oculta una vez casi invisible.

Swift 2

func animateOut(view:UIView) {

    UIView.animateWithDuration (0.25, delay: 0.0, options: UIViewAnimationOptions.CurveLinear ,animations: {
        view.layer.opacity = 0.1
        }, completion: { _ in
            view.hidden = true
    })   
}

Rápido 3, 4, 5

func animateOut(view: UIView) {

    UIView.animate(withDuration: 0.25, delay: 0.0, options: UIView.AnimationOptions.curveLinear ,animations: {
        view.layer.opacity = 0.1
    }, completion: { _ in
        view.isHidden = true
    })
}
Jaro
fuente
4

Aquí tienes, esto se compilará

Swift 2

UIView.animateWithDuration(0.3, animations: {
    self.blurBg.alpha = 1
}, completion: {(_) -> Void in
    self.blurBg.hidden = true
})

Rápido 3, 4, 5

UIView.animate(withDuration: 0.3, animations: {
    self.blurBg.alpha = 1
}, completion: {(_) -> Void in
    self.blurBg.isHidden = true
})

La razón por la que hice el área de Bool como un guión bajo es porque no está usando ese valor, si lo necesita, puede reemplazar el (_) con (value: Bool)

Kris Gellci
fuente
1

A veces, desea incluir esto en una variable para animar de diferentes maneras según la situación. Para eso necesitas

 let completionBlock : (Bool) -> () = { _ in 
 }

O puede usar el igualmente detallado:

 let completionBlock = { (_:Bool) in 
 }

Pero en cualquier caso, hay que indicar el Boollugar.

Dan Rosenstark
fuente
0

SWIFT 3.x + 4.x

Me gustaría hacer una actualización y simplificar las cosas.

El siguiente ejemplo se implementa en cualquiera viewque se oculte lentamente y cuando sea completamente transparente; se quita del padreview

okLa variable siempre regresa truecon la terminación de la animación.

    alpha = 1
    UIView.animate(withDuration: 0.5, animations: {
        self.alpha = 0
    }) { (ok) in
        print("Ended \(ok)")
        self.removeFromSuperview()
    }
Trevor
fuente