iOS构建自定义评级控制问题

时间:2015-04-23 10:09:53

标签: ios debugging uibutton

我知道那里有很多第三方解决方案,但我已经决定自己建立一个解决方案来完全控制动画并学习新东西。

似乎大部分时间都是通过子类化UIControl和跟踪触摸来完成的,但我使用了不同的方法。我用图像创建系统按钮。这样我就可以免费在印刷机上获得精彩的高光动画。无论如何,它非常好用,直到你真的很快按下它。这是一个发生了什么的GIF。

enter image description here

有时候,如果你真的很快就会让一颗满满的星星卡住。我将尝试解释这个动画背后发生的事情。由于满星和空星有不同的颜色,每次变满或变空时我都会改变按钮的色调颜色。您看到的动画是一个单独的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];

    }];

}

1 个答案:

答案 0 :(得分:0)

啊,我已经设法找到了我的错误背后的原因,它现在完美无缺!

我使用View Debugging查看它是否是动画中的UIImageView卡在按钮上,或者按钮本身的图像设置不正确。我很惊讶地看到导致问题的按钮图像。然后我再次查看代码并意识到我在延迟后更改完成块中的按钮图像,而不考虑它的状态是否已经改变。 makeFullWithDelay的一个简单修复:解决了我的问题。

   } completion:^(BOOL finished) {

    if (self.isFull) {

        [self setImage:self.starImageFull forState:UIControlStateNormal];
        [self setTintColor:self.fullTintColor];

    }

    [fullStar removeFromSuperview];

}];

昨天整个晚上都试图找到答案,在我发布问题答案之后就自己来了。告诉人们你的问题确实有助于我更多地关注你的逻辑。谢谢大家: - )

我应该删除帖子,还是将来可能对某人有所帮助?