UIScrollViewに3つのキーパッドがあり、各キーパッドはボタンの列です。ボタンの状態(キーパッドがデリゲートとして機能している)の更新を取得すると、この状態の変化に対応する特定のボタン画像があります-オン、オフ、および2つのオン/オフアニメーション(1Hzおよび10Hz)。現在、すべてが機能していますが、すべてのアニメーションを適切に同期する必要があります。私が持っているコードは、単一のキーパッドでアニメーションを同期しますが、ページ上のすべてのキーパッドではありません(これは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];
}
}
繰り返しますが、これは1つのキーパッドのアニメーションを同期しますが、すべてではありません。
私が思いついた解決策の1つは、すべてのアニメーションをシステム時間の倍数(たとえば、可能な限り1秒に近い時間)で開始することでしたが、それを実現する実用的なアプローチを思い付くことができませんでした。同期のパート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の無限ループとブロック)。正確に正しいタイミングで投票することは決してないからだと思います。
私がやりたいことをする方法はありますか?