16

I have searched the entire internet (maybe I am exaggerating a little) for a tutorial on how to put a DatePicker into a UIPopover and display that in an iPad application. I have tried creating a viewcontroller, placing the datepicker in the view controller and then:

self.popover = [[UIPopoverController alloc] initWithContentViewController:sa];

(sa is the name of the viewcontroller i created), but this doesn't work, and the app crashes. Can anyone help?

Robotnik
  • 3,643
  • 3
  • 31
  • 49
Prajoth
  • 900
  • 3
  • 12
  • 26

2 Answers2

60

Try with below code. It will work fine:

Objective-C

- (IBAction)showDatePicker:(UIButton *)sender {
    UIDatePicker *datePicker = [[UIDatePicker alloc]init];//Date picker
    datePicker.frame = CGRectMake(0, 0, 320, 216);
    datePicker.datePickerMode = UIDatePickerModeDateAndTime;
    [datePicker setMinuteInterval:5];
    [datePicker addTarget:self action:@selector(dateChanged:) forControlEvents:UIControlEventValueChanged];//need to implement this method in same class


    UIView *popoverView = [[UIView alloc] init];   //view
    popoverView.backgroundColor = [UIColor clearColor];
    [popoverView addSubview:datePicker];
    // here you can add tool bar with done and cancel buttons if required

    UIViewController *popoverViewController = [[UIViewController alloc] init];
    popoverViewController.view = datePicker;
    popoverViewController.view.frame = CGRectMake(0, 0, 320, 216);
    popoverViewController.modalPresentationStyle = UIModalPresentationPopover;
    popoverViewController.preferredContentSize = CGSizeMake(320, 216);
    popoverViewController.popoverPresentationController.sourceView = sender; // source button
    popoverViewController.popoverPresentationController.sourceRect = sender.bounds; // source button bounds
    //popoverViewController.popoverPresentationController.delegate = self;
    [self presentViewController:popoverViewController animated:YES completion:nil];
}
- (void)dateChanged:(UIDatePicker *)datePicker {
    NSLog(@"DATE :: %@", datePicker.date);
}

Swift 4.2

 @IBAction func showDatePicker(_ sender: UIButton) {
    let datePicker = UIDatePicker()//Date picker
    let datePickerSize = CGSize(width: 320, height: 216) //Date picker size
    datePicker.frame = CGRect(x: 0, y: 0, width: datePickerSize.width, height: datePickerSize.height)
    datePicker.datePickerMode = .dateAndTime
    datePicker.minuteInterval = 5
    datePicker.addTarget(self, action: #selector(dateChanged(_:)), for: .valueChanged)

    let popoverView = UIView()
    popoverView.backgroundColor = UIColor.clear
    popoverView.addSubview(datePicker)
    // here you can add tool bar with done and cancel buttons if required

    let popoverViewController = UIViewController()
    popoverViewController.view = popoverView
    popoverViewController.view.frame = CGRect(x: 0, y: 0, width: datePickerSize.width, height: datePickerSize.height)
    popoverViewController.modalPresentationStyle = .popover
    popoverViewController.preferredContentSize = datePickerSize
    popoverViewController.popoverPresentationController?.sourceView = sender // source button
    popoverViewController.popoverPresentationController?.sourceRect = sender.bounds // source button bounds
    popoverViewController.popoverPresentationController?.delegate = self // to handle popover delegate methods 
    self.present(popoverViewController, animated: true, completion: nil)

    }
    @objc func dateChanged(_ datePicker: UIDatePicker) {
        print("DATE :: \(datePicker.date)")
    }

Same code will work iPhone also if you implement below delegate respective in view controller

extension YourViewController : UIPopoverPresentationControllerDelegate {
    func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
        // Force popover style
        return UIModalPresentationStyle.none
    }
}
Narayana Rao Routhu
  • 6,303
  • 27
  • 42
  • 3
    in result method you can get date using datepicker.date – Narayana Rao Routhu Sep 12 '11 at 04:45
  • 1
    Sorry for the noob question, but how do you set up the "result" method without a delegate method? Till now, I have only created UIPopovers from existing viewcontrollers, so I set up a delegate method to pass the data. But how would I extract the data using the selector(Result) method? Thanks for your help! – Prajoth Sep 13 '11 at 02:23
  • @Prajoth you wouldn't need to set a delegate for the date picker. If you look at the line call with [datePicker addTarget...]; the result is IBAction that view controller itself has. – Phong Le Dec 10 '13 at 21:55
  • @JugalKBalara check my updated code working properly for iOS8 – Narayana Rao Routhu Dec 16 '15 at 15:23
  • 1
    This is great, Narayana. Just tested in Xcode 9 on the iPad. – Alex Zavatone Oct 20 '17 at 01:04
3

Now since you have tagged iPhone It can clearly be assumed that you are trying to use UIPopoverController in iPhone But UIPopoverController is available only for iPad. So it is resulting in a crash since iPhone doesn't recognize that controller.

Suresh Varma
  • 9,750
  • 1
  • 60
  • 91
  • 4
    OP originally tagged iPhone, however his question states iPad, and has accepted an answer that (as you mention) would only work on an iPad. I have re-tagged this question as iPad to avoid further confusion – Robotnik Sep 11 '12 at 05:43
  • For further reading on "`UIPopoverController` is available only for `iPad`": http://marksands.github.io/2014/05/27/how-apple-cheats.html – Bruno Koga Jul 17 '14 at 18:21