如何制作一个模态日期选择器,只覆盖屏幕的一半?

19

我希望实现 iPhone 通讯录应用程序中的生日日期设置器的相同效果。如何让一个模态日期选择器只显示在屏幕上半部分。

我希望日期选择器位于 UITableView 上方(就像 iPhone 通讯录应用程序中一样)。我希望UITableView在日期选择器后面自由滚动(就像 iPhone 通讯录应用程序中一样)。

提前感谢您。


您的请求存在冲突或需要重新表述:您要求一个模态选择器,同时又希望UITableView在其后自由滚动。此外,是什么触发了它的出现?每个单元格(其中包含文本字段)?特定单元格?还是工具栏/导航栏中的按钮? - Oli
5个回答

53

迄今为止,实现日期选择器/滚轮选择器键盘的最佳方法是使用文本字段的 输入视图属性:

  1. 构建一个包含UITextField的简单自定义UITableViewCell(只有因为问题是关于将其嵌入表视图中)。

@interface pickerCell : UITableViewCell
{
    UITextField *txtTextField;
    UIPickerView* dtpPicker;
}
  • 将TextField的inputView设置为UIPickerView(确保它们都已分配和初始化):

  • txtTextField.inputView = dtpPicker;
    
  • 你快要完成了。现在,当文本框成为第一响应者(用户点击它)时,用户将会看到一个选择器视图。 只需填充自己的值,或使用日期选择器。

  • 您可以将选择器的代理 / 数据源设置为同一单元格(如果它始终是出生日期单元格),或者让单元格的父视图加载它的数据。无论您做出哪种选择,请确保在更新 txtTextField.text 时进行更新。

  • pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
    

    祝你好运! Elad.


    这是一个比制作自定义动画和添加按钮更好的答案。 - jrturton
    优美的解决方案。谢谢。 - zxcat
    我发现的其他解决方案都充满了神奇数字。我很高兴我继续寻找。 - Andreas
    如果我想要在点击选项卡栏目时显示日期选择器,类似这样的东西能行吗? - Nuno Gonçalves
    1
    更直接的说法是,您可以使用UIDatePicker而不是UIPickerView。 - letanthang
    显示剩余3条评论

    2

    这是我实现它的方式:我在一个名为DateTimeEntryViewController的不同控制器中拥有UIDatePicker,在用户点击按钮/单元格以输入日期和时间时,我在我的UIViewController中执行以下代码:

    self.alphaView = [[[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
    self.alphaView.opaque = NO;
    self.alphaView.backgroundColor = [UIColor clearColor];
    self.dateTimeEntryViewController.view.backgroundColor = [UIColor clearColor];
    
    UIWindow *window = [[TTNavigator navigator] window];
    [window addSubview:self.alphaView];
    [window insertSubview:self.dateTimeEntryViewController.view aboveSubview:self.alphaView];
    
    CGRect r = [_dateTimeEntryViewController.view frame];
    r.origin.y = 480.0f;
    [self.dateTimeEntryViewController.view setFrame:r]; 
    
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
    [UIView setAnimationDuration:0.5f];
    self.alphaView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5f];
    r.origin.y = 0;
    [self.dateTimeEntryViewController.view setFrame:r];
    [UIView commitAnimations];
    

    因此,我基本上是展示了一个视图控制器,在当前视图控制器的顶部有一个UIDatePicker。

    2

    这段代码将在UITableView中添加一个日期选择器作为子视图。假设我们是UITableViewController的子类。

    我们将从底部动画显示选择器。最后,我们将钩入scrollViewDidScroll:委托方法,以便在表格滚动时,选择器似乎停留在原地。

    在.h文件中,添加一个picker属性。

    @property (strong, nonatomic) UIDatePicker *datePicker;
    

    在你的 .m 文件中,我们添加日期选择器。
    - (void)viewDidLoad
    {
      // Your own customization code.
    
        self.datePicker = [[UIDatePicker alloc] initWithFrame:CGRectMake(0, 200, 320, 216)];
        self.datePicker.hidden = YES;
        [self.datePicker addTarget:self action:@selector(datePickerValueChanged:) forControlEvents:UIControlEventValueChanged];
        [self.view addSubview:self.datePicker];
    }
    
    - (void)presentDatePicker
    {
        if (self.datePicker.hidden == NO) { return; }
    
        // Set the date picker frame to be below the screen.
        self.datePicker.frame = CGRectMake(0, self.view.frame.size.height, self.datePicker.size.width, self.datePicker.size.height);
        CGRect originFrame = self.datePicker.frame;
    
        // Animate from the bottom.
        [UIAnimation animateWithDuration:.3 animations^{
          self.datePicker.frame = CGRectMake(0, 200, originFrame.size.width, originFrame.size.height);
        }];
    }
    
    #pragma mark - Scroll view delegate
    - (void)scrollViewDidScroll:(UIScrollView *)scrollView
    {
        CGRect tableBounds = self.tableView.bounds;
        CGRect datePickerFrame = self.datePicker.frame;
    
        self.datePicker.frame = CGRectMake(0, 200 + tableBounds.origin.y, datePickerFrame.size.width, datePickerFrame.size.height);
    }
    

    不要忘记在viewDidUnload中使用@synthesize声明你的属性,并释放它。


    1
    在iPhone通讯录应用程序中,当按下按钮时,日期选择器会出现。要做到这一点,您需要以下几个东西:
    1. 一个连接到操作的按钮,我们将称之为 `-(IBAction)showDatePicker:(id)sender`
    2. 一个iVar,即您的datePicker,我们将其称为 `datePicker`。
    现在,在 `ViewDidLoad` 中,您必须创建 datePicker 并设置其框架。因为我们不希望它在按下 showDatePicker 按钮之前显示出来,所以设置其框架使其超出屏幕范围。`(0,416,320,216)` 应该不错。现在将 datePicker 添加为您的视图控制器的子视图。请记住,它不应该立即显示出来,因为我们已将其框架设置为超出屏幕。现在,在您的 showDatePicker 操作中,我们希望使 datePicker 出现,因此可以通过更改块动画中的框架来对其进行动画处理:
    [UIView animateWithDuration:0.5 animations:^{
        [datePicker setFrame:CGRectMake(0, 200, 320, 216)];
    }];
    

    同样地,如果您想制作一个使datePicker消失的按钮,您也可以这样做。您只需将框架设置回原来的状态即可。
    希望这有所帮助!
    -K

    谢谢!动画效果很棒。但是我将datePicker添加到的视图是UITableView。这意味着datePicker会随UITableView一起滚动。在iPhone上的联系人应用程序中,UITableView可以独立滚动,而弹出的datePicker则不受影响。有什么办法可以实现这个效果吗?谢谢! - rustybeanstalk
    2
    我认为最简单的解决方案是根本不将其添加到 tableView。如果您将 VC 改为 UIViewController 的子类而不是 UITableViewController,则仍然可以拥有 tableView(并且成为其委托和数据源),但作为主视图的子视图(UITableViewController 与通用 VC 相比要少得多)。然后,您可以将 datePicker 添加到主视图而不是 tableView 中。 - Martin Gjaldbaek

    1

    虽然这是在一个旧帖子中发表的,但可能会对某些人有所帮助。为3.5英寸屏幕添加200就足够了,如果想要通用方法,请使用

    - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
       CGRect tableBounds = self.tableView.bounds;
       CGRect datePickerFrame = self.datePicker.frame;
       self.datePicker.frame = CGRectMake(0,
                                          tableBounds.origin.y + tableBounds.size.height - datePickerFrame.size.height,
                                          datePickerFrame.size.width,
                                          datePickerFrame.size.height);
    }
    

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接