2

我在 UIScrollView 上有三个键盘,每个键盘都是一列按钮。当我获得按钮状态的更新(键盘充当代表)时,我有某些按钮图像可以响应这种状态变化 - 开、关和两个开/关动画(1 Hz 和 10 Hz)。现在我已经完成了所有工作,但我需要正确同步所有动画。我的代码在单个键盘上同步动画,但不是页面上的所有键盘(这是在 KeypadController 中):

#pragma mark -
#pragma mark LEDDelegate

- (void)LEDUpdated:(LED *)sender {
    // Search through our LEDs for a match on the updating LED. This gives us
    // the button index so we can update properly.
    int ledIndex = -1; // Needs to be zero indexed
    Component *tempComp;
    LED *tempLED;
    for (NSUInteger itemCount = 0; itemCount < [taskButtonTitleCollection count]; ++itemCount) {
        tempComp = (Component *) [taskButtonTitleCollection objectAtIndex:itemCount];
        if ([[tempComp getComponentType] isEqualToString:@"LED" ]){
            tempLED = (LED *) [tempComp getComponentElement];
            ledIndex++;
            if (tempLED == sender) {
                break;
            }
        }
    }

    //Code for selecting images here - removed for brevity    

    // Declare the image we're about to use
    UIImage *newNormal, *newHighlight, *newBlink;

    // Going to need the button for flashing
    UIButton *btn = [buttonCollection objectAtIndex:ledIndex];

    // For syncing animation, part 1
    // TODO: This syncs a single keypad, which means we don't sync between columns
    NSMutableArray *buttonsToSync = [[NSMutableArray alloc] init];
    for (UIButton *active in buttonCollection) {
        if ([[active imageView] isAnimating]) {
            [[active imageView] stopAnimating];
            if (active != btn) {
                [buttonsToSync addObject:active];
            }
        }  
    }

    // Grab the updated state of the current led object so we can select the
    // correct button images
    switch ([tempLED state]) {
        case LED_STATE_ON:
            newNormal = [[Utils getImageNamed:pressedImage] stretchableImageWithLeftCapWidth:0.0 topCapHeight:0.0];

            newHighlight = [[Utils getImageNamed:highlightedImage] stretchableImageWithLeftCapWidth:0.0 topCapHeight:0.0];
            break;

        case LED_STATE_FLASH1: // 1 Hz blinking
            newNormal = [[Utils getImageNamed:normalImage] stretchableImageWithLeftCapWidth:0.0 topCapHeight:0.0];
            newBlink = [[Utils getImageNamed:pressedImage] stretchableImageWithLeftCapWidth:0.0 topCapHeight:0.0];

            // We can animate between these two images at the correct
            // speed with the below code.
            [[btn imageView] setAnimationImages:[NSArray arrayWithObjects:newNormal, newBlink, nil]];
            [[btn imageView] setAnimationDuration:1];
            [buttonsToSync addObject:btn];

            newHighlight = [[Utils getImageNamed:highlightedImage] stretchableImageWithLeftCapWidth:0.0 topCapHeight:0.0];
            break;

        case LED_STATE_FLASH2: // 10 Hz blinking
            newNormal = [[Utils getImageNamed:normalImage] stretchableImageWithLeftCapWidth:0.0 topCapHeight:0.0];
            newBlink = [[Utils getImageNamed:pressedImage] stretchableImageWithLeftCapWidth:0.0 topCapHeight:0.0];

            // We can animate between these two images at the correct
            // speed with the below code.
            [[btn imageView] setAnimationImages:[NSArray arrayWithObjects:newNormal, newBlink, nil]];
            [[btn imageView] setAnimationDuration:0.1];
            [buttonsToSync addObject:btn];

            newHighlight = [[Utils getImageNamed:highlightedImage] stretchableImageWithLeftCapWidth:0.0 topCapHeight:0.0];
            break;

        case LED_STATE_OFF:
        default:
            newNormal = [[Utils getImageNamed:normalImage] stretchableImageWithLeftCapWidth:0.0 topCapHeight:0.0];

            newHighlight = [[Utils getImageNamed:normalImageWithoutShadow] stretchableImageWithLeftCapWidth:0.0 topCapHeight:0.0];
            break;
    }

    // Set the new button images for the normal and highlighted states
    [btn setImage:newNormal forState:UIControlStateNormal];
    [btn setImage:newHighlight forState:UIControlStateHighlighted];
    newNormal = nil, newBlink = nil, newHighlight = nil;

    // For syncing animation, part 2
    // TODO: This syncs a single keypad, which means we don't sync between columns
    for (UIButton *active in buttonsToSync) {
        [[active imageView] startAnimating];
    }       
}

同样,这会同步一个小键盘但不是全部的动画。

我想出的一个可能的解决方案是让所有动画在系统时间的某个倍数处开始(例如,尽可能接近一秒),但我想不出一种可行的方法来做到这一点。我尝试在同步的第 2 部分前面添加它(我重新启动动画):

NSDate *date = [NSDate date];
double timePassed_ms = [date timeIntervalSince1970] * 1000.0;

while ( (int)timePassed_ms % 500 != 0) {
    timePassed_ms = [date timeIntervalSince1970] * 1000.0;
}

不幸的是,这不起作用(无限循环和阻止 GUI)。我猜那是因为我从来没有在正确的时间投票。

有没有办法做我想做的事?

4

0 回答 0