如何以方向友好的方式在选项卡栏上显示 UIDatePicker?

发布于 2024-11-15 10:45:14 字数 2948 浏览 4 评论 0原文

当我的用户点击我的表格视图日期字段时,我想在 UIDatePicker 中滑动,就像在标准联系人应用程序中,当用户点击生日字段时一样。还有一个额外的致命细节:

它位于标签栏应用程序中,我希望 UIDatePicker 在标签栏上滑动。当用户将手机横向放置时仍然会旋转。

我显示 UIDatePicker 的方式是插入视图中,然后设置其位置动画:

        [self.view addSubview: self.pickerView];

当我这样做时,会显示 UIDatePicker,但不会覆盖选项卡栏。

我还可以将其添加到窗口中:

        [self.view.window addSubview: self.pickerView];

UIDatePicker 正确地在选项卡栏上滑动,但是随后,它不遵循方向。

我发现的唯一半可接受的方法是完全不使用选项卡栏,方法是使用

        detailViewController.hidesBottomBarWhenPushed = YES;

但这不是我想要的:我想要详细视图中的选项卡栏。我只希望它在选择日期时消失。我无法使用 hidesBottomBarWhenPushed = YESUIDatePicker 放入其自己的控制器中,因为这会完全覆盖屏幕,而且我宁愿让详细视图仍然部分可见。

欢迎任何建议。

以下是我用来显示 UIDatePicker 的完整代码,是从一些示例代码复制过来的:

- (void) doPickDate
{
    NSDate *initialDateForPicker = [(ExpenseData*) self.displayedObject displayDate];
    self.pickerView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin;
    self.pickerView.datePickerMode = UIDatePickerModeDate;
    self.pickerView.date = initialDateForPicker;

    // check if our date picker is already on screen
    if (self.pickerView.superview == nil)
    {
        [self.view 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 - 49 /* tab bar height */;
        self.tableView.frame = newFrame;
        [UIView commitAnimations];

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

}

I want to slide in a UIDatePicker when my user taps on my table view date field, exactly as in the standard contact app, when the user taps on the birthday field. With one additional killer detail:

It's in a tab bar application and I want the UIDatePicker to slide over the tab bar. And still rotates when the user puts her phone in the lanscape orientation.

The way I show the UIDatePicker is to insert in the view, and then animate its position:

        [self.view addSubview: self.pickerView];

When I do this, the UIDatePicker is shown, but doesn't cover the tabbar.

I can also add it to the window:

        [self.view.window addSubview: self.pickerView];

The UIDatePicker correctly slides over the tab bar, but then, it doesn't follow the orientation.

The only semi-acceptable way I found, is to do without the tab bar altogether, by using

        detailViewController.hidesBottomBarWhenPushed = YES;

But it's not what I want: I want the tab bar in the detail view. I only want it to go away while picking the date. I can't put the UIDatePicker in its own controller with hidesBottomBarWhenPushed = YES as this would entirely cover the screen, and I'd rather have the detail view still partially visible.

Any suggestion welcome.

Here is the full code I use to show the UIDatePicker, copied over from some sample code:

- (void) doPickDate
{
    NSDate *initialDateForPicker = [(ExpenseData*) self.displayedObject displayDate];
    self.pickerView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin;
    self.pickerView.datePickerMode = UIDatePickerModeDate;
    self.pickerView.date = initialDateForPicker;

    // check if our date picker is already on screen
    if (self.pickerView.superview == nil)
    {
        [self.view 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 - 49 /* tab bar height */;
        self.tableView.frame = newFrame;
        [UIView commitAnimations];

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

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

不醒的梦 2024-11-22 10:45:14

您应该将 UIDatePicker 对象设置为该特定文本字段的 inputView。所有动画和演示内容都将得到处理。

隐藏光标

没有方法可以隐藏光标。我能想到的唯一机制是使用 leftView 属性并将其设置为标签。

CGRect frame = self.textField.bounds;

UILabel * theLabel = [[[UILabel alloc] initWithFrame:frame] autorelease];
theLabel.userInteractionEnabled = YES;
theLabel.backgroundColor = [UIColor clearColor];

UITapGestureRecognizer * tap = [[[UITapGestureRecognizer alloc] initWithTarget:self
                                                                        action:@selector(tap:)] autorelease];
[theLabel addGestureRecognizer:tap];

self.textField.leftViewMode = UITextFieldViewModeAlways;
self.textField.leftView = theLabel;
self.textField.clipsToBounds = YES;

并使用处理点击,

- (void)tap:(UIGestureRecognizer *)gesture {
    [self.textField becomeFirstResponder];
}

现在这不适用于圆角矩形按钮,因为无论标签的框架是什么,光标都会在右上角闪烁。它隐藏其他边框样式的光标。您还可以通过将值设置为其文本来充分利用该标签。

UILabel * theLabel = textField.leftView;
theLabel.text = @"Appropriate Value from Picker";

You should set the UIDatePicker object as the inputView of that particular text field. All the animations and presentation stuff will be taken care of.

Hiding the cursor

There is no method to hide the cursor. The only mechanism I could think of was to use the leftView property and set it to a label.

CGRect frame = self.textField.bounds;

UILabel * theLabel = [[[UILabel alloc] initWithFrame:frame] autorelease];
theLabel.userInteractionEnabled = YES;
theLabel.backgroundColor = [UIColor clearColor];

UITapGestureRecognizer * tap = [[[UITapGestureRecognizer alloc] initWithTarget:self
                                                                        action:@selector(tap:)] autorelease];
[theLabel addGestureRecognizer:tap];

self.textField.leftViewMode = UITextFieldViewModeAlways;
self.textField.leftView = theLabel;
self.textField.clipsToBounds = YES;

and handle the tap using,

- (void)tap:(UIGestureRecognizer *)gesture {
    [self.textField becomeFirstResponder];
}

Now this doesn't work for the rounded rect button as the cursor blinks on the right corner no matter what the label's frame is. It hides the cursor for other border styles. You can also use the label to your advantage by setting your values as its text.

UILabel * theLabel = textField.leftView;
theLabel.text = @"Appropriate Value from Picker";
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文