diff --git a/README.md b/README.md new file mode 100644 index 0000000..830c79f --- /dev/null +++ b/README.md @@ -0,0 +1,77 @@ +# XHStarRateView +iOS自定义星级评论视图 ⭐️⭐️⭐️⭐️⭐️ + +## Demo + +![](https://ws2.sinaimg.cn/large/006tKfTcly1fmxkuml0brg30af0ij0y0.gif) + +## 功能特性 +* 支持设置任意星星数量; +* 支持动画修改评论效果; +* 多种评分样式支持:整星评论、半星评论、不完整星星评论; +* 支持 block 和 delegate 两种方式返回修改结果; +* 支持代码和 Nib 方式创建视图; + + + +## 如何使用 + +1. 下载并拖拽 **XHStarRateView.h** 与 **XHStarRateView.m** 文件到项目。 +2. 导入头文件 `import "XHStarRateView.h"`。 +3. 如果需要,遵守代理协议 **XHStarRateViewDelegate**。 + + + +### 通过代理的方法获取当前评分数 + +```objective-c +XHStarRateView *starRateView = [[XHStarRateView alloc] initWithFrame:CGRectMake(20, 60, 200, 30)]; +starRateView.isAnimation = YES; // 设置是否有动画 +starRateView.rateStyle = XHStarRateViewRateStyeIncompleteStar; // 设置星级评分样式 +starRateView.tag = 1; +starRateView.delegate = self; // 遵守代理协议 +[self.view addSubview:starRateView]; +``` + +你也可以使用封装好的完全初始化方法: + +```objective-c +XHStarRateView *starRateView2 = [[XHStarRateView alloc] initWithFrame:CGRectMake(20, 100, 200, 30) numberOfStar:5 rateStyle:XHStarRateViewRateStyeHalfStar isAnimation:NO delegate:self]; +starRateView2.tag = 2; +[self.view addSubview:starRateView2]; +``` + +实现代理协议: + +```objective-c +-(void)starRateView:(XHStarRateView *)starRateView ratingDidChange:(CGFloat)currentRating { + NSLog(@"%ld---- %f",(long)starRateView.tag,currentRating); +} +``` + + + +### 通过Block传值的方法获取当前评分数 + +```objective-c +XHStarRateView *starRateView3 = [[XHStarRateView alloc] initWithFrame:CGRectMake(20, 140, 200, 30) completion:^(CGFloat currentScore) { + NSLog(@"3---- %f",currentScore); +}]; + +[self.view addSubview:starRateView3]; +``` + +当然,此方式也有一个可用的完全初始化方法: + +```objective-c +XHStarRateView *starRateView4 = [[XHStarRateView alloc] initWithFrame:CGRectMake(20, 180, 200, 30) numberOfStar:8 rateStyle:XHStarRateViewRateStyeHalfStar isAnimation:YES completion:^(CGFloat currentScore) { + NSLog(@"4---- %f",currentScore); +}]; +[self.view addSubview:starRateView4]; +``` + + + + + + diff --git a/XHStarRateView.xcodeproj/project.pbxproj b/XHStarRateView.xcodeproj/project.pbxproj index 4f890db..2fa95d5 100644 --- a/XHStarRateView.xcodeproj/project.pbxproj +++ b/XHStarRateView.xcodeproj/project.pbxproj @@ -173,6 +173,7 @@ TargetAttributes = { 2F20EDC41CAE16D600B650B7 = { CreatedOnToolsVersion = 7.3; + DevelopmentTeam = C33JS9A6R3; }; 2F20EDDD1CAE16D600B650B7 = { CreatedOnToolsVersion = 7.3; @@ -357,10 +358,11 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = C33JS9A6R3; INFOPLIST_FILE = XHStarRateView/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 8.1; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.huahua.XHStarRateView; + PRODUCT_BUNDLE_IDENTIFIER = com.tonintech.XHStarRateView; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; @@ -369,10 +371,11 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + DEVELOPMENT_TEAM = C33JS9A6R3; INFOPLIST_FILE = XHStarRateView/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 8.1; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.huahua.XHStarRateView; + PRODUCT_BUNDLE_IDENTIFIER = com.tonintech.XHStarRateView; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; @@ -420,6 +423,7 @@ 2F20EDE91CAE16D600B650B7 /* Release */, ); defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; 2F20EDEA1CAE16D600B650B7 /* Build configuration list for PBXNativeTarget "XHStarRateViewTests" */ = { isa = XCConfigurationList; @@ -428,6 +432,7 @@ 2F20EDEC1CAE16D600B650B7 /* Release */, ); defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; diff --git a/XHStarRateView.xcodeproj/project.xcworkspace/xcuserdata/huqilin.xcuserdatad/UserInterfaceState.xcuserstate b/XHStarRateView.xcodeproj/project.xcworkspace/xcuserdata/huqilin.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..f6dd494 Binary files /dev/null and b/XHStarRateView.xcodeproj/project.xcworkspace/xcuserdata/huqilin.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/XHStarRateView.xcodeproj/xcuserdata/huqilin.xcuserdatad/xcschemes/xcschememanagement.plist b/XHStarRateView.xcodeproj/xcuserdata/huqilin.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..a299a7c --- /dev/null +++ b/XHStarRateView.xcodeproj/xcuserdata/huqilin.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,14 @@ + + + + + SchemeUserState + + XHStarRateView.xcscheme + + orderHint + 0 + + + + diff --git a/XHStarRateView/Assets.xcassets/AppIcon.appiconset/Contents.json b/XHStarRateView/Assets.xcassets/AppIcon.appiconset/Contents.json index eeea76c..d8db8d6 100644 --- a/XHStarRateView/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/XHStarRateView/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1,5 +1,15 @@ { "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, { "idiom" : "iphone", "size" : "29x29", @@ -30,6 +40,16 @@ "size" : "60x60", "scale" : "3x" }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, { "idiom" : "ipad", "size" : "29x29", @@ -64,6 +84,11 @@ "idiom" : "ipad", "size" : "83.5x83.5", "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" } ], "info" : { diff --git a/XHStarRateView/Base.lproj/LaunchScreen.storyboard b/XHStarRateView/Base.lproj/LaunchScreen.storyboard index 2e721e1..fc810a6 100644 --- a/XHStarRateView/Base.lproj/LaunchScreen.storyboard +++ b/XHStarRateView/Base.lproj/LaunchScreen.storyboard @@ -1,7 +1,12 @@ - - + + + + + - + + + @@ -13,10 +18,9 @@ - + - - + diff --git a/XHStarRateView/Base.lproj/Main.storyboard b/XHStarRateView/Base.lproj/Main.storyboard index f56d2f3..0f36559 100644 --- a/XHStarRateView/Base.lproj/Main.storyboard +++ b/XHStarRateView/Base.lproj/Main.storyboard @@ -1,21 +1,26 @@ - - + + + + + - + + + - + - + - + diff --git a/XHStarRateView/Info.plist b/XHStarRateView/Info.plist index 40c6215..9c0c195 100644 --- a/XHStarRateView/Info.plist +++ b/XHStarRateView/Info.plist @@ -2,6 +2,8 @@ + LSApplicationCategoryType + CFBundleDevelopmentRegion en CFBundleExecutable diff --git a/XHStarRateView/ViewController.m b/XHStarRateView/ViewController.m index b0656ea..586ade3 100644 --- a/XHStarRateView/ViewController.m +++ b/XHStarRateView/ViewController.m @@ -17,31 +17,48 @@ @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; + + /* + 1. Delegate 方式创建 + */ XHStarRateView *starRateView = [[XHStarRateView alloc] initWithFrame:CGRectMake(20, 60, 200, 30)]; - starRateView.isAnimation = YES; - starRateView.rateStyle = IncompleteStar; + starRateView.isAnimation = YES; // 有动画 + starRateView.rateStyle = XHStarRateViewRateStyeIncompleteStar; //允许不完整星评论 starRateView.tag = 1; starRateView.delegate = self; [self.view addSubview:starRateView]; - XHStarRateView *starRateView2 = [[XHStarRateView alloc] initWithFrame:CGRectMake(20, 100, 200, 30) numberOfStars:5 rateStyle:HalfStar isAnination:YES delegate:self]; + /* + 2. 初始化方法创建 + 半星评论、无动画 + */ + XHStarRateView *starRateView2 = [[XHStarRateView alloc] initWithFrame:CGRectMake(20, 100, 200, 30) numberOfStar:5 rateStyle:XHStarRateViewRateStyeHalfStar isAnimation:NO delegate:self]; starRateView2.tag = 2; [self.view addSubview:starRateView2]; - XHStarRateView *starRateView3 = [[XHStarRateView alloc] initWithFrame:CGRectMake(20, 140, 200, 30) finish:^(CGFloat currentScore) { + /* + 3. block 方法1 + 默认设置:完整星评论、 + */ + XHStarRateView *starRateView3 = [[XHStarRateView alloc] initWithFrame:CGRectMake(20, 140, 200, 30) completion:^(CGFloat currentScore) { NSLog(@"3---- %f",currentScore); }]; + [self.view addSubview:starRateView3]; - XHStarRateView *starRateView4 = [[XHStarRateView alloc] initWithFrame:CGRectMake(20, 180, 200, 30) numberOfStars:5 rateStyle:HalfStar isAnination:YES finish:^(CGFloat currentScore) { + /* + 4. block 方法2 + 半星评论、有动画 + */ + XHStarRateView *starRateView4 = [[XHStarRateView alloc] initWithFrame:CGRectMake(20, 180, 200, 30) numberOfStar:8 rateStyle:XHStarRateViewRateStyeHalfStar isAnimation:YES completion:^(CGFloat currentScore) { NSLog(@"4---- %f",currentScore); }]; [self.view addSubview:starRateView4]; } --(void)starRateView:(XHStarRateView *)starRateView currentScore:(CGFloat)currentScore{ - NSLog(@"%ld---- %f",starRateView.tag,currentScore); +-(void)starRateView:(XHStarRateView *)starRateView ratingDidChange:(CGFloat)currentRating { + NSLog(@"%ld---- %f",(long)starRateView.tag,currentRating); } @end diff --git a/XHStarRateView/XHStarRateView/XHStarRateView.h b/XHStarRateView/XHStarRateView/XHStarRateView.h index a264f6f..2d80460 100644 --- a/XHStarRateView/XHStarRateView/XHStarRateView.h +++ b/XHStarRateView/XHStarRateView/XHStarRateView.h @@ -9,33 +9,61 @@ #import @class XHStarRateView; -typedef void(^finishBlock)(CGFloat currentScore); +/** + 点击评分的 block 回调 -typedef NS_ENUM(NSInteger, RateStyle) -{ - WholeStar = 0, //只能整星评论 - HalfStar = 1, //允许半星评论 - IncompleteStar = 2 //允许不完整星评论 -}; + @param currentScore 当前评论分数,CGFloat 类型 + */ +typedef void(^XHStarRateViewRateCompletionBlock)(CGFloat currentScore); -@protocol XHStarRateViewDelegate +/** + 星级评分样式 --(void)starRateView:(XHStarRateView *)starRateView currentScore:(CGFloat)currentScore; + - XHStarRateViewRateStyeFullStar: 整星评论,默认样式。 + - XHStarRateViewRateStyeHalfStar: 允许半星评论。 + - XHStarRateViewRateStyeIncompleteStar: 允许不完整星评论。 + */ +typedef NS_ENUM(NSUInteger, XHStarRateViewRateStye) { + XHStarRateViewRateStyeFullStar, + XHStarRateViewRateStyeHalfStar, + XHStarRateViewRateStyeIncompleteStar, +}; +/** + 点击评分的代理方法 + */ +@protocol XHStarRateViewDelegate +-(void)starRateView:(XHStarRateView *)starRateView ratingDidChange:(CGFloat)currentRating; @end @interface XHStarRateView : UIView -@property (nonatomic,assign)BOOL isAnimation; //是否动画显示,默认NO -@property (nonatomic,assign)RateStyle rateStyle; //评分样式 默认是WholeStar -@property (nonatomic, weak) iddelegate; +@property (nonatomic, assign) BOOL isAnimation; // 是否动画显示,默认 NO +@property (nonatomic, assign) XHStarRateViewRateStye rateStyle; // 星级评分样式 +@property (nonatomic, assign) CGFloat currentRating; // 当前评分,默认为 0 +@property (nonatomic, weak) id delegate; +/** + *通过代理的方法获取当前评分数 + */ +- (instancetype)initWithFrame:(CGRect)frame; --(instancetype)initWithFrame:(CGRect)frame; --(instancetype)initWithFrame:(CGRect)frame numberOfStars:(NSInteger)numberOfStars rateStyle:(RateStyle)rateStyle isAnination:(BOOL)isAnimation delegate:(id)delegate; +- (instancetype)initWithFrame:(CGRect)frame + numberOfStar:(NSInteger)numberOfStar + rateStyle:(XHStarRateViewRateStye)rateStyle + isAnimation:(BOOL)isAnimation + delegate:(id)delegate; +/** + *通过Block传值的方法获取当前评分数 + */ +- (instancetype)initWithFrame:(CGRect)frame + completion:(XHStarRateViewRateCompletionBlock)completionBlock; --(instancetype)initWithFrame:(CGRect)frame finish:(finishBlock)finish; --(instancetype)initWithFrame:(CGRect)frame numberOfStars:(NSInteger)numberOfStars rateStyle:(RateStyle)rateStyle isAnination:(BOOL)isAnimation finish:(finishBlock)finish; +- (instancetype)initWithFrame:(CGRect)frame + numberOfStar:(NSInteger)numberOfStar + rateStyle:(XHStarRateViewRateStye)rateStyle + isAnimation:(BOOL)isAnimation + completion:(XHStarRateViewRateCompletionBlock)completionBlock; @end diff --git a/XHStarRateView/XHStarRateView/XHStarRateView.m b/XHStarRateView/XHStarRateView/XHStarRateView.m index 8cf5ae0..ed9c890 100644 --- a/XHStarRateView/XHStarRateView/XHStarRateView.m +++ b/XHStarRateView/XHStarRateView/XHStarRateView.m @@ -8,155 +8,205 @@ #import "XHStarRateView.h" -#define ForegroundStarImage @"b27_icon_star_yellow" -#define BackgroundStarImage @"b27_icon_star_gray" - -typedef void(^completeBlock)(CGFloat currentScore); +static NSString *const KForegroundStarImage = @"b27_icon_star_yellow"; +static NSString *const KBackgroundStarImage = @"b27_icon_star_gray"; +static const NSUInteger KDefaultNumberOfStar = 5; @interface XHStarRateView() -@property (nonatomic, strong) UIView *foregroundStarView; -@property (nonatomic, strong) UIView *backgroundStarView; - -@property (nonatomic, assign) NSInteger numberOfStars; -@property (nonatomic,assign)CGFloat currentScore; // 当前评分:0-5 默认0 - -@property (nonatomic,strong)completeBlock complete; +@property (nonatomic, strong, readwrite) UIView *foregroundStarView; +@property (nonatomic, strong, readwrite) UIView *backgroundStarView; +@property (nonatomic, assign, readwrite) NSUInteger numberOfStar; // 星星数量 +@property (nonatomic, copy) XHStarRateViewRateCompletionBlock completionBlock; @end @implementation XHStarRateView -#pragma mark - 代理方式 --(instancetype)initWithFrame:(CGRect)frame{ +#pragma mark - Init Method + +// 指定初始化方法 +- (instancetype)initWithFrame:(CGRect)frame + numberOfStar:(NSInteger)numberOfStar + rateStyle:(XHStarRateViewRateStye)rateStyle + isAnimation:(BOOL)isAnimation + completion:(XHStarRateViewRateCompletionBlock)completionBlock + delegate:(id)delegate +{ if (self = [super initWithFrame:frame]) { - _numberOfStars = 5; - _rateStyle = WholeStar; + _numberOfStar = numberOfStar; + _rateStyle = rateStyle; + _isAnimation = isAnimation; + _completionBlock = completionBlock; + _delegate = delegate; [self createStarView]; } return self; } --(instancetype)initWithFrame:(CGRect)frame numberOfStars:(NSInteger)numberOfStars rateStyle:(RateStyle)rateStyle isAnination:(BOOL)isAnimation delegate:(id)delegate{ - if (self = [super initWithFrame:frame]) { - _numberOfStars = numberOfStars; - _rateStyle = rateStyle; - _isAnimation = isAnimation; - _delegate = delegate; +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + if (self = [super initWithCoder:aDecoder]) { + if (_numberOfStar == 0) { + _numberOfStar = KDefaultNumberOfStar; + } [self createStarView]; } return self; } -#pragma mark - block方式 --(instancetype)initWithFrame:(CGRect)frame finish:(finishBlock)finish{ - if (self = [super initWithFrame:frame]) { - _numberOfStars = 5; - _rateStyle = WholeStar; - _complete = ^(CGFloat currentScore){ - finish(currentScore); - }; - [self createStarView]; - } - return self; +#pragma mark 代理方式 + +- (instancetype)initWithFrame:(CGRect)frame { + return [self initWithFrame:frame + numberOfStar:KDefaultNumberOfStar + rateStyle:XHStarRateViewRateStyeFullStar + isAnimation:NO + completion:nil + delegate:nil]; } --(instancetype)initWithFrame:(CGRect)frame numberOfStars:(NSInteger)numberOfStars rateStyle:(RateStyle)rateStyle isAnination:(BOOL)isAnimation finish:(finishBlock)finish{ - if (self = [super initWithFrame:frame]) { - _numberOfStars = numberOfStars; - _rateStyle = rateStyle; - _isAnimation = isAnimation; - _complete = ^(CGFloat currentScore){ - finish(currentScore); - }; - [self createStarView]; - } - return self; +- (instancetype)initWithFrame:(CGRect)frame + numberOfStar:(NSInteger)numberOfStar + rateStyle:(XHStarRateViewRateStye)rateStyle + isAnimation:(BOOL)isAnimation + delegate:(id)delegate +{ + return [self initWithFrame:frame + numberOfStar:numberOfStar + rateStyle:rateStyle + isAnimation:isAnimation + completion:nil + delegate:delegate]; +} + +#pragma mark block方式 + +- (instancetype)initWithFrame:(CGRect)frame + completion:(XHStarRateViewRateCompletionBlock)completionBlock +{ + return [self initWithFrame:frame + numberOfStar:KDefaultNumberOfStar + rateStyle:XHStarRateViewRateStyeFullStar + isAnimation:NO + completion:completionBlock + delegate:nil]; +} + +- (instancetype)initWithFrame:(CGRect)frame + numberOfStar:(NSInteger)numberOfStar + rateStyle:(XHStarRateViewRateStye)rateStyle + isAnimation:(BOOL)isAnimation + completion:(XHStarRateViewRateCompletionBlock)completionBlock +{ + return [self initWithFrame:frame + numberOfStar:numberOfStar + rateStyle:rateStyle + isAnimation:isAnimation + completion:completionBlock + delegate:nil]; +} + +- (void)dealloc { + self.delegate = nil; + self.completionBlock = nil; +} + +#pragma mark - Override + +- (void)layoutSubviews { + [super layoutSubviews]; + + CGFloat animationDuration = (self.isAnimation ? 0.2 : 0); + [UIView animateWithDuration:animationDuration animations:^{ + self.foregroundStarView.frame = CGRectMake(0, 0, self.bounds.size.width / self.numberOfStar * self.currentRating, self.bounds.size.height); + }]; } -#pragma mark - private Method --(void)createStarView{ +#pragma mark - Custom Accessors + +- (void)setCurrentRating:(CGFloat)currentRating { + if (_currentRating == currentRating) { + return; + } + if (currentRating < 0) { + _currentRating = 0; + } else if (currentRating > _numberOfStar) { + _currentRating = _numberOfStar; + } else { + _currentRating = currentRating; + } + + if ([self.delegate respondsToSelector:@selector(starRateView:ratingDidChange:)]) { + [self.delegate starRateView:self ratingDidChange:_currentRating]; + } - self.foregroundStarView = [self createStarViewWithImage:ForegroundStarImage]; - self.backgroundStarView = [self createStarViewWithImage:BackgroundStarImage]; - self.foregroundStarView.frame = CGRectMake(0, 0, self.bounds.size.width*_currentScore/self.numberOfStars, self.bounds.size.height); + if (self.completionBlock) { + _completionBlock(_currentRating); + } + [self setNeedsLayout]; +} + +#pragma mark - Private Method + +- (void)createStarView { + self.foregroundStarView = [self createStarViewWithImageNamed:KForegroundStarImage]; + self.backgroundStarView = [self createStarViewWithImageNamed:KBackgroundStarImage]; + NSAssert(_numberOfStar != 0, @"The Value Of Rate Star should not be Zero"); + self.foregroundStarView.frame = CGRectMake(0, 0, self.bounds.size.width * _currentRating / _numberOfStar, self.bounds.size.height); [self addSubview:self.backgroundStarView]; [self addSubview:self.foregroundStarView]; - + UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(userTapRateView:)]; tapGesture.numberOfTapsRequired = 1; [self addGestureRecognizer:tapGesture]; - } -- (UIView *)createStarViewWithImage:(NSString *)imageName { +- (UIView *)createStarViewWithImageNamed:(NSString *)name { UIView *view = [[UIView alloc] initWithFrame:self.bounds]; view.clipsToBounds = YES; view.backgroundColor = [UIColor clearColor]; - for (NSInteger i = 0; i < self.numberOfStars; i ++) - { - UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:imageName]]; - imageView.frame = CGRectMake(i * self.bounds.size.width / self.numberOfStars, 0, self.bounds.size.width / self.numberOfStars, self.bounds.size.height); - imageView.contentMode = UIViewContentModeScaleAspectFit; - [view addSubview:imageView]; + + NSAssert(_numberOfStar != 0, @"The Value Of Rate Star should not be Zero"); + + @autoreleasepool { + for (NSInteger i = 0; i < _numberOfStar; i ++) { + @autoreleasepool { + UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:name]]; + float starWidth = self.bounds.size.width / _numberOfStar; + float starHeigh = self.bounds.size.height; +// float suitableWidth = MIN(starWidth, starHeigh); + imageView.frame = CGRectMake(i * starWidth, 0, starWidth, starHeigh); + imageView.contentMode = UIViewContentModeScaleAspectFit; + [view addSubview:imageView]; + } + } } + return view; } - (void)userTapRateView:(UITapGestureRecognizer *)gesture { + CGPoint tapPoint = [gesture locationInView:self]; CGFloat offset = tapPoint.x; - CGFloat realStarScore = offset / (self.bounds.size.width / self.numberOfStars); + CGFloat realRating = offset / (self.bounds.size.width / _numberOfStar); + switch (_rateStyle) { - case WholeStar: - { - self.currentScore = ceilf(realStarScore); + case XHStarRateViewRateStyeFullStar: { + self.currentRating = ceilf(realRating); break; } - case HalfStar: - self.currentScore = roundf(realStarScore)>realStarScore ? ceilf(realStarScore):(ceilf(realStarScore)-0.5); - break; - case IncompleteStar: - self.currentScore = realStarScore; + case XHStarRateViewRateStyeHalfStar: { + float round = roundf(realRating); + self.currentRating = (round > realRating) ? round : (round + 0.5); break; - default: + } + case XHStarRateViewRateStyeIncompleteStar: { + self.currentRating = realRating; break; + } } - -} - -- (void)layoutSubviews { - [super layoutSubviews]; - __weak XHStarRateView *weakSelf = self; - CGFloat animationTimeInterval = self.isAnimation ? 0.2 : 0; - [UIView animateWithDuration:animationTimeInterval animations:^{ - weakSelf.foregroundStarView.frame = CGRectMake(0, 0, weakSelf.bounds.size.width * weakSelf.currentScore/self.numberOfStars, weakSelf.bounds.size.height); - }]; -} - - --(void)setCurrentScore:(CGFloat)currentScore { - if (_currentScore == currentScore) { - return; - } - if (currentScore < 0) { - _currentScore = 0; - } else if (currentScore > _numberOfStars) { - _currentScore = _numberOfStars; - } else { - _currentScore = currentScore; - } - - if ([self.delegate respondsToSelector:@selector(starRateView:currentScore:)]) { - [self.delegate starRateView:self currentScore:_currentScore]; - } - - if (self.complete) { - _complete(_currentScore); - } - - [self setNeedsLayout]; } -@end \ No newline at end of file +@end diff --git a/image/Demo.gif b/image/Demo.gif new file mode 100644 index 0000000..40ba01c Binary files /dev/null and b/image/Demo.gif differ diff --git a/image/image.png b/image/image.png new file mode 100644 index 0000000..d734fd8 Binary files /dev/null and b/image/image.png differ