Which view was touched?

Touch and drag the circles. Although a Circle object belongs to a subclass of UIView and is therefore rectangular, it is sensitive to touch only on and within the circumference. The four corners of the Circle outside of the circumference are insensitive to touch, and are clear in color. See the pointInside:withEvent: method of class UIView, and Hit Testing. The touched circle moves to the front, i.e., it is placed on top of the other circles. See the bringSubviewToFront: method of class UIView.

A touch object passed to touchesMoved:withEvent: has a previous location as well as a current location.

Source code in Hit.zip

  1. main.m
  2. Class HitAppDelegate
  3. Class View: the white background.
  4. Class Circle: a movable circle. Calls pointInside:withEvent: and bringSubviewToFront:.

Things to try

  1. Create the three Circle objects with an array of structures and a for loop in the if statement in the initWithFrame: method of class View. For another array of structures, see Manhattan.
    		typedef struct {
    			CGFloat x, y;	//of center
    			CGFloat radius;
    			SEL color;
    		} circle_t;
    		CGFloat w = self.bounds.size.width;
    		CGFloat h = self.bounds.size.height;
    		const circle_t a[] = {
    			{w / 2, h / 4,     w / 10, @selector(greenColor)},
    			{w / 2, h / 2,     w /  8, @selector(cyanColor)},
    			{w / 2, h * 5 / 8, w / 5,  @selector(blueColor)}
    		const size_t n = sizeof a / sizeof a[0];
    		for (size_t i = 0; i < n; ++i) {
    			CGPoint point = CGPointMake(
    				self.bounds.origin.x + a[i].x,
    				self.bounds.origin.y + a[i].y
    			Circle *circle = [[Circle alloc]
    				initWithCenter: point
    				radius:  a[i].radius
    				color: [[UIColor class] performSelector: a[i].color]
    			[self addSubview: circle];

  2. Class Circle contains the code to detect a touch and update the center property of each Circle. All of this could be done in class View instead. See the hitTest:withEvent: method of class UIView.