Blocs sur Swift (animateWithDuration: animations: complétion :)

102

J'ai du mal à faire fonctionner les blocs sur Swift. Voici un exemple qui a fonctionné (sans bloc d'achèvement):

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

ou bien sans la fermeture arrière:

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

mais une fois que j'essaye d'ajouter le bloc d'achèvement, cela ne fonctionnera tout simplement pas:

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

La saisie semi-automatique me donne completion: ((Bool) -> Void)?mais je ne sais pas comment le faire fonctionner. Également essayé avec la fermeture de fin mais a obtenu la même erreur:

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

Mise à jour pour 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#>
})

Je n'utilise pas la fermeture de fin pour le bloc de complétion car je pense que cela manque de clarté, mais si vous l'aimez, vous pouvez voir la réponse de Trevor ci-dessous .

manolosavi
la source
1
"La saisie semi-automatique me donne la complétion: ((Bool) -> Void)? Mais je ne sais pas comment le faire fonctionner" Exactement ce qu'il dit. Ce doit être un bloc qui prend un Bool et renvoie un Void.
mat
Comment savez-vous ce que le ((Bool) -> Void)? est pour? Depuis que je l'ai utilisé dans ObjC avant de savoir que BOOL est terminé. Mais comment un codeur rapide le saurait-il?
malhal

Réponses:

202

le paramètre de complétion dans animateWithDuration prend un bloc qui prend un paramètre booléen. En swift, comme dans les blocs Obj C, vous devez spécifier les paramètres qu'une fermeture prend:

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

La partie importante ici est le (value: Bool) in. Cela indique au compilateur que cette fermeture prend un Bool étiqueté «valeur» et renvoie void.

Pour référence, si vous vouliez écrire une fermeture qui retournait un booléen, la syntaxe serait

{(value: Bool) -> bool in
    //your stuff
}
Zaksoup
la source
Peut également être résolu en utilisant $0pour le premier argument, en utilisant simplement la variable à l'intérieur du bloc, le compilateur comprend que votre bloc accepte un argument.
Can
1
Syntaxe du bloc de complétion dat :(
Chris Allinson
41

La finition est correcte, la fermeture doit accepter un Boolparamètre: (Bool) -> (). Essayer

UIView.animate(withDuration: 0.2, animations: {
    self.blurBg.alpha = 1
}, completion: { finished in
    self.blurBg.hidden = true
})
Nicholas H.
la source
2
Il est à noter que cette version est correcte. Vous n'avez pas besoin d'écrire le type complet car il peut être déduit, il vous suffit donc de mentionner le paramètre de fermeture comme mentionné ici.
Chuck
29

Soulignez par lui-même aux côtés du in mot clé ignorera l'entrée

Swift 2

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

Swift 3, 4, 5

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

Il y a ma solution ci-dessus basée sur la réponse acceptée ci-dessus. Il fait disparaître une vue et la cache autrefois presque 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
    })   
}

Swift 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
la source
4

Ici vous allez, cela va compiler

Swift 2

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

Swift 3, 4, 5

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

La raison pour laquelle j'ai fait de la zone booléenne un trait de soulignement est que vous n'utilisez pas cette valeur, si vous en avez besoin, vous pouvez remplacer le (_) par (valeur: Bool)

Kris Gellci
la source
1

Parfois, vous voulez lancer ceci dans une variable pour animer de différentes manières selon la situation. Pour cela, vous avez besoin

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

Ou vous pouvez utiliser le tout aussi verbeux:

 let completionBlock = { (_:Bool) in 
 }

Mais dans tous les cas, vous devez indiquer le Boolquelque part.

Dan Rosenstark
la source
0

SWIFT 3.x + 4.x

J'aimerais faire une mise à jour et simplifier les choses.

L'exemple ci-dessous est implémenté dans tout ce viewqu'il se cache lentement et lorsqu'il est complètement transparent; le supprime du parentview

okvariable retournera toujours trueavec la fin de l'animation.

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