Aujourd’hui nous allons vous parler de l’évolution de certaine partie du framework Foundation qui se sont rapprocher de la philosophy Swift : CGRect, CGSize & CGPoint. Cet article est une inspiration/traduction du billet de Andyy Hope.
Comme beaucoup de développeur Swift venu du monde de l’Objective-C nous avons tendance à garder nos vieilles habitudes. L’Objective-C étant un sur-ensemble du langage C beaucoup d’API sont inspirées de ces conventions. L’erreur que nous avions tendance à faire était d’utiliser ces conventions en Swift. L’example le plus parlant est l’utilisation des structures géométriques : CGRect
, CGSize
, CGPoint
.
let rect = CGRectMake(0, 0, 100, 100)
let point = CGPointMake(0, 0)
let size = CGSizeMake(100, 100)
Dans cet example nous pouvons remarquer que l’utilisation des conventions Objective-C en Swift ne fait pas naturel. C’est dans cet optique qu’Apple a fournis de nouvelles APIs pour rendre l’utilisation de ces structures plus simple :
let rect = CGRect(x: 0, y: 0, width: 100, height: 100)
let size = CGSize(width: 100, height: 100)
let point = CGPoint(x: 0, y: 0)
La syntaxe ici est maintenant cohérente avec le reste des APIs en Swift. En outre, l’avantage de cette nouvelle syntaxe permet l’utilisation d’arguments comme les Int
et Double
en plus des Float
ou CGFloat
!
Zero
De la même manière pour créer un point zero vous utilisez peut-être cette syntaxe :
let rect = CGRectZero
let size = CGSizeZero
let point = CGPointZero
Vous devriez aussi utiliser la nouvelle syntaxe en Swift qui est très simple d’utilisation :
let rect = CGRect.zero
let size = CGSize.zero
let point = CGPoint.zero
L’avantage de cette syntaxe est que grace à l’inférence de type on peut utiliser directement la déclaration .zero
:
let rect: CGRect = .zero
let size: CGSize = .zero
let point: CGPoint = .zero
La récupération de la valeur
CGRect frame = CGRectMake(0, 0, 100, 100)
CGFloat width = CGRectGetWidth(frame)
CGFloat height = CGRectGetHeight(frame)
CGFloat maxX = CGRectGetMaxX(frame)
CGFloat maxY = CGRectGetMaxY(frame)
Si vous venez de l’Objective-C vous avez certainement utilisé ces getters pour récupérer les valeurs des rect
. Mais pourquoi ne pas utiliser ces valeurs directement ?
CGFloat width = frame.size.width
CGFloat height = frame.size.height
Vos applications doivent éviter de lire et d’écrire directement les données stockées dans la structure de données
CGRect
. À la place vous devriez utiliser les fonctions décrites ici pour manipuler rectangles afin de récupérer leurs caractéristiques.
— Apple, CGGeometry Reference Documentation
Probablement beaucoup d’entre vous s’embête encore avec ces formalités, mais à qui cela plait réellement ? Swift nous soulage en fournissant une API beaucoup plus simple en notation par point :
let frame = CGRect(x: 0, y: 0, width: 100, height: 100)
let width = frame.width
let height = frame.height
let maxX = frame.maxX
let maxY = frame.maxY
Il y a beaucoup d’autres exemples de ces subtilités disponibles avec Swift que vous pouvez découvrir en parcourant la documentation d’Apple.
Mutabilité
let frame = CGRect(x: 0, y: 0, width: 100, height: 100)
let view = UIView(frame: frame)
view.frame.origin.x += 10
Vous êtes non seulement capable de changer les valeurs individuellement les valeurs de la frame
d’une vue mais vous êtes aussi capable de replacer entièrement les sous-structures avec une seule déclaration :
let view = UIView(frame: .zero)
view.frame.size = CGSize(width: 10, height: 10)
view.frame.origin = CGPoint(x: 10, y: 10)
Cette petite fonctionnalité seule est pas une raison suffisante pour arrêté d’utiliser l’Objective-C. La mutabilité des CGRect
consiste à pouvoir les modifier sans avoir à créer des copies de ces structures.
Il y a aussi d’autres constructions dans UIKit
pour qui les changements sont applicables :
UIEdgeInsets
var edgeInsets = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
edgeInsets.top += 10
UIOffset
var offset = UIOffset(horizontal: 10, vertical: 10)
offset.vertical += 10