27

Here my code. I am passing two values into CGRectMake(..) and getting and error.

let width = CMVideoFormatDescriptionGetDimensions(device.activeFormat.formatDescription as CMVideoFormatDescriptionRef!).width
// return Int32 value

let height = CMVideoFormatDescriptionGetDimensions(device.activeFormat.formatDescription as CMVideoFormatDescriptionRef!).height
// return Int32 value

myLayer?.frame = CGRectMake(0, 0, width, height)
// returns error: '`Int32`' not convertible to `CGFloat`

How can I convert Int32 to CGFloat to not return an error?

cdpalmer
  • 658
  • 1
  • 7
  • 19
iosLearner
  • 1,312
  • 1
  • 16
  • 30
  • Direct `Int` to `CGFloat` conversion might be time consuming. Consider using different methods if API is available. For example, you can create `CGSize` from `Int`, and then do `let dividedSize =size.applying(.init(scaleX: 0.5, y: 0.5))`, instead of converting Int's to CGFloat for dividing. – Oleksii Nezhyborets Oct 24 '19 at 11:45

2 Answers2

72

To convert between numerical data types create a new instance of the target type, passing the source value as parameter. So to convert an Int32 to a CGFloat:

let int: Int32 = 10
let cgfloat = CGFloat(int)

In your case you can either do:

let width = CGFloat(CMVideoFormatDescriptionGetDimensions(device.activeFormat.formatDescription as CMVideoFormatDescriptionRef!).width)
let height = CGFloat(CMVideoFormatDescriptionGetDimensions(device.activeFormat.formatDescription as CMVideoFormatDescriptionRef!).height)

myLayer?.frame = CGRectMake(0, 0, width, height)

or:

let width = CMVideoFormatDescriptionGetDimensions(device.activeFormat.formatDescription as CMVideoFormatDescriptionRef!).width
let height = CMVideoFormatDescriptionGetDimensions(device.activeFormat.formatDescription as CMVideoFormatDescriptionRef!).height

myLayer?.frame = CGRectMake(0, 0, CGFloat(width), CGFloat(height))

Note that there is no implicit or explicit type casting between numeric types in swift, so you have to use the same pattern also for converting a Int to Int32 or to UInt etc.

Antonio
  • 71,651
  • 11
  • 148
  • 165
  • I wonder, is it safe to do this conversion on 32-bit systems, where `int32` is (still) 32 bits, however `CGFloat` is 32 bits too. Taking in account that latter is a floating point and [this answer](http://stackoverflow.com/a/30260843/1492173), there will be a loss of precision. Please, correct me if I'm wrong. – Yevhen Dubinin Mar 02 '16 at 00:02
  • I wonder why `let x: Int = 1; let y: Int = 2; let progress = CGFloat(x / y)` wasn't working for me. However, individually wrapping x and y as CGFloats worked. – Andrew Kirna Jun 19 '19 at 16:08
  • 1
    @AndrewKirna not working because it doesn't compile, or because of an unexpected result? In the latter case, the result is 0. `x` and `y` are `Int`, the division truncates, so `1 / 2 = 0` However if you convert at least one to CGFloat, the operands are both CGFLoat, so the expression evaluates to 0.5 – Antonio Jun 21 '19 at 14:10
  • @Antonio, it was because of an unexpected result. But that makes sense...I forgot all Integer division takes the floor of the result even though I'm converting the result to a CGFloat. In other words, the float version of 0 will still be 0. – Andrew Kirna Jun 21 '19 at 14:22
  • Expression took 37ms to type-check (limit: 33ms) – Anton Duzenko Sep 04 '21 at 08:48
3

Just explicitly convert width and height to CGFloat using the CGFloat's initializer:

myLayer?.frame = CGRectMake(0, 0, CGFloat(width), CGFloat(height))
Ivica M.
  • 4,763
  • 1
  • 23
  • 16