CWStarRateView.m 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. //
  2. // CWStarRateView.m
  3. // StarRateDemo
  4. //
  5. // Created by WANGCHAO on 14/11/4.
  6. // Copyright (c) 2014年 wangchao. All rights reserved.
  7. //
  8. #import "CWStarRateView.h"
  9. #define FOREGROUND_STAR_IMAGE_NAME @"vqu_images_H_star_yellow"
  10. #define BACKGROUND_STAR_IMAGE_NAME @"vqu_images_H_star_gray"
  11. #define DEFALUT_STAR_NUMBER 5
  12. #define ANIMATION_TIME_INTERVAL 0.2
  13. @interface CWStarRateView ()
  14. @property (nonatomic, strong) UIView *foregroundStarView;
  15. @property (nonatomic, strong) UIView *backgroundStarView;
  16. @property (nonatomic, assign) NSInteger numberOfStars;
  17. @end
  18. @implementation CWStarRateView
  19. #pragma mark - Init Methods
  20. - (instancetype)init {
  21. NSAssert(NO, @"You should never call this method in this class. Use initWithFrame: instead!");
  22. return nil;
  23. }
  24. - (instancetype)initWithFrame:(CGRect)frame {
  25. return [self initWithFrame:frame numberOfStars:DEFALUT_STAR_NUMBER];
  26. }
  27. - (instancetype)initWithCoder:(NSCoder *)aDecoder {
  28. if (self = [super initWithCoder:aDecoder]) {
  29. _numberOfStars = DEFALUT_STAR_NUMBER;
  30. [self buildDataAndUI];
  31. }
  32. return self;
  33. }
  34. - (instancetype)initWithFrame:(CGRect)frame numberOfStars:(NSInteger)numberOfStars {
  35. if (self = [super initWithFrame:frame]) {
  36. _numberOfStars = numberOfStars;
  37. [self buildDataAndUI];
  38. }
  39. return self;
  40. }
  41. #pragma mark - Private Methods
  42. - (void)buildDataAndUI {
  43. _scorePercent = 1;//默认为1
  44. _hasAnimation = NO;//默认为NO
  45. _allowIncompleteStar = NO;//默认为NO
  46. self.foregroundStarView = [self createStarViewWithImage:FOREGROUND_STAR_IMAGE_NAME];
  47. self.backgroundStarView = [self createStarViewWithImage:BACKGROUND_STAR_IMAGE_NAME];
  48. [self addSubview:self.backgroundStarView];
  49. [self addSubview:self.foregroundStarView];
  50. UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(userTapRateView:)];
  51. tapGesture.numberOfTapsRequired = 1;
  52. [self addGestureRecognizer:tapGesture];
  53. }
  54. - (void)userTapRateView:(UITapGestureRecognizer *)gesture {
  55. CGPoint tapPoint = [gesture locationInView:self];
  56. CGFloat offset = tapPoint.x;
  57. CGFloat realStarScore = offset / (self.bounds.size.width / self.numberOfStars);
  58. CGFloat starScore = self.allowIncompleteStar ? realStarScore : ceilf(realStarScore);
  59. self.scorePercent = starScore / self.numberOfStars;
  60. }
  61. - (UIView *)createStarViewWithImage:(NSString *)imageName {
  62. UIView *view = [[UIView alloc] initWithFrame:self.bounds];
  63. view.clipsToBounds = YES;
  64. view.backgroundColor = [UIColor clearColor];
  65. for (NSInteger i = 0; i < self.numberOfStars; i ++)
  66. {
  67. UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:imageName]];
  68. imageView.frame = CGRectMake(i * self.bounds.size.width / self.numberOfStars, 0, self.bounds.size.width / self.numberOfStars, self.bounds.size.height);
  69. imageView.contentMode = UIViewContentModeScaleAspectFit;
  70. [view addSubview:imageView];
  71. }
  72. return view;
  73. }
  74. - (void)layoutSubviews {
  75. [super layoutSubviews];
  76. __weak CWStarRateView *weakSelf = self;
  77. CGFloat animationTimeInterval = self.hasAnimation ? ANIMATION_TIME_INTERVAL : 0;
  78. [UIView animateWithDuration:animationTimeInterval animations:^{
  79. weakSelf.foregroundStarView.frame = CGRectMake(0, 0, weakSelf.bounds.size.width * weakSelf.scorePercent, weakSelf.bounds.size.height);
  80. }];
  81. }
  82. #pragma mark - Get and Set Methods
  83. - (void)setScorePercent:(CGFloat)scroePercent {
  84. if (_scorePercent == scroePercent) {
  85. return;
  86. }
  87. if (scroePercent < 0) {
  88. _scorePercent = 0;
  89. } else if (scroePercent > 1) {
  90. _scorePercent = 1;
  91. } else {
  92. _scorePercent = scroePercent;
  93. }
  94. if ([self.delegate respondsToSelector:@selector(starRateView:scroePercentDidChange:)]) {
  95. [self.delegate starRateView:self scroePercentDidChange:scroePercent];
  96. }
  97. [self setNeedsLayout];
  98. }
  99. @end