Search code examples
swiftswift2xcode7cgrect

Trouble converting custom CGRect function from Objective-C to Swift


I've been going back and forth on trying to convert a custom CGRect function from Objective-C to Swift.

I'll make some small progress but then I always end up getting stuck. Here is the working function in Objective-C:

CGRect CGRectSmallestWithCGPoints(NSMutableArray *pointsArray, int numberOfPoints) {

NSValue *firstValue = pointsArray[0];

CGFloat greatestXValue = [firstValue CGPointValue].x;
CGFloat greatestYValue = [firstValue CGPointValue].y;
CGFloat smallestXValue = [firstValue CGPointValue].x;
CGFloat smallestYValue = [firstValue CGPointValue].y;

for(int i = 1; i < numberOfPoints; i++) {
    NSValue *value = pointsArray[i];

    CGPoint point = [value CGPointValue];
    greatestXValue = MAX(greatestXValue, point.x);
    greatestYValue = MAX(greatestYValue, point.y);
    smallestXValue = MIN(smallestXValue, point.x);
    smallestYValue = MIN(smallestYValue, point.y);
}

CGRect rect;

rect.origin = CGPointMake(smallestXValue, smallestYValue);
rect.size.width = greatestXValue - smallestXValue;
rect.size.height = greatestYValue - smallestYValue;

  return rect;
}

Here's where I currently am with the Swift conversion:

func CGRectSmallestWithCGPoints(pointsArray: NSArray, numberOfPoints: Int) -> CGRect {

    var greatestXValue = pointsArray[0].x
    var greatestYValue = pointsArray[0].y
    var smallestXValue = pointsArray[0].x
    var smallestYValue = pointsArray[0].y

    for(var i = 1; i < numberOfPoints; i++)
    {
        let point = pointsArray[i];

        greatestXValue = max(greatestXValue, point.x);
        greatestYValue = max(greatestYValue, point.y);
        smallestXValue = min(smallestXValue, point.x);
        smallestYValue = min(smallestYValue, point.y);
    }

    var rect = CGRect()
    rect.origin = CGPointMake(smallestXValue, smallestYValue);
    rect.size.width = greatestXValue - smallestXValue;
    rect.size.height = greatestYValue - smallestYValue;

    return rect;
}

The errors start in the for loop. When I try to use max and min it gives me the following error:

Cannot assign a value of type 'CLHeadingComponentValue' (aka 'Double') to a value of type 'CLHeadingComponentValue!'

And then after the for loop when I modify the rect values it gives me a similar error:

Cannot assign a value of type 'CLHeadingComponentValue' (aka 'Double') to a value of type 'CGFloat'

I'm having trouble understanding why this conversion seems so hard. I've been using Swift on and off for the past few weeks now and I've gotten stuck on certain things like some of the optional concepts but never been stuck on something for this long before.

I'm using Xcode 7 beta with Swift 2 and would really appreciate your help thanks.


Solution

  • You have some mistakes in your code, you have to use the CGPointValue property instead of the x property directly see the fixed code:

    func CGRectSmallestWithCGPoints(pointsArray: NSArray, numberOfPoints: Int) -> CGRect {
    
        var greatestXValue: CGFloat = pointsArray[0].CGPointValue.x
        var greatestYValue: CGFloat = pointsArray[0].CGPointValue.y
        var smallestXValue: CGFloat = pointsArray[0].CGPointValue.x
        var smallestYValue: CGFloat = pointsArray[0].CGPointValue.y
    
        for(var i = 1; i < numberOfPoints; i++) {
    
           let point = pointsArray[i].CGPointValue
    
           greatestXValue = max(greatestXValue, point.x)
           greatestYValue = max(greatestYValue, point.y)
           smallestXValue = min(smallestXValue, point.x)
           smallestYValue = min(smallestYValue, point.y)
        }
    
        var rect = CGRect()
        rect.origin = CGPointMake(smallestXValue, smallestYValue);
        rect.size.width = greatestXValue - smallestXValue;
        rect.size.height = greatestYValue - smallestYValue;
    
        return rect
    }
    

    I hope this help you.