处理触摸事件
我们先加上两个方法。一个是从第一个到某个星星开始从左到右依次点亮,一个是从最后一个星星到某个星星从右到左依次熄灭。
- (void)starsDownToIndex:(NSInteger)index {
for (NSInteger i = self.numberOfStars; i > index; --i) {
CDZStarButton *starButton = [self starForTag:i];
starButton.selected = NO;
starButton.highlighted = NO;
}
}
- (void)starsUpToIndex:(NSInteger)index {
for (NSInteger i = 0; i <= index; i++) {
CDZStarButton *starButton = [self starForTag:i];
starButton.selected = YES;
starButton.highlighted = NO;
}
}
然后设置一个评分的属性,重写其setter方法。allowFraction,用来判断组件是否需要分数表示,floor函数是取最大整数,相当于直接去除小数点后面的数字。判断评分的整数部分是否已经亮着,亮着那么说明从左到右最后一个亮着的右边,反之在左边,分别调用从右到左依次熄灭,或从左到右依次点亮的方法,最后再设置分数部分。
- (void)setScore:(CGFloat)score{
if (_score == score) {
return;
}
_score = score;
NSInteger index = floor(score);
CGFloat fractionPart = score - index;;
if (!self.isAllowFraction || fractionPart == 0) {
index -= 1;
}
CDZStarButton *starButton = [self starForTag:index];
if (starButton.selected) {
[self starsDownToIndex:index];
}
else{
[self starsUpToIndex:index];
}
starButton.fractionPart = fractionPart;
}
主要用到UIControl的四个方法

第一个是开始点击的时候的事件处理,第二个是手指未抬起在屏幕上继续移动的事件处理,第三个是离开屏幕,第四个是因为别的特殊情况事件被结束的处理。
点击时候只要确定点击的星星,确定其小数部分,然后调用评分属性的setter方法就好了。
- (BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event {
CGPoint point = [touch locationInView:self];
CDZStarButton *pressedStar = [self starForPoint:point];
if (pressedStar) {
self.currentStar = pressedStar;
NSInteger index = pressedStar.tag;
CGFloat fractionPart = 1;
if (self.isAllowFraction) {
fractionPart = [pressedStar fractionPartOfPoint:point];
}
self.score = index + fractionPart;
}
return YES;
}
移动处理除了和点击一样的判断逻辑,还要注意手指移开了星星之外的地方,分为所在星星的左边(当前星星熄灭),右边(当前星星完全点亮)两种。
- (BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event {
CGPoint point = [touch locationInView:self];
CDZStarButton *pressedStar = [self starForPoint:point];
if (pressedStar) {
self.currentStar = pressedStar;
NSInteger index = pressedStar.tag;
CGFloat fractionPart = 1;
if (self.isAllowFraction) {
fractionPart = [pressedStar fractionPartOfPoint:point];
}
self.score = index + fractionPart;
}
else{
//移到了当前星星的左边
if (point.x < self.currentStar.frame.origin.x) {
self.score = self.currentStar.tag;
}
//移到了当前星星的右边
else if (point.x > (self.currentStar.frame.origin.x + self.currentStar.frame.size.width)){
self.score = self.currentStar.tag + 1;
}
}
return YES;
}










