开发者

How to show a UIDatePicker over the tab bar, in an orientation-friendly way?

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开发者_Go百科 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;
    }

}


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";
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜