Search code examples
iosipaduipopovercontrolleruidatepicker

UIDatePicker in UIPopover


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?


Solution

  • 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
        }
    }