Comment puis-je rassembler un CGFloat à Swift? J'ai essayé ceil(CDouble(myCGFloat))
mais cela ne fonctionne que sur iPad Air et iPhone 5S.
Lorsque j'exécute sur un autre appareil simulé, une erreur s'affiche en indiquant 'NSNumber' is not a subtype of 'CGFloat'
Mise à jour : Apple ont maintenant défini certaines versions spécifiques à CGFloat de fonctions communes telles que ceil
:
func ceil(x: CGFloat) -> CGFloat
... spécifiquement pour faire face à la différence 32/64 bits. Si vous utilisez simplement ceil
avec un argument CGFloat, il devrait maintenant fonctionner sur toutes les architectures.
Ma réponse originale:
C'est assez horrible, je pense, mais quelqu'un peut-il penser à un meilleur moyen? #if
ne semble pas fonctionner pour CGFLOAT_IS_DOUBLE
; Je pense que vous êtes limité à la construction de configurations, à partir de quoi je peux voir dans la documentation pour la compilation conditionnelle .
var x = CGFloat(0.5)
#if Arch(x86_64) || Arch(arm64)
var test = ceil(x)
#else
var test = ceilf(x)
#endif
Avec Swift 5, vous pouvez choisir l’un des 3 chemins suivants afin d’arrondir un CGFloat
.
CGFloat
rounded(_:)
Le protocole FloatingPoint
donne aux types qui s'y conforment une méthode rounded(_:)
. CGFloat
's rounded(_:)
a la déclaration suivante:
func rounded(_ rule: FloatingPointRoundingRule) -> CGFloat
Renvoie cette valeur arrondie à une valeur intégrale à l'aide de la règle d'arrondi spécifiée.
L'exemple de code Playground ci-dessous montre comment utiliser rounded(_:)
pour arrondir une valeur CGFloat
:
import CoreGraphics
let value1: CGFloat = -0.4
let value2: CGFloat = -0.5
let value3: CGFloat = -1
let value4: CGFloat = 0.4
let value5: CGFloat = 0.5
let value6: CGFloat = 1
let roundedValue1 = value1.rounded(.up)
let roundedValue2 = value2.rounded(.up)
let roundedValue3 = value3.rounded(.up)
let roundedValue4 = value4.rounded(.up)
let roundedValue5 = value5.rounded(.up)
let roundedValue6 = value6.rounded(.up)
print(roundedValue1) // prints -0.0
print(roundedValue2) // prints -0.0
print(roundedValue3) // prints -1.0
print(roundedValue4) // prints 1.0
print(roundedValue5) // prints 1.0
print(roundedValue6) // prints 1.0
ceil(_:)
fonction Darwin fournit une fonction ceil(_:)
ayant la déclaration suivante:
func ceil<T>(_ x: T) -> T where T : FloatingPoint
Le code de Playground ci-dessous montre comment utiliser ceil(_:)
pour arrondir une valeur CGFloat
:
import CoreGraphics
let value1: CGFloat = -0.4
let value2: CGFloat = -0.5
let value3: CGFloat = -1
let value4: CGFloat = 0.4
let value5: CGFloat = 0.5
let value6: CGFloat = 1
let roundedValue1 = ceil(value1)
let roundedValue2 = ceil(value2)
let roundedValue3 = ceil(value3)
let roundedValue4 = ceil(value4)
let roundedValue5 = ceil(value5)
let roundedValue6 = ceil(value6)
print(roundedValue1) // prints -0.0
print(roundedValue2) // prints -0.0
print(roundedValue3) // prints -1.0
print(roundedValue4) // prints 1.0
print(roundedValue5) // prints 1.0
print(roundedValue6) // prints 1.0
NumberFormatter
Si vous voulez arrondir un CGFloat
et le formater avec style dans la même opération, vous pouvez utiliser NumberFormatter
.
import Foundation
import CoreGraphics
let value1: CGFloat = -0.4
let value2: CGFloat = -0.5
let value3: CGFloat = -1
let value4: CGFloat = 0.4
let value5: CGFloat = 0.5
let value6: CGFloat = 1
let formatter = NumberFormatter()
formatter.numberStyle = NumberFormatter.Style.decimal
formatter.roundingMode = NumberFormatter.RoundingMode.ceiling
formatter.maximumFractionDigits = 0
let roundedValue1 = formatter.string(for: value1)
let roundedValue2 = formatter.string(for: value2)
let roundedValue3 = formatter.string(for: value3)
let roundedValue4 = formatter.string(for: value4)
let roundedValue5 = formatter.string(for: value5)
let roundedValue6 = formatter.string(for: value6)
print(String(describing: roundedValue1)) // prints Optional("-0")
print(String(describing: roundedValue2)) // prints Optional("-0")
print(String(describing: roundedValue3)) // prints Optional("-1")
print(String(describing: roundedValue4)) // prints Optional("1")
print(String(describing: roundedValue5)) // prints Optional("1")
print(String(describing: roundedValue6)) // prints Optional("1")
La syntaxe la plus correcte serait probablement:
var f: CGFloat = 2.5
var roundedF = CGFloat(ceil(Double(f)))
Pour utiliser ceil
je vais d’abord faire le CGFloat
un Double
et après plafond, je le reconvertis en CGFloat
.
Cela fonctionne lorsque CGFloat
est défini comme CFloat
ou CDouble
.
Vous pouvez également définir un ceil
pour les floats (Ceci a été réellement implémenté dans Swift 2):
func ceil(f: CFloat) -> CFloat {
return ceilf(f)
}
Ensuite, vous pourrez appeler directement
var roundedF: CGFloat = ceil(f)
tout en préservant la sécurité de type.
Je pense en fait que cela devrait être la solution choisie par Apple, au lieu d’avoir des fonctions séparées ceil
et ceilf
car elles n’ont aucun sens dans Swift.
à partir de Swift Standard Library , vous pouvez également le contourner sur place:
var value: CGFloat = -5.7
value.round(.up) // -5.0
Construire à partir de la réponse de holex. J'ai fait
func accurateRound(value: Double) -> Int {
var d : Double = value - Double(Int(value))
if d < 0.5 {
return Int(value)
} else {
return Int(value) + 1
}
}
- éditer l'extension d'édition -
J'ai aussi récemment transformé cela en une extension pour Floats que je partagerais aussi :)
extension Float {
func roundToInt() -> Int{
var value = Int(self)
var f = self - Float(value)
if f < 0.5{
return value
} else {
return value + 1
}
}
}
Cela fait en sorte que vous pouvez juste être comme
var f : Float = 3.3
f.roundToInt()
Utilisez-le sur Swift 5
let x = 6.5
// Equivalent to the C 'round' function:
print(x.rounded(.toNearestOrAwayFromZero))
// Prints "7.0"
// Equivalent to the C 'trunc' function:
print(x.rounded(.towardZero))
// Prints "6.0"
// Equivalent to the C 'ceil' function:
print(x.rounded(.up))
// Prints "7.0"
// Equivalent to the C 'floor' function:
print(x.rounded(.down))
// Prints "6.0"