J'essaie de réécrire d'Objective-C vers Swift, je ne peux pas travailler sur la syntaxe ou comprendre les documents
Voici un exemple simplifié dans Objective-C que j'ai écrit:
[UIView animateWithDuration:10.0 animations:^{self.navigationController.toolbar.frame = CGRectMake(0,10,0,10);}];
Comment écrire ceci dans Swift?
Voici le modèle de saisie semi-automatique:
UIView.animateWithDuration(duration: NSTimeInterval, animations: (() -> Void))
Comme les types d'arguments attendus et le type de retour à l'argument animations sont connus, le compilateur peut les déduire sans problème. Cela devrait fonctionner (même si je n'ai pas le terrain de jeu disponible pour le moment:
UIView.animateWithDuration(10.0, animations: {
self.navigationController.toolbar.frame = CGRect(x:0.0, y:10.0, width:10.0, height:0.0)
})
pour plus d'informations sur les fermetures, consultez le chapitre dans les documents Swift
remarque à propos de CGRect()
- les documentation du développeur montrent CGRect()
utilisé dans Swift code. Peut-être que cela nécessite une importation?
mise à jour pour les commentaires: vous pouvez également utiliser une fermeture de fin comme suit:
UIView.animateWithDuration(10.0) {
self.navigationController.toolbar.frame = CGRect(x:0.0, y:10.0, width:10.0, height:0.0)
}
Voici le format de fermeture Swift:
{(parameter:type, parameter: type, ...) -> returntype in
//do stuff
}
Voici ce que vous devez faire:
//The animation closure will take no parameters and return void (nothing).
UIView.animateWithDuration(duration: NSTimeInterval, animations: {() -> Void in
//Animate anything.
})
Voici la documentation pour les fermetures.
Le code suivant peut vous aider à écrire votre propre bloc.
class func testFunc(completion: ((list : NSArray!) -> Void)?) {
//--- block code.
if completion! != nil {
completion! (list: NSArray())
}
}
et vous pouvez l'appeler comme -
className.testFunc {
(list: NSArray!) -> Void in
}
Vous pouvez essentiellement l'écrire de 3 manières identiques:
écrire quoi faire dans le bloc de fermeture/code:
UIView.animateWithDuration(10.0) {
self.navigationController.toolbar.frame = CGRect(x:0.0, y:10.0, width:10.0, height:0.0)
}
Ceci est également connu sous le nom de fermeture de fin (Vous ne pouvez faire de fermeture de fin que si le paramètre de fermeture est le paramètre dernier)
Cela ne signifie pas que le paramètre "animations" n'est plus écrit. Il est écrit mais comme dans le format ci-dessus.
Écrivez exactement dans les lignes, la plupart des développeurs l'évitent, car c'est un peu bogué d'écrire avec toutes les parenthèses et accolades.
UIView.animateWithDuration(10.0, animations: {
self.navigationController.toolbar.frame = CGRect(x:0.0, y:10.0, width:10.0, height:0.0)
})
(Contrairement à la fermeture de fin, vous avez écrit le nom, c'est-à-dire "animations") Ceci est connu sous le nom de fermeture en ligne
Écrivez dans un sens plus modulaire
UIView.animateWithDuration(duration: NSTimeInterval, animations: animatingFunc)
func animatingFunc() {
self.navigationController.toolbar.frame = CGRect(x:0.0, y:10.0, width:10.0, height:0.0)
}
Rappelez-vous que le type du paramètre "animations" était () -> Void
Exactement comme ce que nous faisons, animatingFunc ne prend aucun paramètre ie '()' et ne retourne rien ie 'void'
(Dans Swift, les fonctions sont des types et peuvent être transmises en tant que paramètres) Certains pourraient dire que c'est plus lisible, certains pourraient dire que la fermeture de fin est ...
Note latérale1 Vous pouvez également ne rien faire (ce qui n'a vraiment aucun sens, mais dans de nombreux autres gestionnaires/animations/gestionnaires d'achèvement, vous ne voudrez peut-être rien faire)
UIView.animateWithDuration(duration: NSTimeInterval, animations: nil)
Note latérale2
Les fermetures deviennent plus intéressantes lorsque vous devez capturer une valeur. Voir this démonstration simple. Pour plus d'informations sur Swift voir Documentation d'Apple
Comment déclarer une fermeture dans Swift?
En tant que variable:
var closureName: (ParameterTypes) -> ReturnType
Comme variable facultative:
var closureName: ((ParameterTypes) -> ReturnType)?
En tant qu'alias de type:
typealias ClosureType = (ParameterTypes) -> ReturnType
En constante:
let closureName: ClosureType = { ... }
En paramètre d'une autre fonction:
funcName(parameter: (ParameterTypes) -> ReturnType)
Remarque: si la fermeture transmise va survivre à la portée de la méthode, par ex. si vous l'enregistrez dans une propriété, elle doit être annotée avec @escaping
.
Comme argument à un appel de fonction:
funcName({ (ParameterTypes) -> ReturnType in statements })
En tant que paramètre de fonction:
array.sorted(by: { (item1: Int, item2: Int) -> Bool in return item1 < item2 })
En tant que paramètre de fonction avec des types implicites:
array.sorted(by: { (item1, item2) -> Bool in return item1 < item2 })
En tant que paramètre de fonction avec un type de retour implicite:
array.sorted(by: { (item1, item2) in return item1 < item2 })
Comme dernier paramètre de fonction:
array.sorted { (item1, item2) in return item1 < item2 }
Comme dernier paramètre, en utilisant des noms d'argument abrégés:
array.sorted { return $0 < $1 }
Comme dernier paramètre, avec une valeur de retour implicite:
array.sorted { $0 < $1 }
Comme dernier paramètre, comme référence à une fonction existante:
array.sorted(by: <)
En tant que paramètre de fonction avec une sémantique de capture explicite:
array.sorted(by: { [unowned self] (item1: Int, item2: Int) -> Bool in return item1 < item2 })
En tant que paramètre de fonction avec une sémantique de capture explicite et des paramètres inférés/type de retour:
array.sorted(by: { [unowned self] in return $0 < $1 })
Ce site n'est pas destiné à être une liste exhaustive de toutes les utilisations possibles des fermetures.
ref: http://goshdarnclosuresyntax.com/