Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #3 from luugiathuy/master

Multiple slotlights support
  • Loading branch information...
commit cd55d33cda430771dd64b547669bbaafe9524cba 2 parents b15b0aa + a81fc3c
@mcconkiee authored
View
10 HintMakerExample/EMHint.h
@@ -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
22 HintMakerExample/EMHint.m
@@ -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];
View
12 HintMakerExample/EMHintsView.h
@@ -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
View
145 HintMakerExample/EMHintsView.m
@@ -20,27 +20,57 @@
@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;
@@ -48,18 +78,17 @@ - (id)initWithFrame:(CGRect)frame forView:(UIView*)onView
-(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
View
4 HintMakerExample/EMViewController.m
@@ -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
{
View
1  HintMakerExample/HintHelper.h
@@ -24,6 +24,7 @@ typedef enum
EMHintDialogTypeButton,
EMHintDialogTypeList,
EMHintDialogTypeBack,
+ EMHintDialogTypeListAndBack,
EMHintDialogTypeCount
}EMHintDialogType;
View
38 HintMakerExample/HintHelper.m
@@ -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  README.md
@@ -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.
Please sign in to comment.
Something went wrong with that request. Please try again.