I've been looking and trying all the code examples provided for this issue, however i cannot seem to get it working. This is my first time making an app (besides from completing tutorials) so forgive me for asking a 'stupid' question. I'm just a newbie.
I'm trying to create an iOS App to register the starting & end time, the type of service and the customer. As soon as the user taps the UITextField the UIPicker pops-up displaying the information. I was able to create UIDatePicker for the start and end time, and an empty UIPickerView for service and customer.
The problem i've encountered is that i'm trying to add the names of the customers and the types of services to the UIPickerView for each. However so far without success. I've tried doing so with adding an array, but nothing shows up in the UIPickerView. In the storyboard i've added 4 lables and 4 UITextFields for each item.
The code for .h looks like this:
@interface ViewController : UIViewController <UIPickerViewDataSource, UIPickerViewDelegate> {
UIDatePicker *datePicker;
UIDatePicker *datePicker2;
NSArray *dienstArray;
NSArray *klantArray;
}
@property (strong, nonatomic) IBOutlet NSArray *dienstArray; //Service Array
@property (strong, nonatomic) IBOutlet NSArray *klantArray; //Customer Array
@property (weak, nonatomic) IBOutlet UIPickerView *dienstPicker; //Service PickerView
@property (weak, nonatomic) IBOutlet UIPickerView *klantPicker; //Customer PickerView
@property (weak, nonatomic) IBOutlet UITextField *dienstTextField; //Service TextField
@property (weak, nonatomic) IBOutlet UITextField *klantTextField; //Customer TextField
@property (weak, nonatomic) IBOutlet UITextField *dateSelectionTextField; //BeginDate TextField
@property (weak, nonatomic) IBOutlet UITextField *dateSelectionTextField2; //EndDate TextField
@end
This is the code of .m @interface ViewController () @end
@implementation ViewController
@synthesize dienstPicker;
@synthesize klantPicker;
@synthesize klantArray;
@synthesize dienstArray;
- (void)viewDidLoad {
[super viewDidLoad];
//BeginDatumTijdPicker
datePicker=[[UIDatePicker alloc]init];
datePicker.datePickerMode=UIDatePickerModeDateAndTime;
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"NL"]; //Date notation 24hours
[datePicker setLocale: locale];
// Styling for the UIPickerView
[self.dateSelectionTextField setInputView:datePicker]; //shows the UIPickerView
UIToolbar *toolBar=[[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, 320, 44)];
[toolBar setTintColor:[UIColor grayColor]];
UIBarButtonItem *doneBtn=[[UIBarButtonItem alloc]initWithTitle:@"Done" style:UIBarButtonItemStylePlain target:self action:@selector(ShowSelectedDate1)]; //When clicked "Done" the UIPickerView disappears.
UIBarButtonItem *space=[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
[toolBar setItems:[NSArray arrayWithObjects:space,doneBtn, nil]];
[self.dateSelectionTextField setInputAccessoryView:toolBar];
//EindDatumTijdPicker
// [Same as BeginDatumTijdPicker but different names]
//DienstPicker
dienstPicker =[[UIPickerView alloc] init];
dienstArray = [[NSArray alloc] initWithObjects: @"test1", @"test2", @"test3", @".....", nil];
self.dienstPicker.delegate = self;
self.dienstPicker.dataSource = self;
self.dienstPicker.showsSelectionIndicator = YES;
// Styling for the UIPickerView
[self.dienstTextField setInputView:dienstPicker]; //shows the UIPickerView
UIToolbar *toolBar3 = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, 320, 44)];
[toolBar3 setTintColor:[UIColor grayColor]];
UIBarButtonItem *doneBtn3=[[UIBarButtonItem alloc]initWithTitle:@"Done" style:UIBarButtonItemStylePlain target:self action:@selector(ShowSelectedDienst)]; //When clicked "Done" the UIPickerView disappears.
UIBarButtonItem *space3 = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
[toolBar3 setItems:[NSArray arrayWithObjects:space3,doneBtn3,nil]];
[self.dienstTextField setInputAccessoryView:toolBar3];
//KlantPicker
klantPicker =[[UIPickerView alloc] init];
klantArray = [[NSArray alloc] initWithObjects: @"test1.1", @"test2.1", @"test3.1", @".....", nil];
self.klantPicker.delegate= self;
self.klantPicker.dataSource = self;
self.klantPicker.showsSelectionIndicator = YES;
// Styling for the UIPickerView
[self.klantTextField setInputView:klantPicker]; //shows the UIPickerView
UIToolbar *toolBar4 = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, 320, 44)];
[toolBar4 setTintColor:[UIColor grayColor]];
UIBarButtonItem *doneBtn4 =[[UIBarButtonItem alloc]initWithTitle:@"Done" style:UIBarButtonItemStylePlain target:self action:@selector(ShowSelectedKlant)]; //When clicked "Done" the UIPickerView disappears.
UIBarButtonItem *space4 = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
[toolBar4 setItems:[NSArray arrayWithObjects:space4,doneBtn4,nil]];
[self.klantTextField setInputAccessoryView:toolBar4];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
//ShowSelectedService (When clicking the "Done" button, the UIPickerView disappears. )
-(void)ShowSelectedDienst{
[self.dienstTextField resignFirstResponder];
}
//ShowSelectedClient (When clicking the "Done" button, the UIPickerView disappears. )
-(void)ShowSelectedKlant{
[self.klantTextField resignFirstResponder];
}
// The code below
// works just fine.
//DatePicker Begin tijd
-(void)ShowSelectedDate1 {
NSDateFormatter *formatter=[[NSDateFormatter alloc]init];
[formatter setDateFormat:@"dd MMM HH:mm"]; //formats date & time
self.dateSelectionTextField.text=[NSString stringWithFormat:@"%@",[formatter stringFromDate:datePicker.date]];
[self.dateSelectionTextField resignFirstResponder];
}
//!!DatePicker Eind tijd!!
//Same as DatePicker Begin Tijd.
@end
I'm hoping everything is clear and that someone can help me. this is what the app looks like:
When the Service textfield is clicked the UIPickerView pops up.
It seems, that nowhere in your code you set the delegate and data source of the UIPickerView
. Without them, the picker view doesn't know what to display and how to inform you that the user has selected something.
Please take a look here : UIPickerViewDataSource and here UIPickerViewDelegate and let me know if something is not clear or you run into trouble implementing these.
Here is an example :
@interface ViewController () <UIPickerViewDelegate, UIPickerViewDataSource> //#1
@property (nonatomic, strong) UITextField *textField;
@property (nonatomic, strong) UIPickerView *pickerView;
@property (nonatomic, strong) NSArray *pickerNames;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.pickerView = [[UIPickerView alloc] init];
self.pickerView.delegate = self; //#2
self.pickerView.dataSource = self; //#2
self.textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 100, CGRectGetWidth(self.view.frame), 50)];
self.textField.borderStyle = UITextBorderStyleRoundedRect;
self.textField.placeholder = @"What's your favourite programming language?";
self.textField.inputView = self.pickerView;
self.pickerNames = @[ @"Objective-C", @"Swift", @"Java", @"C", @"C++", @"Other"];
[self.view addSubview:self.textField];
}
#pragma mark - UIPickerViewDataSource
// #3
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
if (pickerView == self.pickerView) {
return 1;
}
return 0;
}
// #4
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
if (pickerView == self.pickerView) {
return [self.pickerNames count];
}
return 0;
}
#pragma mark - UIPickerViewDelegate
// #5
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
if (pickerView == self.pickerView) {
return self.pickerNames[row];
}
return nil;
}
// #6
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
if (pickerView == self.pickerView) {
self.textField.text = self.pickerNames[row];
}
}
@end
Okay, here are the interesting parts :
Here we declare that we will be conforming to UIPickerViewDelegate
and UIPickerViewDataSource
protocols. A protocol is in its basic a set of method headers. When you declare that you will conform to a protocol, you need to implement them (those that are required at least).
This is quite obvious, we tell the picker that we will be its delegate and datasource. If we didn't declare conformance to the protocols before, the compiler would start giving us errors here.
This method from UIPickerViewDataSource
will be called to know how many components should be displayed. A date picker has typicaly 3 components (day, month, year) for example.
This method wants to know how many elements there will be in every component.
This method is where you actually provide the texts to display to the user. You could also implement one of the other two variations of this method to provide either an attributed text or a totally custom view.
This method gets called when the animation stops on a new item.
The checks for pickerView == self.pickerView
are not needed in this example. I have added them, so that you'd know how to decide for which picker (as you have 4 it seems) to return the information needed. Ideally, this would need some further refactoring, as it is not the best idea to have cluttered delegates/data sources.