2012-05-22 8 views

risposta

6

ho aggiunto un UIToolbar con UIBarButtonItem per il pulsante 'fatto' nel mio xib con il telaio impostato in modo che non è inizialmente visibile (valore y uguale all'altezza della vista primaria).

Ogni volta che l'utente accede al selettore, ho modificato il fotogramma (il valore y) di UIDatePicker e UIToolbar con un'animazione in modo che scorra con il selettore dalla parte inferiore dello schermo simile alla tastiera.

Controlla il mio codice qui sotto.

- (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

Dovresti dare un'occhiata alla risposta di @ Paul-Hunter per la creazione dei componenti xib. –

0

Successo! Ok, non suggerirei mai di farlo, ma qui è dove viene creato il pulsante di esecuzione nel tuo particolare codice tutorial:

Guardando lo storyboard, possiamo vedere che quando si fa clic sulla casella "Ruolo" all'interno di "AddPersonTVC.h". (classe in alto a destra dello storyboard), si apre una classe chiamata "RollPickerTVCell.h"

Guardando in RollPickerTVCell.h, notiamo che tutta la classe è una sottoclasse di "CoreDataTableViewCell"

@interface RolePickerTVCell : CoreDataTableViewCell <UIPickerViewDataSource, UIPickerViewDelegate> 

Guardando la classe "CoreDataTableViewCell.m", troviamo finalmente il nostro uibarbuttonitem!

UIBarButtonItem *doneBtn =[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(done:)]; 
39

Il modo più semplice per farlo è modellarlo in Interface Builder. È un UIView contenente uno UIToolbar e uno UIPickerView.

enter image description here

Quindi creare uno sbocco per il UIView e collegarlo.

enter image description here

Se poi si dispone di un UITextField è possibile assegnare la visualizzazione personalizzata alla sua proprietà inputView.

[self.textField setInputView:self.customPicker]; 

In alternativa è possibile aggiungere il selettore di visualizzazione principale ...

- (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]; 
} 

... e quindi utilizzare questo metodo per mostrare o nascondere il selettore.

- (void)setPickerHidden:(BOOL)hidden 
{ 
    CGAffineTransform transform = hidden ? CGAffineTransformIdentity : CGAffineTransformMakeTranslation(0, -CGRectGetHeight(self.customPicker.frame)); 

    [UIView animateWithDuration:0.3 animations:^{ 
     self.customPicker.transform = transform; 
    }]; 
} 
+0

Quale tema utilizza XCode? – nemesis

+0

@nemesis Penso che sia questo: https://github.com/chriskempson/tomorrow-theme/tree/master/Xcode%204 –

2

ho creare una classe personalizzata, questo sostiene orientamento multipla:

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; 
} 

Utilizzando visualizzazione personalizzata nel vostro controller della vista:

- (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; 
} 

Spero che questo aiuti. :)

+0

Stavo provando il tuo metodo. Ho creato una classe personalizzata e ho importato il file .h in una nuova classe. Ma dice un identificatore non definito. Sto facendo qualcosa di sbagliato? – aVC

+0

#import #import "DateTimePicker.h" @interface ViewController: UIViewController { DateTimePicker * dateTimePicker; } – thanhbinh84

1

C'è una soluzione più elegante. Non sono sicuro se questo è recente (come di iOS7), ma questo ha funzionato per me splendidamente.

TJDatePicker.h

@protocol TJDatePickerActionDelegate <NSObject> 
- (void)cancel:(id)sender; 
- (void)done:(id)sender; 
@end 

@interface TJDatePicker : UIDatePicker 
@property (strong, nonatomic) UIView *navInputView; 
@property (weak, nonatomic) id<TJDatePickerActionDelegate> actionDelegate; 
@end 

TJDatePicker.m

#import "TJDatePicker.h" 

@interface TJDatePicker() 
@property (strong, nonatomic) TJButton *cancelButton; 
@property (strong, nonatomic) TJButton *doneButton; 
@end 

@implementation TJDatePicker 

- (id)initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) 
    { 
     [self updateSubviews]; 
    } 

    return self; 
} 

- (void)layoutSubviews 
{ 
    [super layoutSubviews]; 

    [self updateSubviews]; 
} 

- (void)updateSubviews 
{ 
    self.navInputView.frame = CGRectMake(0, 0, self.width, 45); 
    self.cancelButton.frame = CGRectMake(5, 5, 80, 35); 
    CGFloat width = 80; 
    self.doneButton.frame = CGRectMake(CGRectGetMaxX(self.navInputView.frame) - width, self.cancelButton.frame.origin.y, width, self.cancelButton.height); 
} 

- (UIView *)navInputView 
{ 
    if (!_navInputView) 
    { 
     _navInputView = [[UIView alloc] init]; 
     _navInputView.backgroundColor = [UIColor whiteColor]; 

     self.cancelButton = [UIButton buttonWithType:UIButtonTypeCustom]; 
     [self.cancelButton setTitle:@"CANCEL" forState:UIControlStateNormal]; 
     [self.cancelButton addTarget:self action:@selector(cancelButtonPressed) forControlEvents:UIControlEventTouchUpInside]; 
     [_navInputView addSubview:self.cancelButton]; 

     self.doneButton = [UIButton buttonWithType:UIButtonTypeCustom]; 
     [self.doneButton setTitle:@"DONE" forState:UIControlStateNormal]; 
     [self.doneButton addTarget:self action:@selector(doneButtonPressed) forControlEvents:UIControlEventTouchUpInside]; 
     [_navInputView addSubview:self.doneButton]; 
    } 

    return _navInputView; 
} 

- (void)cancelButtonPressed 
{ 
    [self.actionDelegate cancel:self]; 
} 

- (void)doneButtonPressed 
{ 
    [self.actionDelegate done:self]; 
} 

E poi in fase di implementazione ...

self.datePicker = [[TJDatePicker alloc] init]; 
self.datePicker.actionDelegate = self; 
self.textField.inputAccessoryView = self.datePicker.navInputView; 

La chiave qui è quello di utilizzare la inputAccessoryView del UITextField che stai pianificando di impostare UIDatePicker su.

0

Nel caso in cui si sta lavorando su una tabella delle cellule di vista e non si utilizza un UITextField (quindi, si prevede di non utilizzare l'accessorio View), ecco quello che ho fatto:

ho creato una cella di vista tabella chiamata GWDatePickerCell che assomiglia a questo (nessun file .nib coinvolto).

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 

Ora tutto quello che dovevo fare quando si creano le celle della tabella Vista:

  • Specificare il @selector per il pulsante Done .
  • impostare l'altezza cella corretta in heightForRowAtIndexPath
1

Si ottiene il pulsante "Done" nella barra degli strumenti utilizzando l'ActionSheetPicker. È un'ottima alternativa alla costruzione di te stesso.

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

+0

Risolvere questo post con un commento del genere non è così amichevole ... –

+2

Per favore aiutami a capire come non è amichevole? Mi sono imbattuto in questa domanda alla ricerca di una risposta, e ho trovato che la migliore risposta per me era usare la libreria. Perché a qualcun altro non piacerebbe anche saperlo? –