When you move a view to a random point, you
must take into account several things. Often a view must fit entirely
within its parent’s view container so there aren’t parts of the view
clipped off. You may also want to add a boundary to that container so
the view does not quite touch the parent’s edge at any time. Finally,
if you’re working with out-of-the-box SDK versions of the UIView
class, you need to work with random centers, not random positions. Just picking a point somewhere in
the parent view fails some or all of these qualifications.
Recipe 1 approaches this problem by creating a series of insets. It uses the UIEdgeInset
structure to define the boundaries for the view. This structure
contains four inset values, corresponding to the amount to inset a
rectangle at its top, left, bottom, and right.
typedef struct {
CGFloat top, left, bottom, right;
} UIEdgeInsets;
This method uses the UIEdgeInsetsInsetRect() function to narrow a CGRect rectangle to create an inner container, which is called innerRect in this method.
It
then narrows the container even further. It insets that rectangle by
half the child’s height and width. This leaves enough room around any
point in the subrectangle to allow the placement of the child view,
guaranteeing that the view can do so without overlapping the inner
bounded rectangle. Select any point in that subrectangle to return a
valid center for the child view.
Recipe 1. Randomly Moving a Bounded View
- (CGPoint) randomCenterInView: (UIView *) aView withInsets: (UIEdgeInsets) insets { // Move in by the inset amount and then by size of the subview CGRect innerRect = UIEdgeInsetsInsetRect([aView bounds], insets); CGRect subRect = CGRectInset(innerRect, self.frame.size.width / 2.0f, self.frame.size.height / 2.0f); // Return a random point float rx = (float)(random() % (int)floor(subRect.size.width)); float ry = (float)(random() % (int)floor(subRect.size.height)); return CGPointMake(rx + subRect.origin.x, ry + subRect.origin.y); }
- (CGPoint) randomCenterInView: (UIView *) aView withInset: (float) inset { UIEdgeInsets insets = UIEdgeInsetsMake(inset, inset, inset, inset); return [self randomCenterInView:aView withInsets:insets]; }
- (void) moveToRandomLocationInView: (UIView *) aView { self.center = [self randomCenterInView:aView withInset:5]; return; }
|