今天為大家?guī)?lái)一個(gè)iOS星級(jí)評(píng)分控件的實(shí)現(xiàn)裤纹,歡迎拍磚委刘。
在github上搜索iOS星級(jí)評(píng)分控件,可以看到TQStarRatingView是排名比較靠前的鹰椒,所以今天就以這個(gè)為例來(lái)說(shuō)明iOS星級(jí)評(píng)分控件的實(shí)現(xiàn)锡移。TQStarRatingView在github的地址:https://github.com/TinyQ/TQStarRatingView
首先就是如何能夠?qū)崿F(xiàn)單個(gè)星星顏色的變化。
要弄懂這個(gè)問(wèn)題漆际,那么就應(yīng)該先知道展示的view是張什么樣的淆珊。
打開(kāi)TQStarRatingView.m文件,找到commonInit方法奸汇,如下:
- (void)commonInit
{
self.starBackgroundView = [self buidlStarViewWithImageName:kBACKGROUND_STAR];
self.starForegroundView = [self buidlStarViewWithImageName:kFOREGROUND_STAR];
[self addSubview:self.starBackgroundView];
[self addSubview:self.starForegroundView];
}
從這里可以看到生成了兩個(gè)view施符,starBackgroundView為背景(暗淡的星星)往声,而starForegroundView為前景(高亮的星星)。再找到生成這兩個(gè)view的方法buidlStarViewWithImageName
- (UIView *)buidlStarViewWithImageName:(NSString *)imageName
{
CGRect frame = self.bounds;
UIView *view = [[UIView alloc] initWithFrame:frame];
view.clipsToBounds = YES;
CGFloat starsWidth = frame.size.width - (_numberOfStar - 1) * divisionWidth;
for (int i = 0; i < self.numberOfStar; i ++)
{
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:imageName]];
imageView.frame = CGRectMake(i / self.numberOfStar * starsWidth + i * divisionWidth, 0, starsWidth / self.numberOfStar, frame.size.height);
[view addSubview:imageView];
}
return view;
}
可以看到其實(shí)背景view和前景view的frame是完全一樣的戳吝,沒(méi)有區(qū)別浩销。納尼!其實(shí)就是兩個(gè)形狀大小一模一樣的骨坑,一個(gè)覆蓋掉另外一個(gè)撼嗓,高亮星星覆蓋掉了暗淡星星~~~這么說(shuō)來(lái)我們看到的星級(jí)的效果就應(yīng)該是要顯示多少顆星的時(shí)候,把前景的寬度設(shè)置為對(duì)應(yīng)的大小欢唾,然后下面的暗淡的星星就顯示出來(lái)了且警,是不是這樣,咱接著往下看礁遣。
接下來(lái)我們可以看到有兩個(gè)設(shè)置控件分?jǐn)?shù)的方法斑芜,大致代碼如下:
- (void)setScore:(float)score withAnimation:(bool)isAnimate completion:(void (^)(BOOL finished))completion
{
NSAssert((score >= 0.0)&&(score <= 1.0), @"score must be between 0 and 1");
if (score < 0)
{
score = 0;
}
if (score > 1)
{
score = 1;
}
CGPoint point = CGPointMake(score * self.frame.size.width, 0);
//省略部分代碼
[self changeStarForegroundViewWithPoint:point];
}
/**
*? 通過(guò)坐標(biāo)改變前景視圖
*
*? @param point 坐標(biāo)
*/
- (void)changeStarForegroundViewWithPoint:(CGPoint)point
{
CGPoint p = point;
if (p.x < 0)
{
p.x = 0;
}
if (p.x > self.frame.size.width)
{
p.x = self.frame.size.width;
}
NSString * str = [NSString stringWithFormat:@"%0.2f",p.x / self.frame.size.width];
float score = [str floatValue];
p.x = score * self.frame.size.width;
self.starForegroundView.frame = CGRectMake(0, 0, p.x, self.frame.size.height);
//省略部分代碼
}
score是一個(gè)浮點(diǎn)數(shù),大小限制為0-1之間祟霍,所以其實(shí)這是個(gè)百分比杏头。然后會(huì)根據(jù)這個(gè)百分比計(jì)算要顯示的高亮的星星的寬度是多少,來(lái)設(shè)置starForegroundView顯示的寬度(frame.x從0開(kāi)始)沸呐。果然跟我們上面的猜測(cè)是一樣的醇王,并且這種方式的話,可以滿足我們對(duì)分?jǐn)?shù)設(shè)置的大多數(shù)要求崭添,如:4分寓娩、4.5分甚至4.1分這種都能輕松搞定。