SwiftでCGFloatを切り上げるにはどうすればよいですか? 試してみましceil(CDouble(myCGFloat))
たが、iPad Air と iPhone 5S でしか動作しません。
別のシミュレートされたデバイスで実行すると、次のエラーが表示されます'NSNumber' is not a subtype of 'CGFloat'
更新: Apple は、次のような一般的な関数の CGFloat 固有のバージョンをいくつか定義しましたceil
。
func ceil(x: CGFloat) -> CGFloat
...具体的には、32/64 ビットの違いに対処するためです。単純ceil
に CGFloat 引数を使用すると、すべてのアーキテクチャで機能するはずです。
私の元の答え:
これはかなりひどいと思いますが、もっと良い方法を考えられる人はいますか? #if
ではうまくいかないようですCGFLOAT_IS_DOUBLE
; 条件付きコンパイルのドキュメントで確認できることから、ビルド構成に限定されていると思います。
var x = CGFloat(0.5)
#if arch(x86_64) || arch(arm64)
var test = ceil(x)
#else
var test = ceilf(x)
#endif
Swift 5 では、 a を切り上げるために、次の 3 つのパスのいずれかを選択できますCGFloat
。
CGFloat
のrounded(_:)
方法を使用するFloatingPoint
protocol は、それに準拠する型にrounded(_:)
メソッドを提供します。には次の宣言がありますCGFloat
。rounded(_:)
func rounded(_ rule: FloatingPointRoundingRule) -> CGFloat
指定された丸め規則を使用して整数値に丸められたこの値を返します。
以下の Playground サンプル コードはrounded(_:)
、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(_:)
機能の使用Darwinceil(_:)
は、次の宣言を持つ関数を提供します。
func ceil<T>(_ x: T) -> T where T : FloatingPoint
以下の Playground コードはceil(_:)
、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
同じ操作でa を切り上げてCGFloat
スタイルでフォーマットする場合は、 を使用できます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")
最も正しい構文は、おそらく次のようになります。
var f: CGFloat = 2.5
var roundedF = CGFloat(ceil(Double(f)))
使用するceil
には、最初にCGFloat
aを作成しDouble
、その後、天井を に戻しCGFloat
ます。
がまたはCGFloat
として定義されている場合に機能します。CFloat
CDouble
ceil
for floatを定義することもできます(これは実際には Swift 2 で実装されています)。
func ceil(f: CFloat) -> CFloat {
return ceilf(f)
}
その後、直接電話をかけることができます
var roundedF: CGFloat = ceil(f)
型安全性を維持しながら。
Swift では意味をなさないため、別個のceil
and関数を使用するのではなく、これが Apple によって選択されたソリューションであるべきだと私は実際に信じています。ceilf
Swift 標準ライブラリから、インプレースで丸めることもできます。
var value: CGFloat = -5.7
value.round(.up) // -5.0
ホールレックスの答えから構築します。やった
func accurateRound(value: Double) -> Int {
var d : Double = value - Double(Int(value))
if d < 0.5 {
return Int(value)
} else {
return Int(value) + 1
}
}
-編集拡張版-
私も最近、これを Floats の拡張機能に変えました:)
extension Float {
func roundToInt() -> Int{
var value = Int(self)
var f = self - Float(value)
if f < 0.5{
return value
} else {
return value + 1
}
}
}
これにより、次のようになります
var f : Float = 3.3
f.roundToInt()