头文件

#import <UIKit/UIKit.h>

@class RateView;

 

@protocol RateViewDelegate

- (void)rateView:(RateView *)rateView ratingDidChange:(float)rating;

@end

 

@interface RateView : UIView

 

@property (strong, nonatomic) UIImage *notSelectedImage;

@property (strong, nonatomic) UIImage *halfSelectedImage;

@property (strong, nonatomic) UIImage *fullSelectedImage;

@property (assign, nonatomic) float rating;

@property (assign) BOOL editable;

@property (strong) NSMutableArray *imageViews;

@property (assign, nonatomic) int maxRating;

@property (assign) int midMargin;

@property (assign) int leftMargin;

@property (assign) CGSize minImageSize;

@property (assign) id <RateViewDelegate> delegate;

 

@end

 

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////

实现文件

 

#import "RateView.h"

 

@implementation RateView

 

@synthesize notSelectedImage = _notSelectedImage;

@synthesize halfSelectedImage = _halfSelectedImage;

@synthesize fullSelectedImage = _fullSelectedImage;

@synthesize rating = _rating;

@synthesize editable = _editable;

@synthesize imageViews = _imageViews;

@synthesize maxRating = _maxRating;

@synthesize midMargin = _midMargin;

@synthesize leftMargin = _leftMargin;

@synthesize minImageSize = _minImageSize;

@synthesize delegate = _delegate;

 

- (void)baseInit {

    _notSelectedImage = nil;

    _halfSelectedImage = nil;

    _fullSelectedImage = nil;

    _rating = 0;

    _editable = NO;    

    _imageViews = [[NSMutableArray alloc] init];

    _maxRating = 5;

    _midMargin = 5;

    _leftMargin = 0;

    _minImageSize = CGSizeMake(5, 5);

    _delegate = nil;    

}

 

- (id)initWithFrame:(CGRect)frame

{

    self = [super initWithFrame:frame];

    if (self) {

        [self baseInit];

    }

    return self;

}

 

- (id)initWithCoder:(NSCoder *)aDecoder {

    if ((self = [super initWithCoder:aDecoder])) {

        [self baseInit];

    }

    return self;

}

 

- (void)refresh {

    for(int i = 0; i < self.imageViews.count; ++i) {

        UIImageView *imageView = [self.imageViews objectAtIndex:i];

        if (self.rating >= i+1) {

            imageView.image = self.fullSelectedImage;

        } else if (self.rating > i) {

            imageView.image = self.halfSelectedImage;

        } else {

            imageView.image = self.notSelectedImage;

        }

    }

}

 

- (void)layoutSubviews {

    [super layoutSubviews];

    

    if (self.notSelectedImage == nil) return;

    

    float desiredImageWidth = (self.frame.size.width - (self.leftMargin*2) - (self.midMargin*self.imageViews.count)) / self.imageViews.count;

    float imageWidth = MAX(self.minImageSize.width, desiredImageWidth);

    float imageHeight = MAX(self.minImageSize.height, self.frame.size.height);

    

    for (int i = 0; i < self.imageViews.count; ++i) {

        

        UIImageView *imageView = [self.imageViews objectAtIndex:i];

        CGRect imageFrame = CGRectMake(self.leftMargin + i*(self.midMargin+imageWidth), 0, imageWidth, imageHeight);

        imageView.frame = imageFrame;

        

    }    

    

}

 

- (void)setMaxRating:(int)maxRating {

    _maxRating = maxRating;

    

    // Remove old image views

    for(int i = 0; i < self.imageViews.count; ++i) {

        UIImageView *imageView = (UIImageView *) [self.imageViews objectAtIndex:i];

        [imageView removeFromSuperview];

    }

    [self.imageViews removeAllObjects];

    

    // Add new image views

    for(int i = 0; i < maxRating; ++i) {

        UIImageView *imageView = [[UIImageView alloc] init];

        imageView.contentMode = UIViewContentModeScaleAspectFit;

        [self.imageViews addObject:imageView];

        [self addSubview:imageView];

    }

    

    // Relayout and refresh

    [self setNeedsLayout];

    [self refresh];

}

 

- (void)setNotSelectedImage:(UIImage *)image {

    _notSelectedImage = image;

    [self refresh];

}

 

- (void)setHalfSelectedImage:(UIImage *)image {

    _halfSelectedImage = image;

    [self refresh];

}

 

- (void)setFullSelectedImage:(UIImage *)image {

    _fullSelectedImage = image;

    [self refresh];

}

 

- (void)setRating:(float)rating {

    _rating = rating;

    [self refresh];

}

 

- (void)handleTouchAtLocation:(CGPoint)touchLocation {

    if (!self.editable) return;

    

    int newRating = 0;

    for(int i = self.imageViews.count - 1; i >= 0; i--) {

        UIImageView *imageView = [self.imageViews objectAtIndex:i];        

        if (touchLocation.x > imageView.frame.origin.x) {

            newRating = i+1;

            break;

        }

    }

    

    self.rating = newRating;

}

 

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    UITouch *touch = [touches anyObject];

    CGPoint touchLocation = [touch locationInView:self];

    [self handleTouchAtLocation:touchLocation];

}

 

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {

    UITouch *touch = [touches anyObject];

    CGPoint touchLocation = [touch locationInView:self];

    [self handleTouchAtLocation:touchLocation];

}

 

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {

    [self.delegate rateView:self ratingDidChange:self.rating];

}

 

@end

 

 

From:

http://www.raywenderlich.com/1768/how-to-make-a-custom-uiview-a-5-star-rating-view