按下 UIButton 后会弹出 UIDatePicker

Posted

技术标签:

【中文标题】按下 UIButton 后会弹出 UIDatePicker【英文标题】:UIDatePicker pop up after UIButton is pressed 【发布时间】:2011-06-16 23:30:27 【问题描述】:

如何在按下 UIButton 后使 UIDatePicker 弹出(动画),然后在选择日期后再次关闭?这是在 iPhone 上。

【问题讨论】:

【参考方案1】:
canihazcode?

是的,先生。谢谢你帮我拖延。

- (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];

【讨论】:

非常感谢!我真的很感激帮助!只是一个问题,有没有一种方法可以在不使用标签的情况下重新引用我们想要忽略的视图? 完成按钮选择器是否被调用?在我的情况下没有发生?? 如果您将 UITapGestureRecognizer 事件附加到主视图,则工具栏中的“完成”按钮将不起作用。对于那些有这个问题的人可以使用这里的代码来解决它:***.com/a/14950275/705982@raghul【参考方案2】:

我建议以下(适用于 ios 3.2 或更高版本)。

    创建一个文本字段。 为文本字段分配一个作为 UIDateTimerPicker 的 inputView。 单击按钮时,发送“becomeFirstResponder”事件 - 这将使日期选择器从底部向上滑动... 恕我直言,关闭选择器的最佳方式不是在选择日期时(因为即使我们正在搜索正确的日期/时间也可能会关闭它) - 而是附加一个“完成”或“选择”按钮作为键盘的附件输入视图。

下面是一些显示步骤 2-4 的代码:(我希望我没有忘记复制/粘贴过程中的任何内容...

1+3 创建 UIDateTimePicker 作为文本字段输入视图,并在其上附加一个带有“完成”按钮的工具栏...

    // 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];
    

祝你好运……

【讨论】:

这真的是一种优雅的方式吗?获取文本字段并将其与日期选择器交换?这种方式听起来有点奇怪 您不 swap 日期选择器的文本字段 - 您交换文本字段的 KEYBOARD - 并使键盘成为日期选择器。这为您免费提供所有其他要求的东西 - 免费... 这其实很漂亮! 你只是让我一个半小时的沮丧开发工作无效并且同时让我很开心。我试图关闭键盘并为选择器视图的演示设置动画。我真正需要的只是UITextField 上的-inputView。太棒了。【参考方案3】:

这是@Reuven 的代码的 Swift (1.2) 版本

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()
    

【讨论】:

【参考方案4】:
- (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)];

【讨论】:

这是一个更简单的解决方案。 您可以在答案中添加一些文字向其他人解释吗?【参考方案5】:

为了清楚起见,我添加了一些 cmets,如果我错了,请纠正我(我最近开始为 iOS 开发)。谢谢马蒂亚斯鲍赫!您的代码示例已经帮助了我很多,并提供了很多见解。我希望这些 cmets 也能对其他人做同样的事情。

/*
 * 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];

【讨论】:

以上是关于按下 UIButton 后会弹出 UIDatePicker的主要内容,如果未能解决你的问题,请参考以下文章

关于h5页面,弹框点击确认按钮后会弹出Safari浏览器 问题

使用 UIButton 操作在 UITableViewCell 中显示弹出框

从 UIButton 中获取 UIButton 的标签,该 UIButton 位于此 UIButton 呈现的弹出框中

VC++ MFC关于全局勾子的执行次数问题,高手帮助!成功调用以后,按下F9会弹出两次对话框,求解?只要执行一

sublime text 3 汉化操作过程

Android6.0源码分析之menu键弹出popupwindow菜单流程分析