我知道那里有很多第三方解决方案,但我已经决定自己建立一个解决方案来完全控制动画并学习新东西。
似乎大部分时间都是通过子类化UIControl和跟踪触摸来完成的,但我使用了不同的方法。我用图像创建系统按钮。这样我就可以免费在印刷机上获得精彩的高光动画。无论如何,它非常好用,直到你真的很快按下它。这是一个发生了什么的GIF。
有时候,如果你真的很快就会让一颗满满的星星卡住。我将尝试解释这个动画背后发生的事情。由于满星和空星有不同的颜色,每次变满或变空时我都会改变按钮的色调颜色。您看到的动画是一个单独的UIImageView,它在动画块开始之前添加到按钮顶部,并在完成块中删除。我相信有时在清空星形动画时不会触发,并且在完成块中不会删除图像。但我无法在代码中发现这个错误。
我添加了一些调试代码,以查看是否会触发使星空的块。看起来像是,甚至调用完成块。
2015-04-23 13:00:00.416 RERatingControl[24011:787202]
Touch number: 5
2015-04-23 13:00:00.416 RERatingControl[24011:787202]
removing a star at index: 4
2015-04-23 13:00:00.693 RERatingControl[24011:787202] star removed
星级索引是从零开始的,所以第五颗星应该被删除,但它不是。
完整项目在github。它非常小。如果有人帮我解决这个问题,我将不胜感激。哦,如果您想: - )
,请随意使用此代码更新。我被建议在这里发布一些逻辑代码。我没有马上做,因为我觉得它太麻烦了。
按钮操作方法:
- (void)buttonPressed:(id)sender {
static int touchNumber = 0;
NSLog(@"\nTouch number: %d", touchNumber);
touchNumber++;
if (self.isUpdating) {
return;
}
self.updating = YES;
NSInteger index = [self.stars indexOfObject:sender];
__block NSTimeInterval delay = 0;
[self.stars enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
REStarButton *btn = (REStarButton*)obj;
if (idx <= index) {
if (!btn.isFull) {
NSLog(@"\nadding a star at index: %ld", (long)idx);
[btn makeFullWithDelay:delay];
delay += animationDelay;
}
} else {
if (btn.isFull) {
NSLog(@"\nremoving a star at index: %ld", (long)idx);
[btn makeEmptyWithDelay:0];
}
}
}];
if ([self.delegate respondsToSelector:@selector(ratingDidChangeTo:)]) {
[self.delegate ratingDidChangeTo:index + 1];
}
self.updating = NO;
}
清空全星方法:
- (void)makeEmptyWithDelay:(NSTimeInterval)delay {
// if (!self.isFull) {
// return;
// }
self.full = NO;
UIImageView *fullStar = [[UIImageView alloc] initWithImage:self.starImageFull];
[self addSubview:fullStar];
CGFloat xOffset = CGRectGetMidX(self.bounds) - CGRectGetMidX(fullStar.bounds);
CGFloat yOffset = CGRectGetMidY(self.bounds) - CGRectGetMidY(fullStar.bounds);
fullStar.frame = CGRectOffset(fullStar.frame, xOffset, yOffset);
[self setImage:self.starImageEmpty forState:UIControlStateNormal];
[self setTintColor:self.superview.tintColor];
[UIView animateWithDuration:animationDuration delay:delay options:UIViewAnimationOptionCurveEaseOut animations:^{
//fullStar.transform = CGAffineTransformMakeScale(0.1f, 0.1f);
fullStar.transform = CGAffineTransformMakeTranslation(0, 10);
fullStar.alpha = 0;
} completion:^(BOOL finished) {
[fullStar removeFromSuperview];
NSLog(@"star removed");
}];
制作空星星方法:
}
- (void)makeFullWithDelay:(NSTimeInterval)delay {
// if (self.isFull) {
// return;
// }
self.full = YES;
UIImageView *fullStar = [[UIImageView alloc] initWithImage:self.starImageFull];
CGFloat xOffset = CGRectGetMidX(self.bounds) - CGRectGetMidX(fullStar.bounds);
CGFloat yOffset = CGRectGetMidY(self.bounds) - CGRectGetMidY(fullStar.bounds);
fullStar.frame = CGRectOffset(fullStar.frame, xOffset, yOffset);
fullStar.transform = CGAffineTransformMakeScale(0.01f, 0.01f);
[self addSubview:fullStar];
[UIView animateKeyframesWithDuration:animationDuration delay:delay options:0 animations:^{
CGFloat ratio = 0.35;
[UIView addKeyframeWithRelativeStartTime:0 relativeDuration:ratio animations:^{
fullStar.transform = CGAffineTransformMakeScale(animationScaleRatio, animationScaleRatio);
}];
[UIView addKeyframeWithRelativeStartTime:ratio relativeDuration:1 - ratio animations:^{
fullStar.transform = CGAffineTransformIdentity;
}];
} completion:^(BOOL finished) {
[self setImage:self.starImageFull forState:UIControlStateNormal];
[self setTintColor:self.fullTintColor];
[fullStar removeFromSuperview];
}];
}
答案 0 :(得分:0)
啊,我已经设法找到了我的错误背后的原因,它现在完美无缺!
我使用View Debugging查看它是否是动画中的UIImageView卡在按钮上,或者按钮本身的图像设置不正确。我很惊讶地看到导致问题的按钮图像。然后我再次查看代码并意识到我在延迟后更改完成块中的按钮图像,而不考虑它的状态是否已经改变。 makeFullWithDelay的一个简单修复:解决了我的问题。
} completion:^(BOOL finished) {
if (self.isFull) {
[self setImage:self.starImageFull forState:UIControlStateNormal];
[self setTintColor:self.fullTintColor];
}
[fullStar removeFromSuperview];
}];
昨天整个晚上都试图找到答案,在我发布问题答案之后就自己来了。告诉人们你的问题确实有助于我更多地关注你的逻辑。谢谢大家: - )
我应该删除帖子,还是将来可能对某人有所帮助?