iOS - 仿淘寶星星評(píng)分

前言:

最近項(xiàng)目中做商城,涉及到訂單評(píng)價(jià),評(píng)分的問題,網(wǎng)上參考了別人的一些資料,然后封裝了一套可以實(shí)現(xiàn)評(píng)分功能的方法,效果如下:

Untitled00.gif
具體方法如下:
  • KFStarView.h
#import <UIKit/UIKit.h>

@class KFStarView;
@protocol KFStarViewDelegate <NSObject>
@optional

// 星星百分比(得分值)發(fā)生變化的代理
- (void)starView:(KFStarView *)starView scorePercentDidChange:(CGFloat)newScorePercent;
@end

@interface KFStarView : UIView

@property (nonatomic, assign) CGFloat scorePercent;//得分值,范圍為0~1淳衙,默認(rèn)1
@property (nonatomic, assign) BOOL hasAnimation;//是否允許動(dòng)畫说搅,默認(rèn)為NO
@property (nonatomic, assign) BOOL allowIncompleteStar;//評(píng)分時(shí)是否允許不是整星饭耳,默認(rèn)為NO

@property (nonatomic, weak) id<KFStarViewDelegate>delegate;
- (instancetype)initWithFrame:(CGRect)frame numberOfStars:(NSInteger)numberOfStars;

@end
  • KFStarView.m
#import "KFStarView.h"

#define STAR_FRONT_NAME @"star_selected" //點(diǎn)亮星星圖片
#define STAR_BACK_NAME @"star_deauful" // 未點(diǎn)亮星星圖片
#define DEFALUT_STAR_NUMBER 5 // 默認(rèn)星星個(gè)數(shù)
#define ANIMATION_TIME_INTERVAL 0.2 // 動(dòng)畫延時(shí)

@interface KFStarView()

// 前景視圖
@property (nonatomic, strong) UIView *foregroundStarView;
// 背景視圖
@property (nonatomic, strong) UIView *backgroundStarView;
// 星星個(gè)數(shù)
@property (nonatomic, assign) NSInteger numberOfStars;

@end

@implementation KFStarView

- (instancetype)initWithFrame:(CGRect)frame {
    // 初始化,這里我設(shè)置星星個(gè)數(shù)為5
    return [self initWithFrame:frame numberOfStars:DEFALUT_STAR_NUMBER];
}

// 考慮到使用xib的情況
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    
    if (self = [super initWithCoder:aDecoder]) {
        _numberOfStars = DEFALUT_STAR_NUMBER;
        [self createDataAndUI];
    }
    return self;
}

- (instancetype)initWithFrame:(CGRect)frame numberOfStars:(NSInteger)numberOfStars {
    if (self = [super initWithFrame:frame]) {
        _numberOfStars = numberOfStars;
        [self createDataAndUI];
    }
    return self;
}

#pragma mark - Private Methods
// 創(chuàng)建視圖
- (void)createDataAndUI {
    _scorePercent = 1;//默認(rèn)為1
    _hasAnimation = NO;//默認(rèn)為NO
    _allowIncompleteStar = NO;//默認(rèn)為NO
    
    self.foregroundStarView = [self createStarViewWithImage:STAR_FRONT_NAME];
    self.foregroundStarView.frame = CGRectMake(0, 0, 0, self.bounds.size.height);
    self.backgroundStarView = [self createStarViewWithImage:STAR_BACK_NAME];
    
    [self addSubview:self.backgroundStarView];
    [self addSubview:self.foregroundStarView];
    
    // 添加點(diǎn)按手勢(shì)(也可以添加拖動(dòng)手勢(shì))
    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(userTapRateView:)];
    tapGesture.numberOfTapsRequired = 1;
    [self addGestureRecognizer:tapGesture];
}

- (void)userTapRateView:(UITapGestureRecognizer *)gesture {
    CGPoint tapPoint = [gesture locationInView:self]; // 手指當(dāng)前點(diǎn)
    CGFloat offset = tapPoint.x;
    // 當(dāng)前偏移的X值 = 手指當(dāng)前的位置*(星星視圖總寬度/星星個(gè)數(shù))
    CGFloat realStarScore = offset / (self.bounds.size.width / self.numberOfStars);
    // ceilf函數(shù):返回浮點(diǎn)數(shù)整數(shù)部分(舍棄小數(shù)點(diǎn)部分淋淀,往個(gè)位數(shù)進(jìn)1)如12.234 → ceilf(12.234)=13
    // 這句的意思是 是否顯示整星
    CGFloat starScore = self.allowIncompleteStar ? realStarScore : ceilf(realStarScore);
    // 用手指移動(dòng)的距離/星星的個(gè)數(shù)  == 點(diǎn)亮星星個(gè)數(shù)
    self.scorePercent = starScore / self.numberOfStars;
}

- (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 * self.bounds.size.width / self.numberOfStars, 0, self.bounds.size.width / self.numberOfStars, self.bounds.size.height);
        imageView.contentMode = UIViewContentModeScaleAspectFit;
        [view addSubview:imageView];
    }
    return view;
}

- (void)layoutSubviews {
    [super layoutSubviews];
    __weak KFStarView *weakSelf = self;
    CGFloat animationTimeInterval = self.hasAnimation ? ANIMATION_TIME_INTERVAL : 0;
    [UIView animateWithDuration:animationTimeInterval animations:^{
        weakSelf.foregroundStarView.frame = CGRectMake(0, 0, weakSelf.bounds.size.width * weakSelf.scorePercent, weakSelf.bounds.size.height);
    }];
}

#pragma mark - Get and Set Methods

- (void)setScorePercent:(CGFloat)scroePercent {
    if (_scorePercent == scroePercent) {
        return;
    }
    // 得分范圍我設(shè)置的是0~1 這個(gè)可以你自己設(shè)定
    if (scroePercent < 0) {
        _scorePercent = 0;
    } else if (scroePercent > 1) {
        _scorePercent = 1;
    } else {
        _scorePercent = scroePercent;
    }
    // 代理方法弟头,當(dāng)星星百分比發(fā)生變化時(shí)候調(diào)用
    if ([self.delegate respondsToSelector:@selector(starView:scorePercentDidChange:)]) {
        [self.delegate starView:self scorePercentDidChange:scroePercent];
    }
    // 重新布局, 刷新視圖
    [self setNeedsLayout];
}

@end
具體使用方法:
  • 初始化
   KFStarView *starView = [[KFStarView alloc] initWithFrame:CGRectMake(CGRectGetMaxX(studioLogo.frame) + 5, CGRectGetMaxY(topLabel.frame) + 5, 150, 20) numberOfStars:5];
    starView.scorePercent = 0.0;
    starView.allowIncompleteStar = NO;
    starView.hasAnimation = YES;
    starView.delegate = self;
    [self addSubview:starView];
  • 實(shí)現(xiàn)代理方法
#pragma mark -- KFStarViewDelegate
- (void)starView:(KFStarView *)starView scorePercentDidChange:(CGFloat)newScorePercent{
    // 返回的是評(píng)分結(jié)果
    self.starPercent = newScorePercent;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市赏壹,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌衔沼,老刑警劉巖蝌借,帶你破解...
    沈念sama閱讀 206,482評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異指蚁,居然都是意外死亡菩佑,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門凝化,熙熙樓的掌柜王于貴愁眉苦臉地迎上來稍坯,“玉大人,你說我怎么就攤上這事搓劫∏朴矗” “怎么了?”我有些...
    開封第一講書人閱讀 152,762評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵枪向,是天一觀的道長勤揩。 經(jīng)常有香客問我,道長秘蛔,這世上最難降的妖魔是什么陨亡? 我笑而不...
    開封第一講書人閱讀 55,273評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮深员,結(jié)果婚禮上负蠕,老公的妹妹穿的比我還像新娘。我一直安慰自己倦畅,他們只是感情好遮糖,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評(píng)論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著叠赐,像睡著了一般欲账。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上燎悍,一...
    開封第一講書人閱讀 49,046評(píng)論 1 285
  • 那天敬惦,我揣著相機(jī)與錄音,去河邊找鬼谈山。 笑死俄删,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的奏路。 我是一名探鬼主播畴椰,決...
    沈念sama閱讀 38,351評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼鸽粉!你這毒婦竟也來了斜脂?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,988評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤触机,失蹤者是張志新(化名)和其女友劉穎帚戳,沒想到半個(gè)月后玷或,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,476評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡片任,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評(píng)論 2 324
  • 正文 我和宋清朗相戀三年偏友,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片对供。...
    茶點(diǎn)故事閱讀 38,064評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡位他,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出产场,到底是詐尸還是另有隱情鹅髓,我是刑警寧澤,帶...
    沈念sama閱讀 33,712評(píng)論 4 323
  • 正文 年R本政府宣布京景,位于F島的核電站窿冯,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏醋粟。R本人自食惡果不足惜靡菇,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望米愿。 院中可真熱鬧厦凤,春花似錦、人聲如沸育苟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽违柏。三九已至博烂,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間漱竖,已是汗流浹背禽篱。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評(píng)論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留馍惹,地道東北人躺率。 一個(gè)月前我還...
    沈念sama閱讀 45,511評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像万矾,于是被迫代替她去往敵國和親悼吱。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容