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