收到消息的iOS动画队列

时间:2014-08-12 23:46:31

标签: ios animation uianimation

我有一个简单的动画,在收到消息时运行。如果他们只收到一条消息,这很有用。但是,如果用户在动画中收到多条消息,则动画将重新开始。我不希望这种情况发生,我想在开始下一个动画之前完成动画。我的想法是创建一种类型的队列,它将循环通过带有键的字典来自'和'身体'但我不确定这是不是最好的做法。有没有人有任何想法?

- (void) messageReceived:(NSNotification *)notification
{

NSString *body = [[notification userInfo] valueForKey:@"body"];
NSString *from = [[notification userInfo] valueForKey:@"from"];
UILabel *usernameLabel = (UILabel *)[self.view viewWithTag:502];
usernameLabel.text = from;

 UILabel *messageLabel = (UILabel *)[self.view viewWithTag:503];
 messageLabel.text = body;
CGRect notificationFrame = notificationView.frame;
notificationFrame.origin.y = 0;

[UIView animateWithDuration:0.3
                          delay:0.0
                        options:UIViewAnimationOptionCurveEaseOut
                     animations:^{
                         notificationView.frame = notificationFrame;
                     }
                     completion:^(BOOL finished){

if (finished) {
                             [UIView animateWithDuration:0.3
                                                   delay:1.0
                                                 options:UIViewAnimationOptionCurveEaseOut
                                              animations:^{
                                                  CGRect oldNotificationFrame = notificationView.frame;
                                                  oldNotificationFrame.origin.y = -100;
                                                  notificationView.frame = oldNotificationFrame;
                                              }
                                              completion:NULL];
                         }


                     }];
}

1 个答案:

答案 0 :(得分:3)

我认为你需要双管齐下;创建消息并对消息进行排队,然后为消息设置动画,除非一个或多个消息已经排队等待动画;在这种情况下,只需对动画进行排队。动画结束后,完成块将递归,直到队列为空。

@implementation yourCLass {

    //  holds incoming animation requests in FIFO order
    NSMutableArray *animationQueue;

    //  control switch to avoid starting an animation if one is running
    BOOL isAnimating;
}

- (void) messageReceived:(NSNotification *)notification {

    //  pertinent message data is stored in a dict in the array
  NSString *body = [[notification userInfo] valueForKey:@"body"];
  NSString *from = [[notification userInfo] valueForKey:@"from"];

  NSDictionary *messageFacts = @{ @"body" : body,
                                  @"from" : from };

    //  most-recent messages get put into position zero; LIFO
    //  NB: this array has already been initialized elsewhere...
  [self->animationQueue insertObject:messageFacts
                             atIndex:0];

    //  now for animating BUT ONLY if not already animating (if already animating the queued
    //  animations will get animated anyway)
  if (!self->isAnimating) {

    [self animateMessages];
  }
}

- (void) animateMessages {

  if (self->animationQueue.count == 0) {
      //  all messages have been animated, clear isAnimating bit and exit

    self->isAnimating = NO;
    return;
  }

  self->isAnimating = YES;

  //  extract message data from array as a dictionary, delete from array
  NSDictionary *messageFacts = [self->animationQueue lastObject];
  [self->animationQueue removeLastObject];

  //  import message data from dictionary to labels
  UILabel *usernameLabel = (UILabel *)[self.view viewWithTag:502];
  usernameLabel.text = messageFacts[@"from"];

  UILabel *messageLabel = (UILabel *)[self.view viewWithTag:503];
  messageLabel.text = messageFacts[@"body"];

  //    other housekeeping
  CGRect notificationFrame = notificationView.frame;
  notificationFrame.origin.y = 0;

  [UIView animateWithDuration:0.3
                        delay:0.0
                      options:UIViewAnimationOptionCurveEaseOut
                   animations:^{

                     notificationView.frame = notificationFrame;
                   }
                   completion:^(BOOL finished){

                     if (finished) {

                       [UIView animateWithDuration:0.3
                                             delay:1.0
                                           options:UIViewAnimationOptionCurveEaseOut
                                        animations:^{

                                          CGRect oldNotificationFrame = notificationView.frame;
                                          oldNotificationFrame.origin.y = -100;
                                          notificationView.frame = oldNotificationFrame;
                                        }
                                        completion:^(BOOL finished){

                                          if (finished ) {

                                              //  when done, method recurs until all notifications have
                                              //  been animated
                                            [self animateMessages];
                                          }
                                        }];
                     }
                   }];
}