1

我编写了一个方法 sortAndSlideHandCards(),它可以移动 6 个 UIButton。每个 UIButton 都移动到相同的位置。这是通过 for-each 循环和在每个 UIButton 上调用的 animateWithDuration 方法来完成的。

同时为多个玩家调用此方法。目前,该行为会导致每个玩家的 UIButtons 移动,但一次只能移动一个。任何时候都不能移动超过一个 UIButton,就好像每个动画都在等待当前正在运行的任何动画停止,然后再尝试它自己的动画,本质上,每个播放器/UIButton 的代码都是按顺序执行的。我希望线程能帮助我解决这个问题。

当我添加线程代码时:

backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);     
sortAndSlideHandCardsGroup = dispatch_group_create();

for(Player* player in _playersArray) {

    dispatch_group_async(sortAndSlideHandCardsGroup, backgroundQueue, ^(void) {
        [player sortAndSlideHandCards];
    });    

    dispatch_group_wait(sortAndSlideHandCardsGroup,DISPATCH_TIME_FOREVER);

我发现每个玩家只触发了第一个 UIButton 动画,并且代码在运行循环“while”中被阻止,因为“_animationEnd”永远不会被设置,因为看起来第二个动画永远不会开始。

我可以看到该方法在自己的线程中启动

- (void) sortAndSlideHandCards  {

NSLog(@"PLAYER:sortAndSlideHandCards");

CGPoint newCenter;
Card* tempCard = nil;
int count = 1;

float duration = 0.2 / _speedMultiplyer;
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
for(Card *card in _handCards) { //move cards in hand to one postion in hand

    if(count == 1) {
        tempCard = [[Card alloc] init:_screenWidth:_screenHeight :[card getNumber] :[card getCardWeight] :[card getSuit] :[card getIsSpecial]];
        [tempCard setImageSrc: _playerNumber :!_isPlayerOnPhone :count : true :_view: _isAI: [_handCards count]];
        newCenter = [tempCard getButton].center;
    }

    _animationStillRunning = true;
    if(![[DealViewController getCardsInPlayArray] containsObject:card] ) {

        [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionLayoutSubviews animations:^{[card getButton].center = newCenter;} completion:^(BOOL finished){[self animationEnd];}];            
        while (_animationStillRunning){ //endAnimation will set _animationStillRunning to false when called
            //stuck in here after first UIButton when threading code is in play
            [runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
        } //endAnimation will set _animationStillRunning to false when called

    }

    count++;
}

}

当我注释掉线程代码时,每个 UIButton (Card) 都会一个接一个地设置动画。

随着线程代码的运行,第一个 UIButton 将进行动画处理,但在通过 for 循环的第二次运行期间,代码将卡在 while 循环中,等待动画结束。我猜第二个动画甚至都没有开始。

我也试过这个线程代码:

[player performSelectorInBackground:@selector(sortAndSlideHandCards) withObject:nil];

同样的结果

任何人都知道为什么 animateWithDuration 不喜欢在主线程以外的线程中被循环调用?

4

1 回答 1

0

您应该能够从执行的任何 UI 操作中启动您想要的动画。UIView animateWith... 方法会立即返回,因此您无需担心等待它们完成。

如果您有未知数量的动画要按顺序启动,请使用该delay参数。伪代码:

NSTimeInterval delay = 0;
NSTimeInterval duration = 0.25;

for (UIView *view in viewsToAnimate)
{
    [UIView animateWithDuration:duration delay:delay animations:^{ ... animations ...}];
    delay += duration;
}

这将增加每个连续动画的延迟,因此它从前一个动画的末尾开始。

于 2012-11-21T16:37:53.367 回答