Advance way of using UIView convertRect method to detect CGRectIntersectsRect multiple times
- by Chris
I recently asked a question regarding collision detection within subviews, with a perfect answer. I've come to the last point in implementing the collision on my application but I've come across a new issue.
Using convertRect was fine getting the CGRect from the subView. I needed it to be a little more complex as it wasn't exactly rectangles that needed to be detected.
on XCode I created an abstract class called TileViewController. Amongst other properties it has a IBOutlet UIView *detectionView;
I now have multiple classes that inherit from TileViewController, and each class there are multiple views nested inside the detectionView which I have created using Interface Builder.
The idea is an object could be a certain shape or size, I've programatically placed these 'tiled' detection points bottom center of each object. A user can select an item and interactive with it, in this circumstance move it around. Here is my touchesMoved method
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:touch.view];
interactiveItem.center = location; // The ViewController the user has chosen to interact with
interactiveView.view.center = location;
// checks if the user has selected an item to interact with
if (interactiveItem) {
// First get check there is more then 1 item in the collection
NSUInteger assetCount = [itemViewCollection count]; //NSMutableArray that holds the ViewControllers
int detectionCount = 0; // To count how many times a CGRectIntersectsRect occured
UIView *parentView = self.view;
// if there is more then 1 item begin collision detection
if (assetCount > 1) {
for (TileViewController *viewController in itemViewCollection)
{
if (viewController.view.tag != interactiveView.view.tag) {
if (viewController.detectionView.subviews) {
for (UIView *detectView in viewController.detectionView.subviews) {
CGRect viewRect;
viewRect = [detectView convertRect:[detectView frame] toView:parentView];
// I could have checked to see if the below has subViews but didn't - In my current implementation it does anyway
for (UIView *detectInteractView in interactiveView.detectionView.subviews) {
CGRect interactRect;
interactRect = [detectInteractView convertRect:[detectInteractView frame] toView:parentView];
if (CGRectIntersectsRect(viewRect, interactRect) == 1) {
NSLog(@"collision detected");
[detectView setBackgroundColor:[UIColor blueColor]];
[detectInteractView setBackgroundColor:[UIColor blueColor]];
detectionCount++;
}
else {
[detectView setBackgroundColor:[UIColor yellowColor]];
[detectInteractView setBackgroundColor:[UIColor yellowColor]];
}
}
}
}
}
}
// Logic if no items collided
if (detectionCount == 0) {
NSLog(@"Do something");
}
}
}
}
Now the method itself works to an extent but I don't think it's working with the nested values properly as the detection is off.
A simplified version of this method works - Using CGRectIntersectsRect on the detectionView itself so I'm wondering if I'm looping through and checking the views correctly?
I wasn't sure whether it was comparing in the same view but I suspect it is, I did modify the code slightly at one point, rather then comparing the values in self.view I took the viewController.detectView's UIViews into the interactiveView.detectView but the outcome was the same.
It's rigged so the subviews change colour, but they change colour when they are not even touching, and when they do touch the wrong UIviews are changing colour
Many thanks in advance