web-dev-qa-db-fra.com

Blocs sur Swift (animateWithDuration: animations: achèvement :)

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'essaie d'ajouter le bloc d'achèvement, cela ne fonctionne tout simplement pas:

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

L'auto-complétion me donne completion: ((Bool) -> Void)? mais je ne sais pas comment le faire fonctionner. Également essayé avec la fermeture finale mais j'ai eu 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 fuite pour le bloc d'achèvement parce que je pense qu'il manque de clarté, mais si vous l'aimez, vous pouvez voir la réponse de Trevor ci-dessous .

97
manolosavi

le paramètre d'achèvement dans animateWithDuration prend un bloc qui prend un paramètre booléen. Dans Swift, comme dans les blocs Obj C, vous devez spécifier les paramètres d’une fermeture:

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éen intitulé 'valeur' ​​et renvoie void.

Pour référence, si vous vouliez écrire une fermeture qui renvoyait un bool, la syntaxe serait la suivante: 

{(value: Bool) -> bool in
    //your stuff
}
197
Zaksoup

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

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

Le soulignement par rapport au mot clé in ignorera l’entrée

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

Il y a ma solution ci-dessus basée sur la réponse acceptée ci-dessus. Il efface une vue et la cache une fois presque invisible.

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
    })   
}
8
Jaro

Voilà, ça va compiler

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

Si j'ai fait de la zone Bool un trait de soulignement, c'est parce que vous n'utilisez pas cette valeur. Si vous en avez besoin, vous pouvez remplacer le (_) par (valeur: Bool).

4
Kris Gellci

Parfois, vous souhaitez insérer cette variable dans une variable pour l'animer de différentes manières en fonction de la situation. Pour cela vous avez besoin

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

Ou vous pouvez utiliser le même mot:

 let completionBlock = { (_:Bool) in 
 }

Mais dans tous les cas, vous devez indiquer la Bool quelque part.

1
Dan Rosenstark

Swift 3.x + 4.x

Je voudrais faire une mise à jour et simplifier les choses.

L'exemple ci-dessous est implémenté dans n'importe quelle view, elle se cache lentement et lorsqu'elle est complètement transparente; se retire du parent view

La variable ok renverra toujours true avec la fin de l'animation.

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