5

I tried to do some simple UIView layout math in swift and tried the following line of code...

var offset: CGFloat = (bounds.width / 2.0) - ((sortedSymptoms.count * bounds.height) / 2.0)

and got the following error from the compiler:

cannot invoke '-' with an argument list of type '(($T6), ($T17))'
        var offset: CGFloat = (bounds.width / 2.0) - ((sortedSymptoms.count * bounds.height) / 2.0)
                              ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~    

The compiler error isn't all that helpful, but it looks like there's a type conflict between Double, Int, and CGFloat of some kind. I was able to get the line to compile by sprinkling in some explicit creations of CGFloats, but I can't believe that this is the right way to do this.

var offset: CGFloat = (bounds.width / CGFloat(2.0)) - ((CGFloat(sortedSymptoms.count) * bounds.height) / CGFloat(2.0))

What's the right way?

Mike Akers
  • 12,039
  • 14
  • 58
  • 71

1 Answers1

8

This is a known issue in Swift and the dev team has been working on improving the issue around CGFloat in particular. But at this time, yes, that's how you write it.

Some followup from devforums (which may make you happy or sad, but at least roughly explains the current status): https://devforums.apple.com/message/1026028#1026028

Note that the main issue here is that the literal 2.0 doesn't coerce to CGFloat, which it arguably should. But count will likely always require a cast, by intent. You cannot always safely convert between numeric types, and Swift intentionally forces you to consider each time you do these kinds of casts. But it should be possible to determine if a literal conversion is safe at compile-time, so that should be fixable.

Rob Napier
  • 286,113
  • 34
  • 456
  • 610
  • Thanks for the devforums link, yeah this is nasty, but makes sense. I hope they figure out an elegant solution, and I hope we don't have to wait for next WWDC before we can start using it. – Mike Akers Sep 26 '14 at 20:28