Kuc Ku
Kuc Ku

Reputation: 51

Xcode UIDatePicker dismiss when tap outside

In my project, I have a UIButton and a UIView, and in the view I add UIDatePicker. When I hit the button, date picker opens. How can I dismiss the date picker?

Upvotes: 1

Views: 1816

Answers (2)

Anindya Sengupta
Anindya Sengupta

Reputation: 2579

I hope the following code will solve your problems. This dismisses the date picker both on "Done" button tap as well as tapping outside on the Overlay view:

#import "ViewController.h"

#define kOverlayviewTag     1
#define kDatepickerTag      2
#define kToolbarTag         3

#define kToolbarHeight      44
#define kDatepickerHeight   216
#define kGenericWidth       320
#define kInvisibleAlpha     0
#define kTransparentAlpha   0.5
#define kOpaqueAlpha        1


@interface ViewController ()

-(IBAction)buttonTapped:(id)sender;

@end

@implementation ViewController

-(void)buttonTapped:(id)sender
{
    if ([self.view viewWithTag:kOverlayviewTag]) {
        return;
    }

    UIView *overlayView = [[UIView alloc] initWithFrame:self.view.bounds];
    overlayView.alpha = kInvisibleAlpha;
    overlayView.backgroundColor = [UIColor blackColor];
    overlayView.tag = kOverlayviewTag;

    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissDatePicker:)];
    [overlayView addGestureRecognizer:tapGesture];
    [self.view addSubview:overlayView];

    UIDatePicker *datePicker = [[UIDatePicker alloc] initWithFrame:CGRectMake(0, self.view.bounds.size.height+kToolbarHeight, kGenericWidth, kDatepickerHeight)];
    datePicker.tag = kDatepickerTag;
    [datePicker addTarget:self action:@selector(changeDate:) forControlEvents:UIControlEventValueChanged];
    [self.view addSubview:datePicker];

    UIToolbar *toolBar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, self.view.bounds.size.height, kGenericWidth, kToolbarHeight)];
    toolBar.tag = kToolbarTag;
    toolBar.barStyle = UIBarStyleBlackTranslucent;
    UIBarButtonItem *spacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
    UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(dismissDatePicker:)];
    [toolBar setItems:[NSArray arrayWithObjects:spacer, doneButton, nil]];
    [self.view addSubview:toolBar];


    CGRect toolbarTargetFrame = CGRectMake(0, self.view.bounds.size.height-kDatepickerHeight-kToolbarHeight, kGenericWidth, kToolbarHeight);
    CGRect datePickerTargetFrame = CGRectMake(0, self.view.bounds.size.height-kDatepickerHeight, kGenericWidth, kDatepickerHeight);
    [UIView animateWithDuration:0.5 animations:^{
        toolBar.frame = toolbarTargetFrame;
        datePicker.frame = datePickerTargetFrame;
        overlayView.alpha = kTransparentAlpha;
    }];


}

- (void)dismissDatePicker:(id)sender {
    CGRect toolbarTargetFrame = CGRectMake(0, self.view.bounds.size.height, kGenericWidth, kToolbarHeight);
    CGRect datePickerTargetFrame = CGRectMake(0, self.view.bounds.size.height+kToolbarHeight, kGenericWidth, kDatepickerHeight);

    [UIView animateWithDuration:0.5 animations:^{
        [self.view viewWithTag:kOverlayviewTag].alpha = kInvisibleAlpha;
        [self.view viewWithTag:kDatepickerTag].frame = datePickerTargetFrame;
        [self.view viewWithTag:kToolbarTag].frame = toolbarTargetFrame;
    } completion:^(BOOL finished) {
        [[self.view viewWithTag:kOverlayviewTag] removeFromSuperview];
        [[self.view viewWithTag:kToolbarTag] removeFromSuperview];
        [[self.view viewWithTag:kDatepickerTag] removeFromSuperview];
    }];
}


- (void)changeDate:(UIDatePicker *)sender {
    NSLog(@"New Date: %@", sender.date);
}

Updated with blocks for UIAnimation from UIDatePicker pop up after UIButton is pressed

Upvotes: 1

crzyonez777
crzyonez777

Reputation: 1807

What I usually do is adding a toolbar on the top of UIDatePicker. In the toolbar, I add a button that calls the method to close the date picker when it pressed.

You can also add an UIView instance under the UIDatePicker instance, and implement touchesBegan method to close the UIDatePicker. That way, when an user taps outside the datepicker, it calls touchesBegan method that close the datepicker.

Upvotes: 0

Related Questions