Question or problem in the Swift programming language:
I’m simply trying to round the CGFloat return value of CGRectGetWidth.
override func layoutSubviews() { let roundedWidth = roundf(CGRectGetWidth(self.bounds)) ... }
The compiler won’t let me, giving the error:
‘NSNumber’ is not a subtype of ‘CFloat’.
I guess there is some basic thing I am missing here. roundf is taking a CFloat as argument, so how can I convert my CGFloat to CFloat to make the conversion?
Update:
Now using round instead of roundf but I am still getting the same error. I’ve tried cleaning the project and restarting Xcode.
How to solve the problem:
Solution 1:
CGRect
members are CGFloats
, which, despite their name, are actually CDoubles
. Thus, you need to use round()
, not roundf()
override func layoutSubviews() { let roundedWidth = round(CGRectGetWidth(self.bounds)) ... }
Solution 2:
The problem is that CGFloat is platform dependent (just like it is in ObjC). In a 32 bit environment, CGFloat is type aliased to CFloat – in a 64 bit environment, to CDouble. In ObjC, without the more pedantic warnings in place, round was happy to consume your float, and roundf your doubles.
Swift doesn’t allow implicit type conversions.
Try building for an iPhone 5 and a iPhone 5s simulator, I suspect you’ll see some differences.
Solution 3:
For some reason I needed to make an explicit typecast to CDouble
to make it work.
let roundedWidth = round(CDouble(CGRectGetWidth(self.bounds)))
I find this pretty strange since a CGFloat
is a CDouble
by definition. Seems like the compilator got a bit confused here for some reason.
Solution 4:
CGFloat() works with all architectures for me.