Iphone 带选择器视图的UITableViewController

Iphone 带选择器视图的UITableViewController,iphone,uitableview,uidatepicker,Iphone,Uitableview,Uidatepicker,我有一个严重的问题,我自己解决不了。我花了数小时搜索文档、编程指南以及开发人员论坛和堆栈溢出 问题是我想在UITableViewController中显示选择器视图。我有一个屏幕,有多个文本字段,允许我按标题/作者/关键字搜索。。。我还想使用UIDatePicker(或UIPickerView——例如指定“最后5天”)指定最小和最大日期 我想使用UITableViewController,因为当用户按下文本字段时,键盘弹出时,它可以节省我调整表格大小的大量时间。事实上,我从来没有能够使用UIVi

我有一个严重的问题,我自己解决不了。我花了数小时搜索文档、编程指南以及开发人员论坛和堆栈溢出

问题是我想在UITableViewController中显示选择器视图。我有一个屏幕,有多个文本字段,允许我按标题/作者/关键字搜索。。。我还想使用UIDatePicker(或UIPickerView——例如指定“最后5天”)指定最小和最大日期

我想使用UITableViewController,因为当用户按下文本字段时,键盘弹出时,它可以节省我调整表格大小的大量时间。事实上,我从来没有能够使用UIViewController和聆听textfields的委托来重现这个动画。它几乎完美无瑕,但与使用UITableViewController显示的表的行为相比,它存在一些明显的缺点

所以当只有文本字段时,一切都很好。但是日期文件呢?当我想添加新联系人并指定生日时,我想让它与苹果的Contacts.app一模一样。在该应用程序中,显示日期选择器,调整表的大小,在电子邮件/电话字段和生日字段之间切换非常有效。我可以相信,在这种情况下,日期选择器是键盘,但不是用于键入电话/电子邮件,而是日期,因为它像键盘一样滑入/滑出,打开键盘/选择器时会立即被替换

你是怎么做到的? 或者我在哪里可以找到复制它的最简单的解决方案。我相信这不会那么难,因为这是非常普遍的情况

问候
Chris

如果要滑入/滑出选择器视图,可以使用核心动画。 最简单的代码片段:

// Slide picker view in
[UIView beginAnimations: @"SlideIn" context: nil];
myPickerView.frame = upFrame;
[UIView commitAnimations];

// ...

// Slide picker view out
[UIView beginAnimations: @"SlideOut" context: nil];
myPickerView.frame = downFrame;
[UIView commitAnimations];
upFrame
downFrame
分别是屏幕上和屏幕外选取器视图的正确位置


希望这有帮助。

您必须创建一个UIWindow对象,然后添加一个视图。windowLevel属性使其高于状态栏,您可能需要也可能不需要

//statusWindow is a UIWindow ivar declared in the header
//pickerShowing is declared as a BOOL in header
//release and removeFromSuperview is done in the animation delegate methods

//ANIMATE IN

-(void)slideIn {
    CGRect pickerFrame = CGRectMake(0.0f, 0.0f, 320.0f, 200.0f); //guessing on height
    UIView *viewForPicker = [[UIView alloc] init];
    UIPickerView *aPicker = [[UIPickerView alloc] init]; //don't forget to set delegate and dataSource
    viewForPicker.frame = pickerFrame;
    statusWindow = [[UIWindow alloc] initWithFrame:CGRectMake(0.0, 480.0, 320.0f, 200.0f)];//guessing on height, y value is off the screen (bottom)
    statusWindow.windowLevel = UIWindowLevelStatusBar;
    statusWindow.hidden = NO;
    statusWindow.backgroundColor = [UIColor clearColor];
    [statusWindow makeKeyAndVisible];
    [viewForPicker addSubview:aPicker];
    [statusWindow addSubview:viewForPicker];
    [viewForPicker release];
    [aPicker release];
    [UIView beginAnimations:@"slideUp" context:nil];
    [UIView setAnimationDuration:0.3];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(animationFinished:)];
    statusWindow.frame = CGRectMake(0.0f, 200.0f, 320.0f, 200.0f); //guessing on y and height values, change them to suit needs 
    [UIView commitAnimations];
    pickerShowing = YES;
}


//ANIMATE out:



-(void)slideOut {
    [UIView beginAnimations:@"slideDown" context:nil];
    [UIView setAnimationDuration:0.3];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(animationFinished:)];
    statusWindow.frame = CGRectMake(0.0f, 480.0f, 320.0f, 200.0f);
    [UIView commitAnimations];
    pickerShowing = NO;
}

-(void)animationFinished:(NSString *)name {
    if ([name isEqualToString:@"slideDown"]) {
        [statusWindow release];
    }
}
你可以从苹果下载一个完整的示例应用程序来演示这一点。
所有这些都是毫无意义的。我们应该处理inputView和inputAccessoryView,其中inputView应该有选择器和inputAccessoryView工具栏。

我自己尝试过,到目前为止,我唯一没有完成的事情就是调整表视图的大小。但是myPickerView被添加为哪个UI元素的子视图?一个美丽的风景?如果我将选择器作为子视图添加到tableview,则在我滚动表格时,它也会上下滚动。我使用UITableViewController,因此self.view=tableviewAh。。。如果可能,您必须将其附加到表的父级
self.parentViewController
。是的,这很酷,但在这种情况下,我必须像照顾一个小婴儿一样照顾这个窗口。即使我按下导航控制器的“后退”按钮,带有选择器的窗口仍保持可见。如果textfield的键盘可见,则当视图控制器消失时,它将隐藏。难道没有其他方法可以玩键盘和选择器吗?如果有一天我能将选取器视图和日期选取器视为键盘的一种类型,我会感到惊讶……你必须为选取器和UIWindow何时可见设置布尔值,即滑块完成时。滑出完成后,将BOOL设置回NO。检查viewController的BOOL in viewwillEnglish,如果是,则调用slideOut方法。这将必须在标题中声明,如BOOL pickershow;我真的很感谢你的帮助,这越来越有意义了。但是,您确定必须添加这么多行代码才能达到这样的效果吗?我的意思是,这真的是正确的方法吗?我想让我的picker视图像键盘一样工作,这种行为是否有些奇怪?只是想知道为什么苹果没有提供更好的东西来显示它。这是一个解决办法,因为viewController正在管理一个tableView,正如你所发现的,它可以上下滚动。我不在我的xcode办公桌上,但您可以尝试在出现选择器时将tableView的scrollable属性设置为NO?只是一个猜测虽然我不能同意这样的解决方案,但我必须考虑我自己的解决方案,但非常感谢。如果有人不确定这个答案的意思。。。然后,需要将UITextField添加到表单元格(在tableView:CellForRowatineXpath:)中,并使用view标记,以便以后检索它。将表视图控制器设置为委托,然后将inputView和inputAccessoryView属性设置为UIDatePicker和UIToolbar实例(如果需要,可以从nib)。现在,当您点击单元格时,选择器将显示出来。重写UITextViewDelegate方法以使用NSDateFormatter实例格式化输出。
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *targetCell = [tableView cellForRowAtIndexPath:indexPath];
    self.pickerView.date = [self.dateFormatter dateFromString:targetCell.detailTextLabel.text];

    // check if our date picker is already on screen
    if (self.pickerView.superview == nil)
    {
        [self.view.window addSubview: self.pickerView];

        // size up the picker view to our screen and compute the start/end frame origin for our slide up animation
        //
        // compute the start frame
        CGRect screenRect = [[UIScreen mainScreen] applicationFrame];
        CGSize pickerSize = [self.pickerView sizeThatFits:CGSizeZero];
        CGRect startRect = CGRectMake(0.0,
                                      screenRect.origin.y + screenRect.size.height,
                                      pickerSize.width, pickerSize.height);
        self.pickerView.frame = startRect;

        // compute the end frame
        CGRect pickerRect = CGRectMake(0.0,
                                       screenRect.origin.y + screenRect.size.height - pickerSize.height,
                                       pickerSize.width,
                                       pickerSize.height);
        // start the slide up animation
        [UIView beginAnimations:nil context:NULL];
            [UIView setAnimationDuration:0.3];

            // we need to perform some post operations after the animation is complete
            [UIView setAnimationDelegate:self];

            self.pickerView.frame = pickerRect;

            // shrink the table vertical size to make room for the date picker
            CGRect newFrame = self.tableView.frame;
            newFrame.size.height -= self.pickerView.frame.size.height;
            self.tableView.frame = newFrame;
        [UIView commitAnimations];

        // add the "Done" button to the nav bar
        self.navigationItem.rightBarButtonItem = self.doneButton;
    }
}

- (void)slideDownDidStop
{
    // the date picker has finished sliding downwards, so remove it
    [self.pickerView removeFromSuperview];
}

- (IBAction)dateAction:(id)sender
{
    NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
    UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
    cell.detailTextLabel.text = [self.dateFormatter stringFromDate:self.pickerView.date];
}

- (IBAction)doneAction:(id)sender
{
    CGRect screenRect = [[UIScreen mainScreen] applicationFrame];
    CGRect endFrame = self.pickerView.frame;
    endFrame.origin.y = screenRect.origin.y + screenRect.size.height;

    // start the slide down animation
    [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationDuration:0.3];

        // we need to perform some post operations after the animation is complete
        [UIView setAnimationDelegate:self];
        [UIView setAnimationDidStopSelector:@selector(slideDownDidStop)];

        self.pickerView.frame = endFrame;
    [UIView commitAnimations];

    // grow the table back again in vertical size to make room for the date picker
    CGRect newFrame = self.tableView.frame;
    newFrame.size.height += self.pickerView.frame.size.height;
    self.tableView.frame = newFrame;

    // remove the "Done" button in the nav bar
    self.navigationItem.rightBarButtonItem = nil;

    // deselect the current table row
    NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
    [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
}