Building a Custom Picker Component - Part 2

Episode #26 | 13 minutes | published on 07/26/2012
Subscribers Only
In this episode, I continue where I left of in episode 25. I add a nice animation to present & dismiss the picker, as well as a backdrop view that allows you to tap anywhere to cancel.

Links

Animating in & out

I found that using an animation with opposite curves looked best:

    // animating in...
    [UIView animateWithDuration:0.25 delay:0
                        options:UIViewAnimationCurveEaseIn
                     animations:^{
                        // ...
                     } completion:^(BOOL finished) {
                        // ...
                     }];

    
    // animating out...
    [UIView animateWithDuration:0.25 delay:0
                        options:UIViewAnimationCurveEaseOut
                     animations:^{
                        // ...
                     } completion:^(BOOL finished) {
                        // ...
                     }];

Adding the backdrop

- (UIView *)backdropView {
    UIView *backdropView = [[UIView alloc] initWithFrame:self.bounds];
    backdropView.backgroundColor = [UIColor colorWithWhite:0 alpha:BSMODALPICKER_BACKDROP_OPACITY];
    backdropView.alpha = 0;
    
    UIGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onBackdropTap:)];
    [backdropView addGestureRecognizer:tapRecognizer];
    return backdropView;
}
- (void)presentInView:(UIView *)view withBlock:(BSModalPickerViewCallback)callback {
    self.frame = view.bounds;
    self.callbackBlock = callback;
    
    [_panel removeFromSuperview];
    [_backdropView removeFromSuperview];
    
    _panel = [[UIView alloc] initWithFrame:CGRectMake(0, self.bounds.size.height - BSMODALPICKER_PANEL_HEIGHT, self.bounds.size.width, BSMODALPICKER_PANEL_HEIGHT)];
    _picker = [self picker];
    _toolbar = [self toolbar];
    
    _backdropView = [self backdropView];
    [self addSubview:_backdropView];

    [_panel addSubview:_picker];
    [_panel addSubview:_toolbar];
    
    [self addSubview:_panel];
    [view addSubview:self];
    
    CGRect oldFrame = _panel.frame;
    CGRect newFrame = _panel.frame;
    newFrame.origin.y += newFrame.size.height;
    _panel.frame = newFrame;
    
    [UIView animateWithDuration:0.25 delay:0
                        options:UIViewAnimationCurveEaseOut
                     animations:^{
                         _panel.frame = oldFrame;
                         _backdropView.alpha = 1;
                     } completion:^(BOOL finished) {
                         
                     }];
}

- (void)dismissPicker {
    [UIView animateWithDuration:0.25 delay:0
                        options:UIViewAnimationCurveEaseOut
                     animations:^{
                         CGRect newFrame = _panel.frame;
                         newFrame.origin.y += _panel.frame.size.height;
                         _panel.frame = newFrame;
                         _backdropView.alpha = 0;
                     } completion:^(BOOL finished) {
                         [_panel removeFromSuperview];
                         _panel = nil;
                         
                         [_backdropView removeFromSuperview];
                         _backdropView = nil;
                         
                         [self removeFromSuperview];
                     }];
}

Finally, we just need to cancel the dialog if the user taps on the backdrop:

- (void)onBackdropTap:(id)sender {
    [self onCancel:sender];
}
blog comments powered by Disqus
Back