頭文件
#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