之前项目中有用到星级评价,模仿美团的订单评价写了个小demo,效果如下
- 代码实现
以为需求不确定有几行评价结果,然后我是按一行一个View处理的,上图对应的是四个View,后续有时间会再调整下。😭
#pragma mark - private Method
-(void)createStarView{
self.testVC.view.backgroundColor = [UIColor redColor];
self.backgroundColor = [UIColor whiteColor];
if ([self.subviews containsObject:self.foregroundStarView]) {
[self.foregroundStarView removeFromSuperview];
}
if ([self.subviews containsObject:self.backgroundStarView]) {
[self.backgroundStarView removeFromSuperview];
}
self.foregroundStarView = [self createStarViewWithImage:ForegroundStarImage];
self.backgroundStarView = [self createStarViewWithImage:BackgroundStarImage];
CGFloat foregroundStarViewWidth = 0.;
if (_currentScore > 0) {
foregroundStarViewWidth = _currentScore * StartWidth + (ceilf(_currentScore) - 1) * _starSpaceing;
} else {
foregroundStarViewWidth = 0;
}
self.foregroundStarView.frame = CGRectMake(0, 0, foregroundStarViewWidth, 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 *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 * (StartWidth + _starSpaceing), 0, StartWidth, self.bounds.size.height);
imageView.contentMode = UIViewContentModeScaleAspectFit;
[view addSubview:imageView];
}
return view;
}
- (void)userTapRateView:(UITapGestureRecognizer *)gesture {
CGPoint tapPoint = [gesture locationInView:self];
CGFloat offset = tapPoint.x;
// CGFloat realStarScore = offset / (((StartWidth + _starSpaceing) * self.numberOfStars - _starSpaceing) / self.numberOfStars);
//一个星+一个间距为单位 向下取整
CGFloat floorStarScore = floorf(offset / (StartWidth + _starSpaceing));
//多于一个完整星(星宽+间距)外的宽度
CGFloat excessWidth = offset - floorStarScore * (StartWidth + _starSpaceing);
//真实星数目
CGFloat realStarScore = (offset - floorStarScore * _starSpaceing) / StartWidth;
;
if (excessWidth > StartWidth) { //多的是间距。向下取整
realStarScore = floorf(realStarScore);
}
switch (_rateStyle) {
case ZJYWholeStar:
{
self.currentScore = ceilf(realStarScore);
break;
}
case ZJYHalfStar:
self.currentScore = roundf(realStarScore)>=realStarScore ? ceilf(realStarScore):(ceilf(realStarScore)-0.5);
break;
case ZJYIncompleteStar:
self.currentScore = realStarScore;
break;
default:
break;
}
}
ZJYStarRateView *starRateView = [[ZJYStarRateView alloc] initWithFrame:CGRectMake(20, 100, 200, 30)];
starRateView.isAnimation = YES;
starRateView.rateStyle = ZJYIncompleteStar;
starRateView.tag = 1;
starRateView.currentScore = 1.2;
starRateView.starSpaceing = StarSpace;
starRateView.delegate = self;
[self.view addSubview:starRateView];
ZJYStarRateView *starRateView2 = [[ZJYStarRateView alloc] initWithFrame:CGRectMake(20, 140, 200, 30) numberOfStars:5 rateStyle:ZJYHalfStar isAnination:YES delegate:self];
starRateView2.tag = 2;
starRateView2.starSpaceing = StarSpace;
[self.view addSubview:starRateView2];
ZJYStarRateView *starRateView3 = [[ZJYStarRateView alloc] initWithFrame:CGRectMake(20, 180, 200, 30) finish:^(CGFloat currentScore) {
NSLog(@"3---- %f",currentScore);
}];
starRateView3.starSpaceing = StarSpace;
[self.view addSubview:starRateView3];
ZJYStarRateView *starRateView4 = [[ZJYStarRateView alloc] initWithFrame:CGRectMake(20, 220, 200, 30) numberOfStars:5 rateStyle:ZJYHalfStar isAnination:YES finish:^(CGFloat currentScore) {
NSLog(@"4---- %f",currentScore);
}];
starRateView4.testVC = self;
starRateView4.starSpaceing = StarSpace;
[self.view addSubview:starRateView4];
#pragma mark -ZJYStarRateViewDelegate
-(void)starRateView:(ZJYStarRateView *)starRateView currentScore:(CGFloat)currentScore{
NSLog(@"%ld---- %f",starRateView.tag,currentScore);
}