ReactiveCocoa / ReactiveViewModel

Model-View-ViewModel, using ReactiveCocoa
MIT License
1.96k stars 259 forks source link

MVVM and animation callbacks, executing one view update after another #15

Closed bobspryn closed 10 years ago

bobspryn commented 10 years ago

I'm trying to determine a clean way to do the following with MVVM, with the approach that changes to the view should always be triggered by changes to the viewModel. Basically it's an action that provides information that I need to use in the second of two chained animations.

  1. Looking at a table list of items.
  2. Tap one to go into a carousel-like modal where you can page through full screen versions horizontally.
  3. Tap a button on the card indicating you would like to select that one
  4. Close the carousel with animation and then ->
  5. Animate the row you selected in the cards up to the top.

So right now I catch the tap, hide the modal with an animation, and in the completion handler for that animation I update the viewmodel, which causes the next animation step to happen (animating the row to the top).

[[RACObserve(self, optionDetailContainerViewController.cardButtonTappedSignal) switchToLatest]
    subscribeNext:^(RACTuple *values) {
        @strongify(self);
        NSNumber *index = values.first;
        NSNumber *type = values.second;
        if (type.integerValue == TCOptionDetailTypeUse) {
            id object = self.viewModel.searchResults[index.integerValue];
            if ([self.viewModel.selectedOptions containsObject:object]) {
                return;
            }
        }
        [self removeOptionDetailCardsWithCompletionHandler:^{
           @strongify(self);
            if (type.integerValue == TCOptionDetailTypeDelete) {
                [self.viewModel deleteSelectedOption:index.integerValue];
            } else {
                [self.viewModel useThirdPartyObject:self.viewModel.searchResults[index.integerValue]];
            }
        }];
    }];

Really what should happen is tapping the button updates the view model to indicate that the modal should close, and then somehow at the end of that animation, the view model is updated again to reflect the next step with the information (index, type) that gathered from the button tap.

I know this probably isn't spelled out really well, but my brain is a little foggy right now.

jspahrsummers commented 10 years ago

Sorry, I've been pretty busy and only just now had an opportunity to read this in detail.

I think I vaguely understand your use case, but what are the concrete questions you have about this design?

bobspryn commented 10 years ago

Really I guess I'm looking for a pattern here. Animation callbacks make for some difficulty in managing the view from changes in the view model when you need to wait for an animation to complete before doing something else in the view. I think it's just a rough edge of MVVM on Cocoa touch.

jspahrsummers commented 10 years ago

I do this at least once in the GroceryList app.

Just do what feels right, and try to stick to the principles of MVVM and FRP. There's not always a One True Way™ for every problem.

bobspryn commented 10 years ago

Yup I get that. Just didn't know if someone else already had a great idea. I'll look through GroceryList again to spot it. Thanks!