Search code examples
objective-cuicollectionviewuicollectionviewlayout

Xcode - Round to closest X value considering altered base x/y positions


I'm currently working on a UICollectionViewLayout which is more or less similar to the Garageband iPad Appication - featuring reusable decoration/supplementary views.

One of the main features is gridline snapping - which would enable you to snap the X/Y frame positions of the GREEN cells to the nearest horizontal/vertical gridline.

The issue I'm having, is that the base X/Y position doesn't start at 0,0 because I have a floating column and floating row - so my snapping calculation is wrong because it doesn't consider the floating row/floating column width/height.

Here is an image illustrating my problem:

snapping/coordinate problem Here is my code for calculating the snapped positions:

CGPoint cellTopLeft = self.frame.origin;
CGFloat gridlineWidth = 30;
CGFloat floatingColumnWidth = 120; // width of the floating left column
CGFloat floatingRowHeight = 100; // height of the floating top row
CGFloat rowHeight = 100; // height of rows on the left (table 0, table 1, table 2, etc)

float snapped_x = [self closest:cellTopLeft.x toValue:gridlineWidth];
float snapped_y = [self closest:cellTopLeft.y toValue:rowHeight];

- (float)closest:(float)input toValue:(float)value {
    return value * floorf((input / value) + 0.5);
}

As you can see by the "Grand 0" green cell that I'm actively dragging, the position is wrong.


Solution

  • Thanks @zrzka - sometimes the seemingly complicated bugs can be the easiest ones to solve, and just takes an extra pair of eyes.

    The solution was:

    float snapped_x = [self closest:cellTopLeft.x - floatingColumnWidth toValue:gridlineWidth] + floatingColumnWidth
    float snapped_y = [self closest:cellTopLeft.y - floatingRowHeight toValue:rowHeight] + floatingRowHeight;