美文网首页iOS自定义控件
iOS - 仿淘宝星星评分

iOS - 仿淘宝星星评分

作者: Mr_Bob_ | 来源:发表于2016-11-04 18:06 被阅读53次
    前言:

    最近项目中做商城,涉及到订单评价,评分的问题,网上参考了别人的一些资料,然后封装了一套可以实现评分功能的方法,效果如下:

    Untitled00.gif
    具体方法如下:
    • KFStarView.h
    #import <UIKit/UIKit.h>
    
    @class KFStarView;
    @protocol KFStarViewDelegate <NSObject>
    @optional
    
    // 星星百分比(得分值)发生变化的代理
    - (void)starView:(KFStarView *)starView scorePercentDidChange:(CGFloat)newScorePercent;
    @end
    
    @interface KFStarView : UIView
    
    @property (nonatomic, assign) CGFloat scorePercent;//得分值,范围为0~1,默认1
    @property (nonatomic, assign) BOOL hasAnimation;//是否允许动画,默认为NO
    @property (nonatomic, assign) BOOL allowIncompleteStar;//评分时是否允许不是整星,默认为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" //点亮星星图片
    #define STAR_BACK_NAME @"star_deauful" // 未点亮星星图片
    #define DEFALUT_STAR_NUMBER 5 // 默认星星个数
    #define ANIMATION_TIME_INTERVAL 0.2 // 动画延时
    
    @interface KFStarView()
    
    // 前景视图
    @property (nonatomic, strong) UIView *foregroundStarView;
    // 背景视图
    @property (nonatomic, strong) UIView *backgroundStarView;
    // 星星个数
    @property (nonatomic, assign) NSInteger numberOfStars;
    
    @end
    
    @implementation KFStarView
    
    - (instancetype)initWithFrame:(CGRect)frame {
        // 初始化,这里我设置星星个数为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
    // 创建视图
    - (void)createDataAndUI {
        _scorePercent = 1;//默认为1
        _hasAnimation = NO;//默认为NO
        _allowIncompleteStar = NO;//默认为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];
        
        // 添加点按手势(也可以添加拖动手势)
        UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(userTapRateView:)];
        tapGesture.numberOfTapsRequired = 1;
        [self addGestureRecognizer:tapGesture];
    }
    
    - (void)userTapRateView:(UITapGestureRecognizer *)gesture {
        CGPoint tapPoint = [gesture locationInView:self]; // 手指当前点
        CGFloat offset = tapPoint.x;
        // 当前偏移的X值 = 手指当前的位置*(星星视图总宽度/星星个数)
        CGFloat realStarScore = offset / (self.bounds.size.width / self.numberOfStars);
        // ceilf函数:返回浮点数整数部分(舍弃小数点部分,往个位数进1)如12.234 → ceilf(12.234)=13
        // 这句的意思是 是否显示整星
        CGFloat starScore = self.allowIncompleteStar ? realStarScore : ceilf(realStarScore);
        // 用手指移动的距离/星星的个数  == 点亮星星个数
        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;
        }
        // 得分范围我设置的是0~1 这个可以你自己设定
        if (scroePercent < 0) {
            _scorePercent = 0;
        } else if (scroePercent > 1) {
            _scorePercent = 1;
        } else {
            _scorePercent = scroePercent;
        }
        // 代理方法,当星星百分比发生变化时候调用
        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];
    
    • 实现代理方法
    #pragma mark -- KFStarViewDelegate
    - (void)starView:(KFStarView *)starView scorePercentDidChange:(CGFloat)newScorePercent{
        // 返回的是评分结果
        self.starPercent = newScorePercent;
    }
    

    相关文章

      网友评论

      本文标题:iOS - 仿淘宝星星评分

      本文链接:https://www.haomeiwen.com/subject/cgdwuttx.html