Reputation: 2042
My intention is to compare CGPoints
or CGPoint
values (and as the app is also for Mac OS NSPoints
or NSPoint
values) of several moving objects to detect if the objects have the same position.
My first solution to this was to fast enumerate an array of those objects and store all CGPoints
to an array, then fast enumerate the array of objects again to check whether the position is the same of any other object:
// STEP 1: Collect all Positions
NSMutableArray *allPositions = [NSMutableArray arrayWithCapacity:self.allObjects.count];
for (Object *myObject in self.allObjects) {
CGPoint myObjectPosition = ...;
[allPositions addObject:myObjectPosition]; // Problem here
}
// STEP 2: Check for Overlapping
for (Object *myObject in self.allObjects) {
CGPoint myObjectPosition = ...;
if ([allPositions containsObject:myObjectPosition] {
// Overlapping
}
}
The problem with this is adding the points to the allPositions
Array. Therefore NSValue
can be used:
[NSValue valueWithCGPoint:point];
But this does work only under iOS, for Mac OS there has to be used valueWithPoint
and NSPoint
.
Can I save maybe save the x
and the y
values in dictionaries and store them to the allPositions
Array? Or is there an even better solution without having 2x fast enumerations? There are about 100 objects in self.allObjects
...
Upvotes: 3
Views: 3561
Reputation: 519
While working on universal iOS/OSX app i solved this problem by using NSValue category. NSValue+CGPoint.h:
@interface NSValue (CGPoint)
#if TARGET_OS_MAC
+ (NSValue *)valueWithCGPoint:(CGPoint)point;
- (CGPoint)CGPointValue;
#endif
@end
NSValue+CGPoint.m:
#import "NSValue+CGPoint.h"
@implementation NSValue (CGPoint)
#if TARGET_OS_MAC
+ (NSValue *)valueWithCGPoint:(CGPoint)point {
return [NSValue valueWithPoint:point];
}
- (CGPoint)CGPointValue {
return [self pointValue];
}
#endif
@end
Now i can use the same code on both iOS and Mac, for example:
// store point in NSValue
CGPoint p = {10, 10};
NSValue *v = [NSValue valueWithCGPoint:p];
// read point from NSValue
CGPoint p2 = [v CGPointValue];
Upvotes: 1
Reputation: 22930
//NSGeometry.h
typedef CGPoint NSPoint;
//CGGeometry.h
struct CGPoint {
CGFloat x;
CGFloat y;
};
typedef struct CGPoint CGPoint;
NSPoint
and CGpoint
are same;
// NSValue/+valueWithPoint:(NSPoint)point is available on Mac OS X
// NSValue/+valueWithCGPoint:(CGPoint)point is available on iOS
//save value in CGPoint
if([NSValue respondsToSelector:@selector(valueWithPoint:)])
{
NSPoint lPoint = NSPointFromCGPoint(lCGPoint);
// do some op
}
else {
// do some op
}
EDIT
Dont use respondsToSelector
, use TARGET_OS_IPHONE
macro.
Upvotes: 0
Reputation: 21966
CGPoint and NSPoint are the same struct. It doesn't matter if they got a different name, they both hold two CGFloat. They got the same size and the same alignment, and therefore they can be used interchangeably. So in your case valueWithPoint: fits.
Edit
About the second thing you ask, this should be done with macros:
#if TARGET_OS_IPHONE
value= [NSValue valueWithCGPoint: point];
#else
value= [NSValue valueWithPoint: point];
#endif
Getting the point back:
#if TARGET_OS_IPHONE
point= value.CGPointValue;
#else
point= value.pointValue;
#endif
http://sealiesoftware.com/blog/archive/2010/8/16/TargetConditionalsh.html
Upvotes: 6