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 Episode source code Animating in & out I found that using an animation with opposite curves looked best: // animating in... [UIView animateWithDuration:0.25 delay:0 options:<b>UIViewAnimationCurveEaseIn</b> animations:^{ // ... } completion:^(BOOL finished) { // ... }]; // animating out... [UIView animateWithDuration:0.25 delay:0 options:<b>UIViewAnimationCurveEaseOut</b> 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]; <b>[_backdropView removeFromSuperview];</b> _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]; <b>_backdropView = [self backdropView]; [self addSubview:_backdropView];</b> [_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; <b>_backdropView.alpha = 1;</b> } 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; <b>_backdropView.alpha = 0;</b> } completion:^(BOOL finished) { [_panel removeFromSuperview]; _panel = nil; <b>[_backdropView removeFromSuperview]; _backdropView = nil;</b> [self removeFromSuperview]; }]; } Finally, we just need to cancel the dialog if the user taps on the backdrop: - (void)onBackdropTap:(id)sender { [self onCancel:sender]; }