从回调地狱逃脱!使用PromiseKit(Promise的权威库)巧妙地实现复杂的iOS动画! !! !!


通过mixiappwchr

在诸如iOS之类的应用程序开发中,异步处理是必不可少的。网络通信和思想处理有许多实现方式,但是老实说,大量的回调会使前景变得非常糟糕。

然后,您将要在iOS上使用Promise进行编写,但是Promise Kit如今变得很流行。

这次,我将解释如何使使用此库的动画编写更加容易。

PromiseKit

PromiseKit

我最喜欢这个库的地方是方法链非常容易理解。

1
2
3
4
5
6
7
dispatch_promise(^{
    return md5(email);
}).then(^(NSString *md5){
    return [NSURLConnection GET:@"http://gravatar.com/%@", md5];
}).then(^(UIImage *gravatarImage){
    self.imageView.image = gravatarImage;
});

例如,如果将其与可用于Promise的库螺栓进行比较,则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
PFQuery *query = [PFQuery queryWithClassName:@"Student"];
[query orderByDescending:@"gpa"];
[[[[[self findAsync:query] continueWithSuccessBlock:^id(BFTask *task) {
  NSArray *students = task.result;
  PFObject *valedictorian = [students objectAtIndex:0];
  [valedictorian setObject:@YES forKey:@"valedictorian"];
  return [self saveAsync:valedictorian];
}] continueWithSuccessBlock:^id(BFTask *task) {
  PFObject *valedictorian = task.result;
  return [self findAsync:query];
}] continueWithSuccessBlock:^id(BFTask *task) {
  NSArray *students = task.result;
  PFObject *salutatorian = [students objectAtIndex:1];
  [salutatorian setObject:@YES forKey:@"salutatorian"];
  return [self saveAsync:salutatorian];
}] continueWithSuccessBlock:^id(BFTask *task) {
  // Everything is done!
  return nil;
}];

即使为此我想清楚地写

和Promise,我也不会陷入麻烦的地狱,因为[]已满。
以前有一些Promise / Defferd,但是在此区域仅描述了一些库,但是由于PromiseKit已经清除了这一点,所以感觉好像我要使用的库终于问世了。
随着Swift的到来,这里的问题可能首先消失了,但是PromiseKit也在促进对Swift的支持,因此从现在开始引入它不会有什么坏处。

用PromiseKit编写动画

就个人而言,最近最麻烦的事情是我经常在各个地方使用复杂的动画,但是当同时编写多个动画时

例如,如果您要编写动画使View跳动,请
UIView animateKeyframesWithDuration实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 self.target.transform = CGAffineTransformMakeTranslation(0, -300);
    [UIView promiseWithDuration:self.duration/4 delay:self.delay options:0 animations:^{
        // End
        self.target.transform = CGAffineTransformMakeTranslation(0, -10);
    } completion:^(BOOL finished) {
        [UIView promiseWithDuration:self.duration/4 delay:0 options:0 animations:^{
            // End
            self.target.transform = CGAffineTransformMakeTranslation(0, 5);
        } completion:^(BOOL finished) {
            [UIView promiseWithDuration:self.duration/4 delay:0 options:0 animations:^{
                // End
                self.target.transform = CGAffineTransformMakeTranslation(0, -2);
            } completion:^(BOOL finished) {
                [UIView animateKeyframesWithDuration:self.duration/4 delay:0 options:0 animations:^{
                    // End
                    self.target.transform = CGAffineTransformMakeTranslation(0, 0);
                } completion:^(BOOL finished) {
                     [self next];
                }];
            }];
        }];
    }];

大分县的压痕将是惊人的。

我一直在等待Promise库的最终版本来对此进行改进,但是随着Promise Kit的出现,我终于可以对其进行改进。

因为没有围绕动画的实现,所以我实现了它并将其合并到主体中。

您仍然可以实现它。

通过此修复程序使用PromiseKit,可以编写如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 // 3つのラベルを画面外から順番に移動するアニメーション
 self.label1.frame.origin.y = -100;
 self.label2.frame.origin.y = -100;
 self.label3.frame.origin.y = -100;

 __weak typeof(self) weakSelf = self;
 dispatch_promise_on(dispatch_get_main_queue(),^{
        return [UIView promiseWithDuration:0.2
                                         animations:^{
           weakSelf.label1.frame.origin.y = 100;

        }];
  }).then(^(BOOL finished){
        return [UIView promiseWithDuration:0.2 animations:^{
             weakSelf.label3.frame.origin.y = 200;

        }];
  }).then(^(BOOL finished){
        return [UIView promiseWithDuration:0.2 animations:^{
            weakSelf.label3.frame.origin.y = 300;

        }];  
});

怎么样?您可以编写UIAnimation而不会使缩进令人恐惧。

UIView动画我们已经添加了一种将XXXX方法转化为Promise的方法,因此您应该能够以相同的方式做出Promise。

PromiseKit很容易像这样扩展实现本身,因此很容易为其他库创建Promises。

请尝试使用它