Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ build/

*.pbxuser
*.perspectivev3
.DS_Store
2 changes: 2 additions & 0 deletions Classes/FavStarControlAppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ - (void)applicationDidFinishLaunching:(UIApplication *)application {


- (void)dealloc {
#if !__has_feature(objc_arc)
[viewController release];
[window release];
[super dealloc];
#endif
}


Expand Down
15 changes: 12 additions & 3 deletions Classes/FavStarControlViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,19 @@ - (void)viewDidLoad
[super viewDidLoad];

UIImage *dot, *star;
dot = [UIImage imageNamed:@"dot.png"];
star = [UIImage imageNamed:@"star.png"];
JSFavStarControl *rating = [[JSFavStarControl alloc] initWithLocation:CGPointMake(110, 220) dotImage:dot starImage:star];
dot = [UIImage imageNamed:@"dot10x10.png"];
star = [UIImage imageNamed:@"star10x10.png"];
JSFavStarControl *rating = [[JSFavStarControl alloc] initWithImages:CGRectMake(110, 220, 100, 20)
dotImage:dot
starImage:star];
rating.rating = 1;

[rating addTarget:self action:@selector(updateRating:) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:rating];

#if !__has_feature(objc_arc)
[rating release];
#endif
}

- (void)updateRating:(id)sender
Expand Down Expand Up @@ -61,7 +68,9 @@ - (void)viewDidUnload {


- (void)dealloc {
#if !__has_feature(objc_arc)
[super dealloc];
#endif
}

@end
24 changes: 21 additions & 3 deletions Classes/JSFavStarControl.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,37 @@

#import <UIKit/UIKit.h>

#ifndef JF_STRONG
#if __has_feature(objc_arc)
#define JF_STRONG strong
#else
#define JF_STRONG retain
#endif
#endif

#ifndef JF_WEAK
#if __has_feature(objc_arc_weak)
#define JF_WEAK weak
#elif __has_feature(objc_arc)
#define JF_WEAK unsafe_unretained
#else
#define JF_WEAK assign
#endif
#endif

@interface JSFavStarControl : UIControl {

NSInteger _rating;

CGFloat _fontSize ;
UIImage *_dot, *_star;
}

@property (nonatomic, readonly) NSInteger rating;
@property (nonatomic,assign) CGFloat padding;
@property (nonatomic,assign) NSInteger rating;

// dotImage and starImage can both be nil, or not even a dot or a star (a any images you want!)
// If either of these parameters are nil, the class will draw its own dot/star
// Use location to position the favstar control in your view - the control will manage its own width/height (kind of like UIActivityIndicator)
- (id)initWithLocation:(CGPoint)location dotImage:(UIImage *)dotImage starImage:(UIImage *)starImage;
- (id)initWithImages:(CGRect)frame dotImage:(UIImage *)dotImage starImage:(UIImage *)starImage;

@end
138 changes: 108 additions & 30 deletions Classes/JSFavStarControl.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,83 @@

#define RATING_MAX 5

@interface JSFavStarControl ()

-(BOOL)isFirstStarTouched:(CGPoint)touchLocation section:(CGRect)section;

@end

@implementation JSFavStarControl

@synthesize rating = _rating;
@synthesize padding;

-(BOOL)isFirstStarTouched:(CGPoint)touchLocation section:(CGRect)section
{
CGFloat w = (_star!=nil ) ? _star.size.width : _fontSize;

return (touchLocation.x >0 && touchLocation.x < section.origin.x + w );
}

- (void)initialize
{
_rating = 0;
_fontSize = self.frame.size.height -2 ;
self.padding = 15.0;
//self.backgroundColor = [UIColor clearColor];
self.opaque = NO;


}

- (void)setRating:(NSInteger)rating
{
if( rating != _rating ) {
_rating = rating;

[self setNeedsDisplay];
}
}

#pragma mark - initialization

-(id)initWithCoder:(NSCoder *)aDecoder
{
if( self = [super initWithCoder:aDecoder] ) {

[self initialize];
}

return self;

}

- (id)initWithFrame:(CGRect)frame
{
if( self = [super initWithFrame:frame] ) {

[self initialize];
}

return self;
}

- (id)initWithLocation:(CGPoint)location dotImage:(UIImage *)dotImage starImage:(UIImage *)starImage
- (id)initWithImages:(CGRect)frame dotImage:(UIImage *)dotImage starImage:(UIImage *)starImage
{
if (self = [self initWithFrame:CGRectMake(location.x, location.y, 100, 20)])
NSParameterAssert(dotImage);
NSParameterAssert(starImage);


if (self = [super initWithFrame:frame])
{
_rating = 0;
self.backgroundColor = [UIColor clearColor];
self.opaque = NO;

[self initialize];
#if __has_feature(objc_arc)
_dot = dotImage;
_star = starImage;
#else
_dot = [dotImage retain];
_star = [starImage retain];
#endif
}

return self;
Expand All @@ -39,9 +102,9 @@ - (void)drawRect:(CGRect)rect
if (_star)
[_star drawAtPoint:currPoint];
else
[@"★" drawAtPoint:currPoint withFont:[UIFont boldSystemFontOfSize:22]];
[@"★" drawAtPoint:currPoint withFont:[UIFont boldSystemFontOfSize:_fontSize]];

currPoint.x += 20;
currPoint.x += self.padding;
}

NSInteger remaining = RATING_MAX - _rating;
Expand All @@ -51,21 +114,25 @@ - (void)drawRect:(CGRect)rect
if (_dot)
[_dot drawAtPoint:currPoint];
else
[@" •" drawAtPoint:currPoint withFont:[UIFont boldSystemFontOfSize:22]];
currPoint.x += 20;
[@" •" drawAtPoint:currPoint withFont:[UIFont boldSystemFontOfSize:_fontSize]];
currPoint.x += self.padding;
}
}


- (void)dealloc
{
[_dot release];
#if !__has_feature(objc_arc)
[_dot release];
[_star release];

#endif

_dot = nil,
_star = nil;

#if !__has_feature(objc_arc)
[super dealloc];
#endif
}


Expand All @@ -76,22 +143,29 @@ - (BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event

CGPoint touchLocation = [touch locationInView:self];

for (int i = 0; i < RATING_MAX; i++)
{
if (touchLocation.x > section.origin.x && touchLocation.x < section.origin.x + section.size.width)
{ // touch is inside section
if (_rating != (i+1))
{
_rating = i+1;
[self sendActionsForControlEvents:UIControlEventValueChanged];
}

break;
}

section.origin.x += section.size.width;
if( _rating == 1 && [self isFirstStarTouched:touchLocation section:section]) {

_rating = 0;
[self sendActionsForControlEvents:UIControlEventValueChanged];

}
else {
for (int i = 0; i < RATING_MAX; i++)
{
if (touchLocation.x > section.origin.x && touchLocation.x < section.origin.x + section.size.width)
{ // touch is inside section
if (_rating != (i+1))
{
_rating = i+1;
[self sendActionsForControlEvents:UIControlEventValueChanged];
}

break;
}

section.origin.x += section.size.width;
}
}

[self setNeedsDisplay];
return YES;
}
Expand Down Expand Up @@ -148,7 +222,11 @@ - (void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event

CGPoint touchLocation = [touch locationInView:self];

if (touchLocation.x < 0)
NSLog(@"endTrackingWithTouch touchLocation.x=[%f]", touchLocation.x);

if( _rating == 0 && [self isFirstStarTouched:touchLocation section:section] ) return;

if (touchLocation.x <= 0 )
{
if (_rating != 0)
{
Expand All @@ -158,9 +236,9 @@ - (void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
}
else if (touchLocation.x > width)
{
if (_rating != 5)
if (_rating != RATING_MAX)
{
_rating = 5;
_rating = RATING_MAX;
[self sendActionsForControlEvents:UIControlEventValueChanged];
}

Expand Down
34 changes: 26 additions & 8 deletions FavStarControl.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@
28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; };
28D7ACF80DDB3853001CB0EB /* FavStarControlViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28D7ACF70DDB3853001CB0EB /* FavStarControlViewController.m */; };
758D370E112C04F6003C8E62 /* JSFavStarControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 758D370D112C04F6003C8E62 /* JSFavStarControl.m */; };
758D3711112C0881003C8E62 /* dot.png in Resources */ = {isa = PBXBuildFile; fileRef = 758D370F112C0881003C8E62 /* dot.png */; };
758D3712112C0881003C8E62 /* star.png in Resources */ = {isa = PBXBuildFile; fileRef = 758D3710112C0881003C8E62 /* star.png */; };
A033B47E15A6D6DD003FEE36 /* JSFavStarControl.podspec in Resources */ = {isa = PBXBuildFile; fileRef = A033B47D15A6D6DD003FEE36 /* JSFavStarControl.podspec */; };
A09CDEBE15A5FDD000452597 /* dot20x20.png in Resources */ = {isa = PBXBuildFile; fileRef = A09CDEBA15A5FDD000452597 /* dot20x20.png */; };
A09CDEBF15A5FDD000452597 /* star20x20.png in Resources */ = {isa = PBXBuildFile; fileRef = A09CDEBB15A5FDD000452597 /* star20x20.png */; };
A09CDEC015A5FDD000452597 /* dot10x10.png in Resources */ = {isa = PBXBuildFile; fileRef = A09CDEBC15A5FDD000452597 /* dot10x10.png */; };
A09CDEC115A5FDD000452597 /* star10x10.png in Resources */ = {isa = PBXBuildFile; fileRef = A09CDEBD15A5FDD000452597 /* star10x10.png */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
Expand All @@ -35,9 +38,12 @@
32CA4F630368D1EE00C91783 /* FavStarControl_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FavStarControl_Prefix.pch; sourceTree = "<group>"; };
758D370C112C04F6003C8E62 /* JSFavStarControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSFavStarControl.h; sourceTree = "<group>"; };
758D370D112C04F6003C8E62 /* JSFavStarControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JSFavStarControl.m; sourceTree = "<group>"; };
758D370F112C0881003C8E62 /* dot.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = dot.png; sourceTree = "<group>"; };
758D3710112C0881003C8E62 /* star.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = star.png; sourceTree = "<group>"; };
8D1107310486CEB800E47090 /* FavStarControl-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "FavStarControl-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = "<group>"; };
A033B47D15A6D6DD003FEE36 /* JSFavStarControl.podspec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = JSFavStarControl.podspec; sourceTree = "<group>"; };
A09CDEBA15A5FDD000452597 /* dot20x20.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = dot20x20.png; sourceTree = "<group>"; };
A09CDEBB15A5FDD000452597 /* star20x20.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = star20x20.png; sourceTree = "<group>"; };
A09CDEBC15A5FDD000452597 /* dot10x10.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = dot10x10.png; sourceTree = "<group>"; };
A09CDEBD15A5FDD000452597 /* star10x10.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = star10x10.png; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -78,6 +84,7 @@
29B97314FDCFA39411CA2CEA /* CustomTemplate */ = {
isa = PBXGroup;
children = (
A033B47D15A6D6DD003FEE36 /* JSFavStarControl.podspec */,
080E96DDFE201D6D7F000001 /* Classes */,
29B97315FDCFA39411CA2CEA /* Other Sources */,
29B97317FDCFA39411CA2CEA /* Resources */,
Expand All @@ -99,8 +106,10 @@
29B97317FDCFA39411CA2CEA /* Resources */ = {
isa = PBXGroup;
children = (
758D370F112C0881003C8E62 /* dot.png */,
758D3710112C0881003C8E62 /* star.png */,
A09CDEBA15A5FDD000452597 /* dot20x20.png */,
A09CDEBB15A5FDD000452597 /* star20x20.png */,
A09CDEBC15A5FDD000452597 /* dot10x10.png */,
A09CDEBD15A5FDD000452597 /* star10x10.png */,
2899E5210DE3E06400AC0155 /* FavStarControlViewController.xib */,
28AD733E0D9D9553002E5188 /* MainWindow.xib */,
8D1107310486CEB800E47090 /* FavStarControl-Info.plist */,
Expand Down Expand Up @@ -169,8 +178,11 @@
files = (
28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */,
2899E5220DE3E06400AC0155 /* FavStarControlViewController.xib in Resources */,
758D3711112C0881003C8E62 /* dot.png in Resources */,
758D3712112C0881003C8E62 /* star.png in Resources */,
A09CDEBE15A5FDD000452597 /* dot20x20.png in Resources */,
A09CDEBF15A5FDD000452597 /* star20x20.png in Resources */,
A09CDEC015A5FDD000452597 /* dot10x10.png in Resources */,
A09CDEC115A5FDD000452597 /* star10x10.png in Resources */,
A033B47E15A6D6DD003FEE36 /* JSFavStarControl.podspec in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -202,6 +214,7 @@
GCC_PREFIX_HEADER = FavStarControl_Prefix.pch;
INFOPLIST_FILE = "FavStarControl-Info.plist";
PRODUCT_NAME = FavStarControl;
SDKROOT = iphoneos5.1;
};
name = Debug;
};
Expand All @@ -214,13 +227,16 @@
GCC_PREFIX_HEADER = FavStarControl_Prefix.pch;
INFOPLIST_FILE = "FavStarControl-Info.plist";
PRODUCT_NAME = FavStarControl;
SDKROOT = iphoneos5.1;
};
name = Release;
};
C01FCF4F08A954540054247B /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_OBJCPP_ARC_ABI = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
GCC_C_LANGUAGE_STANDARD = c99;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
Expand All @@ -234,6 +250,8 @@
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_OBJCPP_ARC_ABI = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
GCC_C_LANGUAGE_STANDARD = c99;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file not shown.
Loading