Ios 通过KVO(异步URLRequest之后)一个接一个地执行动画

Ios 通过KVO(异步URLRequest之后)一个接一个地执行动画,ios,objective-c,key-value-observing,uiviewanimation,Ios,Objective C,Key Value Observing,Uiviewanimation,我想根据传入的数据动态插入ui视图 我发送两个异步URL请求,并从另一个线程获取接收到的数据 我观察到一个属性,它动态地被来自不同请求的数据填充。所以KVO向我发送消息,可能是直接在彼此之后 随着第一条传入的消息,我开始一些相关的动画。在动画期间,新的数据到达并向我的观察者发送消息,这种情况经常发生。然后,我想等待动画结束,然后为新数据启动动画 我正在寻找一个好的实现,而不是一个while循环,等待bool改变 编辑: 考虑一下,我不能说哪个数据排在第一位。因此,我无法将动画方法定义为第一个。可

我想根据传入的数据动态插入
ui视图

我发送两个异步URL请求,并从另一个线程获取接收到的数据

我观察到一个属性,它动态地被来自不同请求的数据填充。所以KVO向我发送消息,可能是直接在彼此之后

随着第一条传入的消息,我开始一些相关的动画。在动画期间,新的数据到达并向我的观察者发送消息,这种情况经常发生。然后,我想等待动画结束,然后为新数据启动动画

我正在寻找一个好的实现,而不是一个while循环,等待bool改变

编辑:
考虑一下,我不能说哪个数据排在第一位。因此,我无法将动画方法定义为第一个。

可能会在第一个动画的完成例程中发布通知:

UIView animateWithDuration:delay:options:animations:completion:

可能会在第一个动画的完成例程中发布通知:

UIView animateWithDuration:delay:options:animations:completion:

如何在传入视图时将其添加到可变数组中,然后使用如下内容:

-(void) animateView:(UIView *)viewToAnimate{    

    [UIView animateWithDuration:0.5 animations:^{
        viewToAnimate.alpha = 0;
    }
                 completion:^(BOOL finished){
                     [_mutableArrayOfAnimationViews removeObject: viewToAnimate];
                     if ([_mutableArrayOfAnimationViews count] > 0) {
                         UIView *newAnimationView = [_mutableArrayOfAnimationViews objectAtIndex:0];
                         [self animateView: newAnimationView];
                     }
                 }];   
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {

    self.kvoToDoList insertObject:object atIndex:0];
    // not sure here what you need to remember in order to do the animation, let's say it's just the object
    [self doAnimations];
}

- (void)doAnimations {

    if (self.kvoToDoList.count == 0) return;
    id object = [self.kvoToDoList lastObject];  // FIFO since we insert at index 0
    [self.kvoToDoList removeLastObject];

    [UIView animateWithDuration:someDuration delay:0.0 options:someOptions animations:^{
        // do animations here based on object
    } completion:^(BOOL finished) {
        // call this recursively, but performSelector so we don't wind up the stack
        [self performSelector:@selector(doAnimations) withObject:nil afterDelay:0.0];
    }];
}

然后,您还可以在视图进入时检查数组是否已为空,如果是,则调用上述方法…

如何在进入时将进入的视图添加到可变数组中,然后使用如下方法:

-(void) animateView:(UIView *)viewToAnimate{    

    [UIView animateWithDuration:0.5 animations:^{
        viewToAnimate.alpha = 0;
    }
                 completion:^(BOOL finished){
                     [_mutableArrayOfAnimationViews removeObject: viewToAnimate];
                     if ([_mutableArrayOfAnimationViews count] > 0) {
                         UIView *newAnimationView = [_mutableArrayOfAnimationViews objectAtIndex:0];
                         [self animateView: newAnimationView];
                     }
                 }];   
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {

    self.kvoToDoList insertObject:object atIndex:0];
    // not sure here what you need to remember in order to do the animation, let's say it's just the object
    [self doAnimations];
}

- (void)doAnimations {

    if (self.kvoToDoList.count == 0) return;
    id object = [self.kvoToDoList lastObject];  // FIFO since we insert at index 0
    [self.kvoToDoList removeLastObject];

    [UIView animateWithDuration:someDuration delay:0.0 options:someOptions animations:^{
        // do animations here based on object
    } completion:^(BOOL finished) {
        // call this recursively, but performSelector so we don't wind up the stack
        [self performSelector:@selector(doAnimations) withObject:nil afterDelay:0.0];
    }];
}

然后,您还可以在视图进入时检查数组是否已为空,如果已为空,则调用上述方法…

创建一个可变数组,作为动画的kvoToDoList如何。在那里输入启动动画所需的任何信息(如触发kvo的对象)

然后,当观察到kvo时,将对象添加到阵列中并调用如下动画函数:

-(void) animateView:(UIView *)viewToAnimate{    

    [UIView animateWithDuration:0.5 animations:^{
        viewToAnimate.alpha = 0;
    }
                 completion:^(BOOL finished){
                     [_mutableArrayOfAnimationViews removeObject: viewToAnimate];
                     if ([_mutableArrayOfAnimationViews count] > 0) {
                         UIView *newAnimationView = [_mutableArrayOfAnimationViews objectAtIndex:0];
                         [self animateView: newAnimationView];
                     }
                 }];   
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {

    self.kvoToDoList insertObject:object atIndex:0];
    // not sure here what you need to remember in order to do the animation, let's say it's just the object
    [self doAnimations];
}

- (void)doAnimations {

    if (self.kvoToDoList.count == 0) return;
    id object = [self.kvoToDoList lastObject];  // FIFO since we insert at index 0
    [self.kvoToDoList removeLastObject];

    [UIView animateWithDuration:someDuration delay:0.0 options:someOptions animations:^{
        // do animations here based on object
    } completion:^(BOOL finished) {
        // call this recursively, but performSelector so we don't wind up the stack
        [self performSelector:@selector(doAnimations) withObject:nil afterDelay:0.0];
    }];
}

创建一个可变数组作为动画的kvoToDoList如何。在那里输入启动动画所需的任何信息(如触发kvo的对象)

然后,当观察到kvo时,将对象添加到阵列中并调用如下动画函数:

-(void) animateView:(UIView *)viewToAnimate{    

    [UIView animateWithDuration:0.5 animations:^{
        viewToAnimate.alpha = 0;
    }
                 completion:^(BOOL finished){
                     [_mutableArrayOfAnimationViews removeObject: viewToAnimate];
                     if ([_mutableArrayOfAnimationViews count] > 0) {
                         UIView *newAnimationView = [_mutableArrayOfAnimationViews objectAtIndex:0];
                         [self animateView: newAnimationView];
                     }
                 }];   
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {

    self.kvoToDoList insertObject:object atIndex:0];
    // not sure here what you need to remember in order to do the animation, let's say it's just the object
    [self doAnimations];
}

- (void)doAnimations {

    if (self.kvoToDoList.count == 0) return;
    id object = [self.kvoToDoList lastObject];  // FIFO since we insert at index 0
    [self.kvoToDoList removeLastObject];

    [UIView animateWithDuration:someDuration delay:0.0 options:someOptions animations:^{
        // do animations here based on object
    } completion:^(BOOL finished) {
        // call this recursively, but performSelector so we don't wind up the stack
        [self performSelector:@selector(doAnimations) withObject:nil afterDelay:0.0];
    }];
}

用一个好主意回答我自己的问题:
你认为executionQueue或executionBlock怎么样

我想,我将执行代码保存到一个块变量中,而一些动画正在进行。在动画完成块中,我查看是否存在有效的executionBlock

如果有,执行,如果没有,什么也不做


另外,当异步消息传入时,我需要保存要加载的块的动画状态。

用一个好主意回答我自己的问题:
你认为executionQueue或executionBlock怎么样

我想,我将执行代码保存到一个块变量中,而一些动画正在进行。在动画完成块中,我查看是否存在有效的executionBlock

如果有,执行,如果没有,什么也不做


另外,当异步消息传入时,我需要保存要加载的块的动画状态。

这不起作用,因为使用KVO时,会自动调用observer方法。啊,我忘了提到,KVO方法会像随机一样被调用,这取决于哪个数据首先进入;我只是省略了你需要解释的所有其他问题。不清楚是否要等待所有数据到达,然后执行Animation1,然后执行Animation2;或者,如果您想在每个动画的数据到达后立即启动动画,那就对了。我已经考虑过了,现在我明白了,你的意思。通过这些通知,我可以控制动画完成后必须执行的操作。在调用observe方法之后我要做的是:根据KVO方法中引入的新值,更改(插入/删除/更新)一个数组。我今天想到的是:我也观察了可变数组,并得到了很好的更改通知。有了这些通知,我想每次都启动动画。(我在概念上模仿UITableView,在scrollView中同时插入/删除/更新视图),但这不起作用,因为使用KVO会自动调用observer方法。啊,我忘了提到,KVO方法会像随机一样被调用,这取决于哪个数据首先进入;我只是省略了你需要解释的所有其他问题。不清楚是否要等待所有数据到达,然后执行Animation1,然后执行Animation2;或者,如果您想在每个动画的数据到达后立即启动动画,那就对了。我已经考虑过了,现在我明白了,你的意思。通过这些通知,我可以控制动画完成后必须执行的操作。在调用observe方法之后我要做的是:根据KVO方法中引入的新值,更改(插入/删除/更新)一个数组。我今天想到的是:我也观察了可变数组,并得到了很好的更改通知。有了这些通知,我想每次都启动动画。(我在概念上模仿UITableView,在scrollView中同时插入/删除/更新视图)+1同意。当我输入基本相同的想法时,没有看到这个负载。不过,我认为最好先执行选择器,然后再递归调用。+1同意。当我输入基本相同的想法时,没有看到这个负载。不过,我认为最好先执行选择器,然后再递归调用。这看起来不错。我想我试试这个。我认为另一个不错的选择是使用一个块并保存动作,以便在动画看起来不错的时候执行。我想我试试这个。我认为另一个不错的选择是使用块并保存动作,以便在动画结束后执行