Colliot
Colliot

Reputation: 1551

Swift binary operator '+' cannot be applied to two CGFloat operands

I am writing a function in Swift to detect which hexagon I am clicking on. But I ran into a peculiar error message stating that I cannot add two CGFloats. Whatever I did, e.g. changing let to var, declare and assign separately, did not work. I guess there must be something else wrong, but I cannot find it. The code is as follows:

func pointToCoordinate(position: CGPoint) -> (Int, Int) {
        var gridHeight = 2 * singleRadius / sqrt(CGFloat(3)) * 1.5
        var gridWidth = 2 * singleRadius
        var halfWidth = singleRadius

        var relativePosition = CGPoint(x: position.x - totalRadius / 2, y: position.y - totalRadius / 2)
        println((relativePosition.y / gridHeight))
        var row = -(cgfloatToInt)(relativePosition.y / gridHeight)
        var column: Int

        println((relativePosition.x + halfWidth * CGFloat(row + 1)) / (gridWidth))
        column = cgfloatToInt((relativePosition.x + halfWidth * CGFloat(row + 1)) / (gridWidth))

//        var innerY: CGFloat = CGFloat(relativePosition.y) + CGFloat(gridHeight * row)
        var innerX = relativePosition.x
        var innerY = relativePosition.y

        innerY = innerY - CGFloat(gridHeight * row)

        println((innerX, innerY))
        return (column, row)
    }

Error Message

Upvotes: 17

Views: 38971

Answers (5)

user3069232
user3069232

Reputation: 8995

iOS 15, Swift 5.x

I had this problem, was solved by unwrapping the value... the floats in my case were optionals.

Upvotes: 2

Michael Shang
Michael Shang

Reputation: 756

Looking through all the answers, castings, conversion and extensions, I think the best solution yet to say for Swift is Operator Overload. Code sample below for Swift 3.0:

/// overloads -/+ between a cgfloat on the left and an int/double on the right
func - (left: CGFloat, right: Double) -> CGFloat {
    return left - CGFloat(right);
}

func - (left: CGFloat, right: Int) -> CGFloat {
    return left - CGFloat(right);
}

func + (left: CGFloat, right: Double) -> CGFloat {
    return left + CGFloat(right);
}

func + (left: CGFloat, right: Int) -> CGFloat {
    return left + CGFloat(right);
}

Put this into a global place OUTSIDE of any class. See magic occurs.

Upvotes: 5

san
san

Reputation: 3328

Late to join. Based on vacawama's answer, you all know the problem is not having the same data type.
CGFloat needs to be written multiple times sometimes. I found this easier via extension. So sharing an answer. You can create a simple extension like below. Ofcourse, this extension can be further modified.

import CoreGraphics
extension Int {
    var cgf: CGFloat { return CGFloat(self) }
    var f: Float { return Float(self) }
}

extension Float {
    var cgf: CGFloat { return CGFloat(self) }
}

extension Double {
    var cgf: CGFloat { return CGFloat(self) }
}

extension CGFloat {
    var f: Float { return Float(self) }
}

Now we can write

innerY = innerY - gridHeight * row.cgf

Upvotes: 1

vacawama
vacawama

Reputation: 154631

The error message is wrong. The problem is that you are trying to multiply an Int and a CGFloat.

Replace:

innerY = innerY - CGFloat(gridHeight * row)

with:

innerY = innerY - gridHeight * CGFloat(row)

The answer above is for the current version of your code. For the commented out version that corresponds to the error message you posted:

Replace:

var innerY: CGFloat = CGFloat(relativePosition.y) + CGFloat(gridHeight * row)

with

var innerY: CGFloat = CGFloat(relativePosition.y) + gridHeight * CGFloat(row)

Upvotes: 56

Chris Conover
Chris Conover

Reputation: 9039

Indeed, there is something else wrong, this works:

import QuartzCore

let a:CGFloat = 1
let b:CGFloat = 2

let c = a + b
var innerY: CGFloat = CGFloat(1.0) + CGFloat(2.0)

and CGFloat implements the FloatingPointType type

Upvotes: 3

Related Questions