5

How can I detect when the user taps the selection indicator in a UIDatePicker?

Without this the user has to scroll to some other date and then back again to pick the date which is displayed under the selection indicator when the date picker slides up.

Thanks a lot,
Stine

The date picker is scrolled to current date when sliding up

UPDATE: This is the only solution I could come up with myself:

UIDatePicker *aDatePicker = [[UIDatePicker alloc] init];
self.datePicker = aDatePicker;
[aDatePicker release];
[self.datePicker addTarget:self action:@selector(datePicked:) forControlEvents:UIControlEventValueChanged];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(datePicked:)];    
[self.datePicker addGestureRecognizer:tap];
[tap release];

Which means that datePicked will be called twice when the user actually rotates the wheel.

UPDATE: The above mentioned solution does not work for UIPickerViews though. I do not know how to achieve the wanted behavior in those cases.

Stine
  • 1,605
  • 5
  • 23
  • 44
  • Have the feeling it cannot be done :( Soooo annoying! – Stine Sep 17 '11 at 14:39
  • 2
    I don't really get why you'd want this. Just because the `UIControlEventValueChanged` action isn't fired for the date that is set initially? Why don't you just use the date picker's `date` property to get the initial selection? Or am I missing the point entirely? – omz Sep 17 '11 at 14:55
  • +1, I totally agree with @omz – Youssef Sep 17 '11 at 15:18
  • I am aware of how to read the currently selected date but I am only interested in doing so if the user is actually picking that date. – Stine Sep 17 '11 at 15:20
  • 1
    Here is the answer http://stackoverflow.com/questions/22319427/ios-7-1-uitapgesture-not-working-with-uipickerview – zvjerka24 Apr 24 '15 at 07:01

3 Answers3

5

You can do some tweak in this way:-

Conform delegate <UIGestureRecognizerDelegate>in your .h file

UITapGestureRecognizer* gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(pickerViewTapGestureRecognized:)];
[yourDatePicker addGestureRecognizer:gestureRecognizer];
gestureRecognizer.delegate=self;
gestureRecognizer.numberOfTapsRequired=2;//Whenever you do double tap it will called. So allow user to do double tap on selected date.

//Below is the Delegate method

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    return YES;
}

//Below method will trigger when do the double tap

-(void)pickerViewTapGestureRecognized:(UITapGestureRecognizer*)recognizer
{
   UIDatePicker *datePicker=(UIDatePicker*)[[recognizer view] viewWithTag:101];
   NSLog(@"datePicker=%@", datePicker.date);
 }
Hussain Shabbir
  • 14,801
  • 5
  • 40
  • 56
2

Try this code:

UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(pickerViewTapped:)];

[recognizer setNumberOfTapsRequired:2];
[recognizer setCancelsTouchesInView:NO];
[recognizer setDelaysTouchesEnded:NO];
[recognizer setDelaysTouchesBegan:NO];

[self.answerPicker addGestureRecognizer:recognizer];

// ....

- (IBAction)pickerViewTapped:(UITapGestureRecognizer *)sender {
    CGPoint coord = [sender locationInView:self.answerPicker];
    if(coord.y <= 126 && coord.y >= 90) {
        //do something
    }
}
David Rönnqvist
  • 56,267
  • 18
  • 167
  • 205
Splash
  • 71
  • 1
  • 5
1

This is an old question but here's what I did in order to grab the selection bar rect on the UIDatePicker. With this, you could just add a button/view with a gesture recognizer to detect taps. It's a bit of a hack but it seems to be working well in iOS6 and iOS7.

+ (CGRect)getSelectionBarRectFromPicker:(UIDatePicker *)picker
{
    int counter = 0;
    CGRect selectionBarRect;
    for(UIView *datePickerView in picker.subviews){
        for(UIView *subview in datePickerView.subviews){
            if([[[UIDevice currentDevice] systemVersion] floatValue] < 7.0){
                if([NSStringFromClass([subview class]) isEqualToString:@"_UIPickerViewSelectionBar"]){
                    if(counter == 0){
                        selectionBarRect.origin = subview.frame.origin;
                        selectionBarRect.size.height = subview.frame.size.height;
                    }
                    selectionBarRect.size.width += subview.frame.size.width;
                    counter++;
                }
            } else {
                if(subview.frame.size.height < 1){
                    if(counter == 0){
                        selectionBarRect.origin = subview.frame.origin;
                        selectionBarRect.size.width = subview.frame.size.width;
                    } else {
                        selectionBarRect.size.height = subview.frame.origin.y - selectionBarRect.origin.y;
                    }
                    counter++;
                }
            }
        }
    }
    return selectionBarRect;
}
unsunghero
  • 971
  • 1
  • 10
  • 22