Objective C implementing a UIPickerView with a “Done” button

后端 未结 7 597
一向
一向 2020-12-03 08:56

I am trying to implement a \"Done\" button in a UIPickerView Similar to the one under this link

I looked in the class reference but I couldn t find it

Thank

相关标签:
7条回答
  • 2020-12-03 09:21

    You get the "Done" button in the toolbar using the ActionSheetPicker. Its is a great alternative to building it yourself.

    https://github.com/skywinder/ActionSheetPicker-3.0

    0 讨论(0)
  • 2020-12-03 09:22

    I create a custom class, this supports multiple orientation:

    DateTimePicker.h

        @interface DateTimePicker : UIView {
    }
    
    @property (nonatomic, assign, readonly) UIDatePicker *picker;
    
    - (void) setMode: (UIDatePickerMode) mode;
    - (void) addTargetForDoneButton: (id) target action: (SEL) action;
    
    @end
    

    DateTimePicker.m

    #define MyDateTimePickerToolbarHeight 40
    
    @interface DateTimePicker()
    
    @property (nonatomic, assign, readwrite) UIDatePicker *picker;
    
    @property (nonatomic, assign) id doneTarget;
    @property (nonatomic, assign) SEL doneSelector;
    
    - (void) donePressed;
    
    @end
    
    
    @implementation DateTimePicker
    
    @synthesize picker = _picker;
    
    @synthesize doneTarget = _doneTarget;
    @synthesize doneSelector = _doneSelector;
    
    - (id) initWithFrame: (CGRect) frame {
        if ((self = [super initWithFrame: frame])) {
            self.backgroundColor = [UIColor clearColor];
    
            UIDatePicker *picker = [[UIDatePicker alloc] initWithFrame: CGRectMake(0, MyDateTimePickerToolbarHeight, frame.size.width, frame.size.height - MyDateTimePickerToolbarHeight)];
            [self addSubview: picker];
    
            UIToolbar *toolbar = [[UIToolbar alloc] initWithFrame: CGRectMake(0, 0, frame.size.width, MyDateTimePickerToolbarHeight)];
            toolbar.barStyle = UIBarStyleBlackOpaque;
            toolbar.autoresizingMask = UIViewAutoresizingFlexibleWidth;
    
            UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithTitle: @"Done" style: UIBarButtonItemStyleBordered target: self action: @selector(donePressed)];
            UIBarButtonItem* flexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
            toolbar.items = [NSArray arrayWithObjects:flexibleSpace, doneButton, nil];
    
            [self addSubview: toolbar];
    
            self.picker = picker;
            picker.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleBottomMargin;
    
            self.autoresizesSubviews = YES;
            self.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleBottomMargin;
        }
        return self;
    }
    
    - (void) setMode: (UIDatePickerMode) mode {
        self.picker.datePickerMode = mode;
    }
    
    - (void) donePressed {
        if (self.doneTarget) {
            [self.doneTarget performSelector:self.doneSelector withObject:nil afterDelay:0];
        }
    }
    
    - (void) addTargetForDoneButton: (id) target action: (SEL) action {
        self.doneTarget = target;
        self.doneSelector = action;
    }
    

    Using custom view in your view controller:

    - (void)viewDidLoad
    {
        [super viewDidLoad];
        UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        [button addTarget:self
                   action:@selector(buttonPressed:)
         forControlEvents:UIControlEventTouchDown];
        [button setTitle:@"Show picker" forState:UIControlStateNormal];
        button.frame = CGRectMake(100, 50, 100, 40.0);
        [self.view addSubview:button];
    
        CGRect screenRect = [[UIScreen mainScreen] bounds];
        CGFloat screenWidth = screenRect.size.width;
        CGFloat screenHeight = screenRect.size.height;
        picker = [[DateTimePicker alloc] initWithFrame:CGRectMake(0, screenHeight/2 - 35, screenWidth, screenHeight/2 + 35)];
        [picker addTargetForDoneButton:self action:@selector(donePressed)];
        [self.view addSubview:picker];
        picker.hidden = YES;
        [picker setMode:UIDatePickerModeDate];
    }
    
    -(void)donePressed {
        picker.hidden = YES;
    }
    
    -(void)buttonPressed:(id)sender {
        picker.hidden = NO;
    }
    

    Hope this helps. :)

    0 讨论(0)
  • 2020-12-03 09:22

    In case you are working on a Table View Cell and you are not using a UITextField (hence you won't be using the Accessory View), here's what I did:

    I created a table view cell called GWDatePickerCell that looks like this (no .nib files involved).

    GWDatePickerCell.h:

    #import <UIKit/UIKit.h>
    
    @interface GWDatePickerCell : UITableViewCell
    
    @property (nonatomic, strong) UIDatePicker *datePicker;
    @property (nonatomic, strong) UIToolbar *toolbar;
    @property (nonatomic, strong) UIBarButtonItem *buttonDone;
    
    @end
    

    GWDatePickerCell.m:

        #import "GWDatePickerCell.h"
    
        @implementation GWDatePickerCell
    
        - (id) initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
            if(!(self=[super initWithStyle:style reuseIdentifier:reuseIdentifier])) return nil;
    
        _datePicker = [[UIDatePicker alloc] init];
        [_datePicker setMinuteInterval:5];
        [_datePicker setDatePickerMode:UIDatePickerModeDateAndTime];
        [self.contentView addSubview:_datePicker];
    
        _toolbar = [[UIToolbar alloc] init];
        _buttonDone = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:nil action:nil];
        _toolbar.items = @[[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil], _buttonDone];
        [self.contentView addSubview:_toolbar];
    
        return self;
    }
    
    - (void)layoutSubviews{
        [super layoutSubviews];
        CGRect r = self.contentView.bounds;
        r.origin.y +=44;
        r.size.height = 216;
        CGRect tb = self.contentView.bounds;
        tb.size.height = 44;
        _datePicker.frame = r;
        _toolbar.frame = tb;
    }
    
    @end
    

    Now all I had to do when creating the cells in the Table View:

    • Specify the @selector for the Done button.
    • Set the correct cell height in heightForRowAtIndexPath
    0 讨论(0)
  • 2020-12-03 09:25

    Success! Ok, I would never suggest doing this, but here's where the done button is created in your particular tutorial code:

    Looking at the storyboard, we can see that when you click the "Role" box within "AddPersonTVC.h" (class at the top right of the storyboard), it pops up a class called "RollPickerTVCell.h"

    Looking into RollPickerTVCell.h, we notice that the whole class is a subclass of "CoreDataTableViewCell"

    @interface RolePickerTVCell : CoreDataTableViewCell <UIPickerViewDataSource, UIPickerViewDelegate>
    

    Looking at the class "CoreDataTableViewCell.m", we finally find our uibarbuttonitem!

    UIBarButtonItem *doneBtn =[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(done:)];
    
    0 讨论(0)
  • 2020-12-03 09:31

    The easiest way to do it is to model it in Interface Builder. It is a UIView containing a UIToolbar and a UIPickerView.

    enter image description here

    Then create an outlet for the UIView and connect it.

    enter image description here

    If you then have a UITextField you can assign your custom view to its inputView property.

    [self.textField setInputView:self.customPicker];
    

    Alternatively you can add the picker to your main view...

    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        self.customPicker.frame = CGRectMake(0, CGRectGetMaxY(self.view.frame), CGRectGetWidth(self.customPicker.frame), CGRectGetHeight(self.customPicker.frame));
        [self.view addSubview:self.customPicker];
    }
    

    ... and then use this method to show or hide the picker.

    - (void)setPickerHidden:(BOOL)hidden
    {
        CGAffineTransform transform = hidden ? CGAffineTransformIdentity : CGAffineTransformMakeTranslation(0, -CGRectGetHeight(self.customPicker.frame));
    
        [UIView animateWithDuration:0.3 animations:^{
            self.customPicker.transform = transform;
        }];
    }
    
    0 讨论(0)
  • 2020-12-03 09:35

    I added a UIToolbar with a UIBarButtonItem for the 'done' button in my xib with the frame set so that it's not initially visible (y value equal to the height of the parent view).

    Every time the user access the picker, I changed the frame (the y value) of the UIDatePicker and the UIToolbar with an animation so that it slides up along with the picker from the bottom of the screen similar to the keyboard.

    Check out my code below.

    - (IBAction)showPicker
    {
        if(pickerVisible == NO)
        {
            // create the picker and add it to the view
            if(self.datePicker == nil) self.datePicker = [[[UIDatePicker alloc] initWithFrame:CGRectMake(0, 460, 320, 216)] autorelease];
            [self.datePicker setMaximumDate:[NSDate date]];
            [self.datePicker setDatePickerMode:UIDatePickerModeDate];
            [self.datePicker setHidden:NO];
            [self.view addSubview:datePicker];
    
            // the UIToolbar is referenced 'using self.datePickerToolbar'
            [UIView beginAnimations:@"showDatepicker" context:nil];
            // animate for 0.3 secs.
            [UIView setAnimationDuration:0.3];
    
            CGRect datepickerToolbarFrame = self.datePickerToolbar.frame;
            datepickerToolbarFrame.origin.y -= (self.datePicker.frame.size.height + self.datePickerToolbar.frame.size.height);
            self.datePickerToolbar.frame = datepickerToolbarFrame;
    
            CGRect datepickerFrame = self.datePicker.frame;
            datepickerFrame.origin.y -= (self.datePicker.frame.size.height + self.datePickerToolbar.frame.size.height);
            self.datePicker.frame = datepickerFrame;
    
            [UIView commitAnimations];
            pickerVisible = YES;
        }
    }
    
    - (IBAction)done
    {
        if(pickerVisible == YES)
        {
            [UIView beginAnimations:@"hideDatepicker" context:nil];
            [UIView setAnimationDuration:0.3];
    
            CGRect datepickerToolbarFrame = self.datePickerToolbar.frame;
            datepickerToolbarFrame.origin.y += (self.datePicker.frame.size.height + self.datePickerToolbar.frame.size.height);
            self.datePickerToolbar.frame = datepickerToolbarFrame;
    
            CGRect datepickerFrame = self.datePicker.frame;
            datepickerFrame.origin.y += (self.datePicker.frame.size.height + self.datePickerToolbar.frame.size.height);
            self.datePicker.frame = datepickerFrame;
            [UIView commitAnimations];
    
            // remove the picker after the animation is finished
            [self.datePicker performSelector:@selector(removeFromSuperview) withObject:nil afterDelay:0.3];
        }
    }
    
    0 讨论(0)
提交回复
热议问题