web-dev-qa-db-fra.com

UIDatePicker apparaît après avoir appuyé sur UIButton

Comment puis-je faire apparaître un UIDatePicker (animé) après avoir appuyé sur un bouton UIB, puis le refermer une fois la date sélectionnée? C'est sur l'iPhone.

31
joshim5
canihazcode?

Oui monsieur. Merci de m'aider à tergiverser.

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

- (void)removeViews:(id)object {
 [[self.view viewWithTag:9] removeFromSuperview];
 [[self.view viewWithTag:10] removeFromSuperview];
 [[self.view viewWithTag:11] removeFromSuperview];
}

- (void)dismissDatePicker:(id)sender {
 CGRect toolbarTargetFrame = CGRectMake(0, self.view.bounds.size.height, 320, 44);
 CGRect datePickerTargetFrame = CGRectMake(0, self.view.bounds.size.height+44, 320, 216);
 [UIView beginAnimations:@"MoveOut" context:nil];
 [self.view viewWithTag:9].alpha = 0;
 [self.view viewWithTag:10].frame = datePickerTargetFrame;
 [self.view viewWithTag:11].frame = toolbarTargetFrame;
 [UIView setAnimationDelegate:self];
 [UIView setAnimationDidStopSelector:@selector(removeViews:)];
 [UIView commitAnimations];
}

- (IBAction)callDP:(id)sender {
 if ([self.view viewWithTag:9]) {
  return;
 }
 CGRect toolbarTargetFrame = CGRectMake(0, self.view.bounds.size.height-216-44, 320, 44);
 CGRect datePickerTargetFrame = CGRectMake(0, self.view.bounds.size.height-216, 320, 216);

 UIView *darkView = [[[UIView alloc] initWithFrame:self.view.bounds] autorelease];
 darkView.alpha = 0;
 darkView.backgroundColor = [UIColor blackColor];
 darkView.tag = 9;
 UITapGestureRecognizer *tapGesture = [[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissDatePicker:)] autorelease];
 [darkView addGestureRecognizer:tapGesture];
 [self.view addSubview:darkView];

 UIDatePicker *datePicker = [[[UIDatePicker alloc] initWithFrame:CGRectMake(0, self.view.bounds.size.height+44, 320, 216)] autorelease];
 datePicker.tag = 10;
 [datePicker addTarget:self action:@selector(changeDate:) forControlEvents:UIControlEventValueChanged];
 [self.view addSubview:datePicker];

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

 [UIView beginAnimations:@"MoveIn" context:nil];
 toolBar.frame = toolbarTargetFrame;
 datePicker.frame = datePickerTargetFrame;
 darkView.alpha = 0.5;
 [UIView commitAnimations];
}
98
Matthias Bauch

Je proposerais ce qui suit (bon pour iOS 3.2 ou mieux).

  1. Créez un champ de texte.
  2. Attribuez au champ de texte un inputView qui est un UIDateTimerPicker.
  3. Lorsque le bouton est cliqué, envoyez un événement "devenirFirstResponder" - cela fera glisser le sélecteur de date du bas pour vous ...
  4. À mon humble avis, la meilleure façon de fermer le sélecteur n'est pas lorsqu'une date est choisie (car cela peut la fermer même si nous recherchons la bonne date/heure) - mais attachez un bouton "Terminé" ou "Sélectionner" comme accessoire au clavier.

Ci-dessous est un code pour montrer les étapes 2-4: (J'espère que je n'ai rien oublié dans le processus de copier/coller ...

1 + 3 Créer UIDateTimePicker en tant que vue de saisie de texte et y attacher une barre d'outils avec le bouton "Terminé" ...

    // create a UIPicker view as a custom keyboard view
    UIPickerView* pickerView = [[UIPickerView alloc] init];
    [pickerView sizeToFit];
    pickerView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
    pickerView.delegate = self;
    pickerView.dataSource = self;
    pickerView.showsSelectionIndicator = YES;

_textField.inputView = pickerView; // _textField must be an instance variable, as you'll need it...

// create a done view + done button, attach to it a doneClicked action, and place it in a toolbar as an accessory input view...
    // Prepare done button
    UIToolbar* keyboardDoneButtonView = [[UIToolbar alloc] init];
    keyboardDoneButtonView.barStyle = UIBarStyleBlack;
    keyboardDoneButtonView.translucent = YES;
    keyboardDoneButtonView.tintColor = nil;
    [keyboardDoneButtonView sizeToFit];

    UIBarButtonItem* doneButton = [[[UIBarButtonItem alloc] initWithTitle:@"Done"
                    style:UIBarButtonItemStyleBordered target:self
                     action:@selector(doneClicked:)] autorelease];
    [_keyboardDoneButtonView setItems:[NSArray arrayWithObjects:doneButton, nil]];

     // Plug the keyboardDoneButtonView into the text field...
        _textField.inputAccessoryView = keyboardDoneButtonView;

// When the setDate button is clicked, call:

    - (void)setDateClicked:(id)sender {
       [_textField becomeFirstResponder]; 
    }

    - (void)doneClicked:(id)sender {
    // Write out the date...
     [_textField resignFirstResponder];
    }

Bonne chance...

35
Reuven

Voici une version Swift (1.2) du code de @ Reuven

class ViewController : UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
    @IBOutlet var pickerTextField : UITextField!
    var picker : UIPickerView!

    override func viewDidLoad() {
        // create a UIPicker view as a custom keyboard view
        self.picker = UIPickerView()

        if let picker = self.picker {
            picker.sizeToFit()
            picker.autoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight
            picker.delegate = self
            picker.dataSource = self
            picker.showsSelectionIndicator = true
            pickerTextField.inputView = picker

            // add a done button
            let toolbar = UIToolbar()
            toolbar.barStyle = UIBarStyle.Black
            toolbar.translucent = true
            toolbar.tintColor = nil
            toolbar.sizeToFit()

            let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Done, target: self, action: "dismissPicker")
            toolbar.setItems([doneButton], animated: false)
            pickerTextField.inputAccessoryView = toolbar
        }
    }

    @IBAction func showPicker() {
        pickerTextField.becomeFirstResponder()
    }

    @IBAction func dismissPicker() {
        pickerTextField.resignFirstResponder()
    }
}
3
Ben L.
- (IBAction)callDP:(id)sender {

    actionSheet = [[UIActionSheet alloc] initWithTitle:nil delegate:nil cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil];

    [actionSheet setActionSheetStyle:UIActionSheetStyleBlackTranslucent];

    CGRect pickerFrame = CGRectMake(0, 40, 0, 0);

    datePickerView = [[UIDatePicker alloc] initWithFrame:pickerFrame];
    datePickerView.tag = 10;
    [datePickerView addTarget:self action:@selector(changeDate:) forControlEvents:UIControlEventValueChanged];

    [actionSheet addSubview:datePickerView];

    UISegmentedControl *closeButton = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObject:@"Close"]];
    closeButton.momentary = YES; 
    closeButton.frame = CGRectMake(260, 7.0f, 50.0f, 30.0f);
    closeButton.segmentedControlStyle = UISegmentedControlStyleBar;
    closeButton.tintColor = [UIColor blackColor];
    [closeButton addTarget:self action:@selector(dismissActionSheet:) forControlEvents:UIControlEventValueChanged];
    [actionSheet addSubview:closeButton];
    [closeButton release];


    //[actionSheet showInView:self.view];
    [actionSheet showInView:[UIApplication sharedApplication].keyWindow];

    [actionSheet setBounds:CGRectMake(0, 0, 320, 485)];
}
2
Travis Loh

J'ai ajouté quelques commentaires pour plus de clarté, corrigez-moi si je me trompe (j'ai récemment commencé à développer pour iOS). Merci Matthias Bauch! Votre exemple de code m'a déjà beaucoup aidé et m'a fourni beaucoup d'informations. J'espère que ces commentaires feront de même pour les autres.

/*
 * Is called when the date is changed by the user.
 */
- (void)changeDate:(UIDatePicker *)sender {
    NSLog(@"New Date: %@", sender.date);
}


/*
 * Releases the background, datepicker and toolbar.
 */
- (void)removeViews:(id)object {

    /*
     *  Releases the background view.
     */ 
    [[self.view viewWithTag:9] removeFromSuperview];
    /*
     *  Releases the datepicker.
     */     
    [[self.view viewWithTag:10] removeFromSuperview];
    /*
     *  Releases the toolbar.
     */     
    [[self.view viewWithTag:11] removeFromSuperview];
}


/*
 * Hides the datapicker.
 */
- (void)dismissDatePicker:(id)sender {

    /*
     * Create a variable with the target position and size for hiding the toolbar.
     */
    CGRect toolbarTargetFrame = CGRectMake(0, self.view.bounds.size.height, 320, 44);
    /*
     * Create a variable with the target position and size for hiding the datepicker.
     */ 
    CGRect datePickerTargetFrame = CGRectMake(0, self.view.bounds.size.height + 44, 320, 216);


    /*
     * Send start animation message to UIView. 
     */ 
    [UIView beginAnimations:@"MoveOut" context:nil];
    /*
     * Set the transparency for hiding the background view.
     */ 
    [self.view viewWithTag:9].alpha = 0;
    /*
     * Set the target position for hiding the datepicker.
     */     
    [self.view viewWithTag:10].frame = datePickerTargetFrame;
    /*
     * Set the target position for hiding the toolbar.
     */     
    [self.view viewWithTag:11].frame = toolbarTargetFrame;
    /*
     * The method setAnimationDelegate enables knowledge on start and end of the animation.
     */         
    [UIView setAnimationDelegate:self];
    /*
     * Calls the removeViews method at the end of the animation.
     */     
    [UIView setAnimationDidStopSelector:@selector(removeViews:)];
    /*
     * Commits the animation thread for execution. 
     */ 
    [UIView commitAnimations];
}


/*
 * Sets up and shows the datepicker.
 */
- (IBAction)callDP:(id)sender {

    /*
     * If view with tag exists ignore the rest of the code and exit.
     */ 
    if([self.view viewWithTag:9]) {
        return;
    }


    /*
     * Create a variable with the target position and size for showing the toolbar.
     */
    CGRect toolbarTargetFrame = CGRectMake(0, self.view.bounds.size.height - 216 - 44, 320, 44);
    /*
     * Create a variable with the target position and size for showing the datepicker.
     */ 
    CGRect datePickerTargetFrame = CGRectMake(0, self.view.bounds.size.height - 216, 320, 216);


    /*
     * Instantiate a UIView with the frame size of the existing view.
     */
    UIView *darkView = [[UIView alloc] initWithFrame:self.view.bounds];
    /*
     * Set the transparency.
     */ 
    darkView.alpha = 0;
    /*
     * Set the background color.
     */ 
    darkView.backgroundColor = [UIColor blackColor];
    /*
     * Set a tag for the UIView instance to reference it by tag.
     */
    darkView.tag = 9;
    /*
     * Setup a tap gesture listener that calls the dismissDatePicker method on tap.
     */     
    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissDatePicker:)];
    /*
     * Add the tap gesture listener to the UIView.
     */ 
    [darkView addGestureRecognizer:tapGesture];
    /*
     * Adds the subview on top of all the other subviews.
     */
    [self.view addSubview:darkView];


    /*
     * Instantiate a UIDatePicker and set the initial frame with the datepicker outside of the view.
     */
    UIDatePicker *datePicker = [[UIDatePicker alloc] initWithFrame:CGRectMake(0, self.view.bounds.size.height+44, 320, 216)];
    /*
     * Set a tag for the UIDatePicker instance to reference it by tag.
     */ 
    datePicker.tag = 10;
    /*
     * Add a listener that listens for changing values in the datepicker which then calls the change date method.
     */     
    [datePicker addTarget:self action:@selector(changeDate:) forControlEvents:UIControlEventValueChanged];
    /*
     * Adds the subview on top of all the other subviews.
     */ 
    [self.view addSubview:datePicker];


    /*
     * Instantiate a UIToolbar and set the initial frame with the toolbar outside of the view.
     */
    UIToolbar *toolBar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, self.view.bounds.size.height, 320, 44)];
    /*
     * Set a tag for the UIToolbar instance to reference it by tag.
     */     
    toolBar.tag = 11;
    /*
     * Set a style for the UIToolbar.
     */ 
    toolBar.barStyle = UIBarStyleBlackTranslucent;
    /*
     * Instantiate a spacer UIBarButtonItem.
     */     
    UIBarButtonItem *spacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
    /*
     * Instantiate a done UIBarButtonItem on click this will call the dismissDatePicker method.
     */     
    UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(dismissDatePicker:)];
    /*
     * Set the created UIBarButtonItems to the toolbar.
     */     
    [toolBar setItems:[NSArray arrayWithObjects:spacer, doneButton, nil]];
    /*
     * Adds the subview on top of all the other subviews.
     */ 
    [self.view addSubview:toolBar];


    /*
     * Start animation.
     */ 
    [UIView beginAnimations:@"MoveIn" context:nil];
    /*
     * Set the target position for showing the toolbar.
     */ 
    toolBar.frame = toolbarTargetFrame;
    /*
     * Set the target position for showing the datepicker.
     */     
    datePicker.frame = datePickerTargetFrame;
    /*
     * Set the transparency for showing background view.
     */     
    darkView.alpha = 0.5;
    /*
     * Commits the animation thread for execution. 
     */     
    [UIView commitAnimations];
}
1
sidneydobber