New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RACSignal with Animation #1248

Closed
RuiAAPeres opened this Issue Apr 14, 2014 · 10 comments

Comments

Projects
None yet
3 participants
@RuiAAPeres
Member

RuiAAPeres commented Apr 14, 2014

As described by this brief conversation with @kastiglione here, I would like to be able to enqueue animations in the form of:

    [UIView animateWithDuration:.3f animations:^{
    } completion:^(BOOL finished) {
    }];

So a second animation, would have to wait for the first one to complete. In this scenario I don't know when the animations might come so:

Animation1 -> after .2f -> Animation2 -> after 5 seconds -> End

If each animations takes .3f I would like that Animation2 wait .1fsecond (so Animation1) ends. How could I achieve this with Reactive Cocoa?

@alanjrogers alanjrogers changed the title from RACSinal with Animation to RACSignal with Animation Apr 14, 2014

@kastiglione

This comment has been minimized.

Show comment
Hide comment
@kastiglione

kastiglione Apr 15, 2014

Member

Check out ReactiveCocoaLayout, which defines a category on RACSignal for doing animations. In particular, check out the header documentation for -animateWithDuration:curve: and -animatedSignalsWithDuration:curve:.

To implement the serial animations, you'll need a signal that sends the values of the properties you want animated, like size, position, color, etc. This signal can send at the appropriate times for animation or queuing, or you'll need a separate signal that controls the timing of the property signal, via -sample: or similar.

In the simplest case, you have a signal that sends colors at the exact time it should be animated or queued for animation, then you can do:

// Or, -animateWithDuration:curve: for a specific animation curve.
RAC(self.view, backgroundColor) = [colorsSignal animateWithDuration:0.3f];

Internally, this simply calls [[colorsSignal animatedSignalsWithDuration:0.3f] concat], which means the first animation signal has to complete before the second one is subscribed to and thus begun.

This answer feels light on details, but at least it gives you a starting point for now.

Member

kastiglione commented Apr 15, 2014

Check out ReactiveCocoaLayout, which defines a category on RACSignal for doing animations. In particular, check out the header documentation for -animateWithDuration:curve: and -animatedSignalsWithDuration:curve:.

To implement the serial animations, you'll need a signal that sends the values of the properties you want animated, like size, position, color, etc. This signal can send at the appropriate times for animation or queuing, or you'll need a separate signal that controls the timing of the property signal, via -sample: or similar.

In the simplest case, you have a signal that sends colors at the exact time it should be animated or queued for animation, then you can do:

// Or, -animateWithDuration:curve: for a specific animation curve.
RAC(self.view, backgroundColor) = [colorsSignal animateWithDuration:0.3f];

Internally, this simply calls [[colorsSignal animatedSignalsWithDuration:0.3f] concat], which means the first animation signal has to complete before the second one is subscribed to and thus begun.

This answer feels light on details, but at least it gives you a starting point for now.

@RuiAAPeres

This comment has been minimized.

Show comment
Hide comment
@RuiAAPeres

RuiAAPeres Apr 15, 2014

Member

@kastiglione it looks quite interesting, my issue is that I am creating a 3rd party lib, using another dependency in order to create it, might not be worth. Still, for other projects, I will consider using this.

Member

RuiAAPeres commented Apr 15, 2014

@kastiglione it looks quite interesting, my issue is that I am creating a 3rd party lib, using another dependency in order to create it, might not be worth. Still, for other projects, I will consider using this.

@kastiglione

This comment has been minimized.

Show comment
Hide comment
@kastiglione

kastiglione Apr 15, 2014

Member

If you peel away enough, it can become a fairly small implementation. If you're comfortable with how it works, you could easily add a simple implementation to your library:

- (RACSignal *)animateWithDuration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options {
    return [[self
        map:^(id value) {
            return [RACSignal createSignal:^ id (id<RACSubscriber> subscriber) {
                [UIView animateWithDuration:duration delay:0 options:options animations:^{
                    [subscriber sendNext:value];
                } completion:^(BOOL finished) {
                    [subscriber sendCompleted];
                }];

                return nil;
            }];
        }]
        concat];
}
Member

kastiglione commented Apr 15, 2014

If you peel away enough, it can become a fairly small implementation. If you're comfortable with how it works, you could easily add a simple implementation to your library:

- (RACSignal *)animateWithDuration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options {
    return [[self
        map:^(id value) {
            return [RACSignal createSignal:^ id (id<RACSubscriber> subscriber) {
                [UIView animateWithDuration:duration delay:0 options:options animations:^{
                    [subscriber sendNext:value];
                } completion:^(BOOL finished) {
                    [subscriber sendCompleted];
                }];

                return nil;
            }];
        }]
        concat];
}
@RuiAAPeres

This comment has been minimized.

Show comment
Hide comment
@RuiAAPeres

RuiAAPeres Apr 15, 2014

Member

@kastiglione the initial self map:, this self would be a signal, but what is the point?

Member

RuiAAPeres commented Apr 15, 2014

@kastiglione the initial self map:, this self would be a signal, but what is the point?

@notxcain

This comment has been minimized.

Show comment
Hide comment
@notxcain

notxcain Apr 15, 2014

The point is that it would be a signal sending values for a property you want to animate.

notxcain commented Apr 15, 2014

The point is that it would be a signal sending values for a property you want to animate.

@RuiAAPeres

This comment has been minimized.

Show comment
Hide comment
@RuiAAPeres

RuiAAPeres Apr 15, 2014

Member

@denis-mikhaylov when I mean what is the point, I got it wrong. What I mean, is how to use it. Is this method inside a RACSignal subclass?

Member

RuiAAPeres commented Apr 15, 2014

@denis-mikhaylov when I mean what is the point, I got it wrong. What I mean, is how to use it. Is this method inside a RACSignal subclass?

@notxcain

This comment has been minimized.

Show comment
Hide comment
@notxcain

notxcain Apr 15, 2014

It is inside category on RACSignal

notxcain commented Apr 15, 2014

It is inside category on RACSignal

@RuiAAPeres

This comment has been minimized.

Show comment
Hide comment
@RuiAAPeres

RuiAAPeres Apr 15, 2014

Member

@denis-mikhaylov I see, still I fail to see how to use it. I will have a look at the demos.

Member

RuiAAPeres commented Apr 15, 2014

@denis-mikhaylov I see, still I fail to see how to use it. I will have a look at the demos.

@notxcain

This comment has been minimized.

Show comment
Hide comment
@notxcain

notxcain Apr 15, 2014

RACSignal *alphas = ...; //Some signal sending `NSNumber`s
RAC(view, alpha) =  [alphas animateWithDuration:0.1 options:kNilOptions];

notxcain commented Apr 15, 2014

RACSignal *alphas = ...; //Some signal sending `NSNumber`s
RAC(view, alpha) =  [alphas animateWithDuration:0.1 options:kNilOptions];
@RuiAAPeres

This comment has been minimized.

Show comment
Hide comment
@RuiAAPeres

RuiAAPeres Apr 15, 2014

Member

@denis-mikhaylov I was failing to see from where the signal was coming. Thanks!

Member

RuiAAPeres commented Apr 15, 2014

@denis-mikhaylov I was failing to see from where the signal was coming. Thanks!

@RuiAAPeres RuiAAPeres closed this Apr 15, 2014

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment