Permalink
Browse files

Merge pull request #3 from luugiathuy/master

Multiple slotlights support
  • Loading branch information...
mcconkiee committed Jul 26, 2012
2 parents b15b0aa + a81fc3c commit cd55d33cda430771dd64b547669bbaafe9524cba
View
@@ -31,9 +31,9 @@ typedef enum
/*
- // return a view where the spotlight should shine
+ // return an array of UIView where spotlights should shine
*/
--(UIView*)hintStateViewToHint:(id)hintState;
+-(NSArray*)hintStateViewsToHint:(id)hintState;
/*
// the default hint space is a label with white helvetica text dynamically centered,
@@ -42,10 +42,10 @@ typedef enum
-(UIView*)hintStateViewForDialog:(id)hintState;
/*
- // return a rect for where the spotlight should shine.
- // convenient if a UIView is not an option
+ // return an array of rects (NSValue objs) for where spotlights should shine.
+ // convenient if UIView array is not an option
*/
--(CGRect)hintStateRectToHint:(id)hintState;
+-(NSArray*)hintStateRectsToHint:(id)hintState;
/*
// return NO, if you plan to daisy chain hints, or do someother action
View
@@ -69,23 +69,23 @@ -(void)presentModalMessage:(NSString*)message where:(UIView*)presentationPlace
{
//incase we have many in a row
if(_modalView!=nil)
- [_modalView removeFromSuperview];
+ [self clear];
- if ([self.hintDelegate respondsToSelector:@selector(hintStateViewToHint:)]) {
- UIView *v = [self.hintDelegate hintStateViewToHint:self];
- if(v!=nil)
- _modalView = [[EMHintsView alloc] initWithFrame:presentationPlace.frame forView:v];
+ if ([self.hintDelegate respondsToSelector:@selector(hintStateViewsToHint:)]) {
+ NSArray *viewArray = [self.hintDelegate hintStateViewsToHint:self];
+ if(viewArray!=nil)
+ _modalView = [[EMHintsView alloc] initWithFrame:presentationPlace.frame forViews:viewArray];
}
- if ([self.hintDelegate respondsToSelector:@selector(hintStateRectToHint:)]) {
- CGRect rect = [self.hintDelegate hintStateRectToHint:self];
- if (rect.size.width>0 && rect.size.height>0)
- _modalView = [[EMHintsView alloc] initWithFrame:presentationPlace.frame withRect:rect];
+ if ([self.hintDelegate respondsToSelector:@selector(hintStateRectsToHint:)]) {
+ NSArray* rectArray = [self.hintDelegate hintStateRectsToHint:self];
+ if (rectArray != nil)
+ _modalView = [[EMHintsView alloc] initWithFrame:presentationPlace.frame withRects:rectArray];
}
if (_modalView==nil)
- [NSException raise:@"No ModalView protocols"
- format:@"you must at least implement a view or point "];
+ _modalView = [[EMHintsView alloc] initWithFrame:presentationPlace.frame];
+
[_modalView setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)];
[presentationPlace addSubview:_modalView];
@@ -17,9 +17,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
@interface EMHintsView : UIView
{
- CGPoint _position;
- CGFloat _radius;
+ // array positions of spotlights
+ NSMutableArray* _positionArray;
+ // array radius of spotlights
+ NSMutableArray* _radiusArray;
}
-- (id)initWithFrame:(CGRect)frame forView:(UIView*)onView;
-- (id)initWithFrame:(CGRect)frame withRect:(CGRect)aRect;
+
+- (id)initWithFrame:(CGRect)frame;
+- (id)initWithFrame:(CGRect)frame forViews:(NSArray*)viewArray;
+- (id)initWithFrame:(CGRect)frame withRects:(NSArray*)rectArray;
@end
@@ -20,46 +20,75 @@
@implementation EMHintsView
-- (id)initWithFrame:(CGRect)frame withRect:(CGRect)aRect
+- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
- // Initialization code
- _position = CGPointMake(aRect.origin.x,
- aRect.origin.y);
- _radius = aRect.size.width;
+ // initialize arrays
+ _positionArray = [[NSMutableArray alloc] init];
+ _radiusArray = [[NSMutableArray alloc] init];
+
+ // set background color
[self setBackgroundColor:[UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:BACKGROUND_ALPHA]];
}
return self;
}
-- (id)initWithFrame:(CGRect)frame forView:(UIView*)onView
+- (id)initWithFrame:(CGRect)frame withRects:(NSArray *)rectArray
+{
+ self = [super initWithFrame:frame];
+ if (self) {
+ _positionArray = [[NSMutableArray alloc] init];
+ _radiusArray = [[NSMutableArray alloc] init];
+ // add spotlight position and radius
+ for (NSValue* theRectObj in rectArray)
+ {
+ CGRect theRect = [theRectObj CGRectValue];
+ CGPoint pos = CGPointMake(theRect.origin.x, theRect.origin.y);
+ CGFloat radius = theRect.size.width;
+ [_positionArray addObject:[NSValue valueWithCGPoint:pos]];
+ [_radiusArray addObject:[NSNumber numberWithFloat:radius]];
+ }
+ [self setBackgroundColor:[UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:BACKGROUND_ALPHA]];
+ }
+ return self;
+}
+
+- (id)initWithFrame:(CGRect)frame forViews:(NSArray *)viewArray
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
- _position = CGPointMake(onView.frame.origin.x + (onView.frame.size.width/2)
- , onView.frame.origin.y + (onView.frame.size.height/2) );
- _radius = onView.frame.size.width;
+ _positionArray = [[NSMutableArray alloc] init];
+ _radiusArray = [[NSMutableArray alloc] init];
+ // add spotlight position and radius
+ for (UIView* theView in viewArray)
+ {
+ CGPoint pos = CGPointMake(theView.frame.origin.x + (theView.frame.size.width/2)
+ , theView.frame.origin.y + (theView.frame.size.height/2) );
+ CGFloat radius = theView.frame.size.width;
+ [_positionArray addObject:[NSValue valueWithCGPoint:pos]];
+ [_radiusArray addObject:[NSNumber numberWithFloat:radius]];
+ }
+
[self setBackgroundColor:[UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:BACKGROUND_ALPHA]];
}
return self;
}
-(void)_background:(CGRect)rect
{
- CGPoint c = _position;
-
+ // context for drawing
CGContextRef context = UIGraphicsGetCurrentContext();
CGImageRef backgroundimage = CGBitmapContextCreateImage(context);
CGContextClearRect(context, rect);
//CGContextDrawImage(context, rect, backgroundimage);
- // Draw the masking image
+ // save state
CGContextSaveGState(context);
- //flip the context (right-sideup)
+ // flip the context (right-sideup)
CGContextTranslateCTM(context, 0, rect.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
@@ -76,47 +105,57 @@ -(void)_background:(CGRect)rect
CGFloat colorLocations[2] = {0.25,0.5};
- //create the gradient Ref
- CGGradientRef gradientRef = CGGradientCreateWithColorComponents(colorspace, components, colorLocations, 2);
- CGColorSpaceRelease(colorspace);
-
- //draw the shape
- CGFloat radius =_radius;
- CGMutablePathRef path = CGPathCreateMutable();
- //
- //draw a rect around view
- CGPathAddRect(path, NULL, CGRectMake(c.x - _radius, c.y -radius,100,100));
- CGPathAddLineToPoint(path, NULL, c.x +_radius, c.y - _radius);
- CGPathAddLineToPoint(path, NULL, c.x +_radius, c.y + _radius);
- CGPathAddLineToPoint(path, NULL, c.x - _radius, c.y + _radius);
- CGPathAddLineToPoint(path, NULL, c.x - _radius, c.y);
- CGPathAddLineToPoint(path, NULL, c.x, c.y);
- /*
-
- //draw a rectangle like spotlight --- i'll get to this later
- CGPathMoveToPoint(path, NULL, c.x-radius, c.y-radius);
- CGPathAddLineToPoint(path, NULL, c.x, c.y-radius);
- CGPathAddArcToPoint(path, NULL, c.x+radius, c.y-radius, c.x+radius, c.y, radius);
- CGPathAddArcToPoint(path, NULL, c.x+radius, c.y +radius, c.x , c.y+radius, radius);
- CGPathAddArcToPoint(path, NULL, c.x -radius, c.y + radius, c.x-radius, c.y, radius);
- CGPathAddArcToPoint(path, NULL, c.x-radius, c.y - radius, c.x, c.y-radius, radius);
- CGContextAddPath(context, path);
- CGContextClip(context);
-
- //fill with gradient
- CGContextDrawRadialGradient(context, gradientRef, c, 0.0f, c, _radius*2, 0);
-
-
- */
-
-
- CGContextAddPath(context, path);
- CGPathRelease(path);
- CGContextClip(context);
+ // draw spotlights
+ int spotlightCount = _positionArray.count;
+ for (int i=0; i<spotlightCount; ++i)
+ {
+ // center and radius of spotlight
+ CGPoint c = [[_positionArray objectAtIndex:i] CGPointValue];
+ CGFloat radius = [[_radiusArray objectAtIndex:i] floatValue];
+
+ //draw the shape
+ CGMutablePathRef path = CGPathCreateMutable();
+ //
+ //draw a rect around view
+ CGPathAddRect(path, NULL, CGRectMake(c.x - radius, c.y -radius,100,100));
+ CGPathAddLineToPoint(path, NULL, c.x + radius, c.y - radius);
+ CGPathAddLineToPoint(path, NULL, c.x + radius, c.y + radius);
+ CGPathAddLineToPoint(path, NULL, c.x - radius, c.y + radius);
+ CGPathAddLineToPoint(path, NULL, c.x - radius, c.y);
+ CGPathAddLineToPoint(path, NULL, c.x, c.y);
+ /*
+
+ //draw a rectangle like spotlight --- i'll get to this later
+ CGPathMoveToPoint(path, NULL, c.x-radius, c.y-radius);
+ CGPathAddLineToPoint(path, NULL, c.x, c.y-radius);
+ CGPathAddArcToPoint(path, NULL, c.x+radius, c.y-radius, c.x+radius, c.y, radius);
+ CGPathAddArcToPoint(path, NULL, c.x+radius, c.y +radius, c.x , c.y+radius, radius);
+ CGPathAddArcToPoint(path, NULL, c.x -radius, c.y + radius, c.x-radius, c.y, radius);
+ CGPathAddArcToPoint(path, NULL, c.x-radius, c.y - radius, c.x, c.y-radius, radius);
+ CGContextAddPath(context, path);
+ CGContextClip(context);
+
+ //fill with gradient
+ CGContextDrawRadialGradient(context, gradientRef, c, 0.0f, c, _radius*2, 0);
+
+
+ */
+ CGContextSaveGState(context);
+
+ CGContextAddPath(context, path);
+ CGPathRelease(path);
+ CGContextClip(context);
+
+ //add gradient
+ //create the gradient Ref
+ CGGradientRef gradientRef = CGGradientCreateWithColorComponents(colorspace, components, colorLocations, 2);
+ CGContextDrawRadialGradient(context, gradientRef, c, 0.0f, c, radius*2, 0);
+ CGGradientRelease(gradientRef);
+
+ CGContextRestoreGState(context);
+ }
- //add gradient
- CGContextDrawRadialGradient(context, gradientRef, c, 0.0f, c, _radius*2, 0);
- CGGradientRelease(gradientRef);
+ CGColorSpaceRelease(colorspace);
CGContextRestoreGState(context);
//convert drawing to image for masking
@@ -19,9 +19,9 @@ @implementation EMViewController
#pragma mark ---------------------------------->>
#pragma mark -------------->>hint deleage
--(UIView*)hintStateViewToHint:(id)hintState
+-(NSArray*)hintStateViewsToHint:(id)hintState
{
- return _info;
+ return [[NSArray alloc] initWithObjects:_info, nil];
}
-(UIView*)hintStateViewForDialog:(id)hintState
{
@@ -24,6 +24,7 @@ typedef enum
EMHintDialogTypeButton,
EMHintDialogTypeList,
EMHintDialogTypeBack,
+ EMHintDialogTypeListAndBack,
EMHintDialogTypeCount
}EMHintDialogType;
@@ -30,6 +30,9 @@ -(void)doNext
case EMHintDialogTypeList:
[modalState presentModalMessage:@"This is a list button! \r\nProtocol: returned rect" where:_vc.navigationController.view];
break;
+ case EMHintDialogTypeListAndBack:
+ [modalState presentModalMessage:@"Multiple spotlights: list and back button \r\nProtocol: returned rect" where:_vc.navigationController.view];
+ break;
default:
[modalState presentModalMessage:@"" where:_vc.navigationController.view];
break;
@@ -62,31 +65,46 @@ -(void)hintStateDidClose:(id)hintState
--(CGRect)hintStateRectToHint:(id)hintState
+-(NSArray*)hintStateRectsToHint:(id)hintState
{
CGFloat ht = 50.0;
CGFloat statusBarHt = 20.0;
- CGRect rect;
+ NSArray* rectArray = nil;
switch (_curType) {
case EMHintDialogTypeInfo:
- rect = CGRectMake(_vc.view.frame.size.width/2 ,
- _vc.view.frame.size.height/2 + (statusBarHt + 44),
- ht,ht);
+ {
+ CGRect rect = CGRectMake(_vc.view.frame.size.width/2 ,
+ _vc.view.frame.size.height/2 + (statusBarHt + 44),
+ ht,ht);
+ rectArray = [[NSArray alloc] initWithObjects:[NSValue valueWithCGRect:rect], nil];
+ }
break;
case EMHintDialogTypeList:
- rect = CGRectMake(290, ht/2 + statusBarHt,ht,ht);
+ {
+ CGRect rect = CGRectMake(290, ht/2 + statusBarHt,ht,ht);
+ rectArray = [[NSArray alloc] initWithObjects:[NSValue valueWithCGRect:rect], nil];
+ }
break;
case EMHintDialogTypeBack:
- rect= CGRectMake(25, ht/2 + statusBarHt,ht,ht);
+ {
+ CGRect rect= CGRectMake(25, ht/2 + statusBarHt,ht,ht);
+ rectArray = [[NSArray alloc] initWithObjects:[NSValue valueWithCGRect:rect], nil];
+ }
+ break;
+ case EMHintDialogTypeListAndBack:
+ {
+ CGRect backRect = CGRectMake(25, ht/2 + statusBarHt,ht,ht);
+ CGRect listRect = CGRectMake(290, ht/2 + statusBarHt,ht,ht);
+ rectArray = [[NSArray alloc] initWithObjects:[NSValue valueWithCGRect:backRect], [NSValue valueWithCGRect:listRect], nil];
+ }
break;
+
case EMHintDialogTypeButton:
- rect = CGRectMake(0, 0, 1, 1);
break;
default:
- rect = CGRectMake(0, 0, 1, 1);
break;
}
- return rect;
+ return rectArray;
}
View
@@ -2,7 +2,7 @@
## Overview
-**EMHint** is an iOS class group that easily adds a spotlight-like effect to a view highlighting or hinting at something that may be important on the screen.The protocols of EMHintDelegate allow users to override many of the default actions and views. Tapping the black overlay fades it away.
+**EMHint** is an iOS class group that easily adds multiple spotlight-like effects to a view highlighting or hinting at some things that may be important on the screen.The protocols of EMHintDelegate allow users to override many of the default actions and views. Tapping the black overlay fades it away.
Great for quick "how to" or tutorials in your app.

0 comments on commit cd55d33

Please sign in to comment.