I have this code to add a datepicker:
// Initiate datepicker and assign to due date
_datePicker = [[UIDatePicker alloc] init];
[_datePicker addTarget:self action:#selector(dateChanged:)
forControlEvents:UIControlEventValueChanged];
_datePicker.minuteInterval = 15;
_dueDate.inputView = _datePicker;
I tried to do the same thing with a pickerview but I had no success, could somebody explain why?
Here is my code:
// Initaite the pickerview and assign to priority text field
_priorityPickerView = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 200, 320, 200)];
// Array otions for priority picker
NSArray *array = [[NSArray alloc] initWithObjects:#"High",#"Medium",#"Low", nil];
self.priorityPickerData = array;
// Connect text field to pickerview
_priority.inputView = _priorityPickerView;
Here is the data set in the picker view:
// Picker View functions
-(NSInteger)numberOfComponantsInPickerView:(UIPickerView *)pickerView{
return 1;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
return [_priorityPickerData count];
}
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{
return [self.priorityPickerData objectAtIndex:row];
}
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
int select = row;
if(select == 0){
_priority.text = #"High";
}else if(select == 1){
_priority.text = #"Medium";
}else if(select == 2){
_priority.text = #"Low";
}
}
Many thanks in advance,
Peter
Set the delegate and datasource to self:
_priorityPickerView.delegate = self;
_priorityPickerView.dataSource = self;
Also at the top of your .m file:
#interface YourViewController ()<UIPickerViewDataSource,UIPickerViewDelegate>
Related
I am trying to prevent my UIPickerview from closing when a field is selected by a user. I want the user to be able to select a field without UIPickerview dismissing automatically. I have tried so many things such as trying the following but none of them helped:
_txtfield.hidden=NO;
[_pickerView endEditing:NO];
[pickerView endEditing:NO];
[_txtfield endEditing:NO];
[self endEditing:NO];
_pickerView.hidden=NO;
-----------------Here is more code----------------
#implementation FieldWithPickerView {
void(^pickerCallback)(NSInteger row);
CGRect myFrame;
}
-(void)viewDidAppear{
}
-(void)commonInit:(CGRect)frame{
[[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class]) owner:self options:nil];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[view]|" options:0 metrics:nil views:#{#"view":self.InputViewPicker}]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[view]|" options:0 metrics:nil views:#{#"view":self.InputViewPicker}]];
[self.layer setCornerRadius:10.0f];
[self setClipsToBounds:YES];
_pickerView = [[UIPickerView alloc] init];
_pickerView.delegate=self;
UIToolbar *toolBar=[[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, 320, 44)];
[toolBar setTintColor:[UIColor grayColor]];
UIBarButtonItem *doneBtn=[[UIBarButtonItem alloc]initWithTitle:#"Done" style:UIBarButtonItemStyleBordered target:self action:#selector(removePicker)];
UIBarButtonItem *space=[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
[toolBar setItems:[NSArray arrayWithObjects:space,doneBtn, nil]];
[self.txtfield setInputAccessoryView:toolBar];
self.txtfield.inputView = _pickerView;
[_txtfield.inputView setBackgroundColor:[UIColor clearColor]];
[_txtfield setBackgroundColor:[UIColor clearColor]];
_txtfield.text=#"--Select---";
_label_view.textColor=[UIColor whiteColor];
_label_view.backgroundColor=SECURUSBLUE;
_label_view.textAlignment = NSTextAlignmentCenter;
_txtfield.textAlignment = NSTextAlignmentCenter;
}
-(void)removePicker
{
[_txtfield resignFirstResponder];
}
-(void)pickerListenner:(void(^)(NSInteger row))handler
{
pickerCallback=handler;
}
- (id)initWithFrame:(CGRect)frame
{
// NSLog(#"initwithframe picker");
self = [super initWithFrame:frame];
if (self)
{
[self commonInit:frame];
}
return self;
}
#pragma mark - Picker View Data source
- (NSInteger)numberOfComponentsInPickerView:
(UIPickerView *)pickerView
{
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView
numberOfRowsInComponent:(NSInteger)component
{
return [_pickerData count];;
}
- (NSString *)pickerView:(UIPickerView *)pickerView
titleForRow:(NSInteger)row
forComponent:(NSInteger)component
{
if(_pickerData.count == 0)
return #"There is nothing";
return [_pickerData objectAtIndex:row];
}
#pragma mark -
#pragma mark - UIPickerViewDelegate
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
// Code logic
NSLog(#"selected row --->%ld!!!!",(long)row);
pickerCallback(row);
// _txtfield.text=[_pickerData objectAtIndex:row];
_txtfield.hidden=NO;
}
- (NSInteger)selectedRowInComponent:(NSInteger)component
{
return component;
}
You need to implement the UIPickerView delegate methods, so add <UIPickerViewDelegate> to your ViewController.
in your viewDidLoad method conform to the protocol like so:
pickerView.delegate = self;
Then add the following method to detect when a row has been selected:
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
// do nothing because it will not dismiss
}
You will need to implement the numberOfRowsInComponent, numberOfComponents, and titleForRow delegate methods as well, but once those are implemented your picker view should not dismiss when a row is selected. You will need to manually dismiss the picker view in your didSelectRow delegate method.
I'm a beginner in iOS Objective-C programming so first of all - sorry for being silly.
I'm using UIPickerView to fill UITextField and it works perfectly for the first use.
photo
Lets assume that user made a mistake using pickerview for the first time. He wants to correct this and opens the same pickerview again. Pickerview is empty.
photo
Also okayButton is missing. What am I doing wrong?
Here's my code:
#import "LoginViewController.h"
#interface LoginViewController ()
#end
#implementation LoginViewController
- (void)viewDidLoad {
[super viewDidLoad];
marksArray =[[NSMutableArray alloc] init];
fuelTypeArray =[[NSMutableArray alloc] init];
inputArray =[[NSMutableArray alloc] init];
marksArray = [NSMutableArray arrayWithObjects:#"Alfa Romeo", #"Aston Martin", #"BMW", #"Cadillac", #"Chevrolet", #"Chrysler", #"Citroen", #"Dacia", #"Daewoo", #"Dodge", #"Ferrari", #"Ford", #"Honda", #"Hummer", #"Hyundai", #"Infiniti", #"Jaguar", #"Jeep", #"Kia", #"Lamborghini", #"Lancia", #"Land Rover", #"Lexus", #"Maserati", #"Mazda", #"Mercedes-Benz", #"Mini", #"Mitsubishi", #"Nissan", #"Opel", #"Peugeot", #"Polonez", #"Pontiac", #"Porshe", #"Renault", #"Rover", #"Saab", #"Seat", #"Skoda", #"Smart", #"Subaru", #"Suzuki", #"Toyota", #"Volkswagen", #"Volvo", nil];
fuelTypeArray = [NSMutableArray arrayWithObjects:#"Benzyna", #"Benzyna+LPG", #"Diesel", #"Elektryczny", #"Hybryda", nil];
okayImageView.hidden = true;
okayButton.hidden= true;
//makes fuelTypePickerView as input console for markTextField
fuelTypePickerView.hidden = true;
fuelTypePickerView = [[UIPickerView alloc] init];
fuelTypePickerView.delegate = self;
fuelTypePickerView.showsSelectionIndicator = YES;
fuelTypeTextField.inputView = fuelTypePickerView;
//makes markPickerView as input console for markTextField
markPickerView.hidden = true;
markPickerView = [[UIPickerView alloc] init];
markPickerView.delegate = self;
markPickerView.showsSelectionIndicator = YES;
markTextField.inputView = markPickerView;
// scrolling login view controller
[scroller setScrollEnabled:YES];
[scroller setContentSize:CGSizeMake(320, 615)];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
// returns the number of 'columns' to display.
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
okayImageView.hidden = false;
okayButton.hidden= false;
return 1;
}
// returns the # of rows in each component..
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
if([pickerView isEqual: markPickerView]){
return 45;
}else if([pickerView isEqual: fuelTypePickerView]){
return 5;
}else{
return 0;
}
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{
if([pickerView isEqual: markPickerView]){
self->inputArray = self->marksArray;
return inputArray[row];
}else if([pickerView isEqual: fuelTypePickerView]){
self->inputArray = self->fuelTypeArray;
return inputArray[row];
}else{
return 0;
}
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if([pickerView isEqual: markPickerView]){
markTextField.text = [inputArray objectAtIndex:row];
}else if([pickerView isEqual: fuelTypePickerView]){
fuelTypeTextField.text = [inputArray objectAtIndex:row];
}
}
-(IBAction) okayButtonPressed:(id)sender{
if(markPickerView.hidden!=YES){
okayImageView.hidden = true;
okayButton.hidden= true;
markPickerView.hidden=YES;
[markTextField resignFirstResponder];
}else if(fuelTypePickerView.hidden!=YES){
okayImageView.hidden = true;
okayButton.hidden= true;
fuelTypePickerView.hidden=YES;
[fuelTypeTextField resignFirstResponder];
}
}
#end
Thanks!
Try adding the following lines in your code
#interface LoginViewController () <UITextFieldDelegate>
then in viewDidLoad
fuelTypeTextField.delegate = self;
markTextField.delegate = self;
Now implement UITextField Delegate in your LoginViewController
-(void)textFieldDidBeginEditing:(UITextField *)sender{
okayImageView.hidden = NO;
okayButton.hidden = NO;
if([sender isEqual:fuelTypeTextField])
{
fuelTypePickerView.hidden = NO;
}
else{
markPickerView.hidden = NO;
}
}
In your Code after click on OK button you are hiding the PickerView, ImageView and Button. But on next time editing the textField you are not unhiding them thats why they are not shown.
I'm using the custom MZFormSheetController to use the custom "alert view". I have a button when I press it, it opens the MZFormSheetController and allows me to select a specific title for this button from UIPickerView. When I select the title from the picker, it is send to the viewController that contains the button by setNeedsDisplay
I want to change the title of the button with the selected title from the pickerView. I wrote the code but the title of the button doesn't updated..
In the button's viewController, The action of the button:
-(IBAction)openSelectCountries:(id)sender{
UIViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"countriesPickerViewController"];
MZFormSheetController *formSheet = [[MZFormSheetController alloc] initWithViewController:vc];
formSheet.transitionStyle = MZFormSheetTransitionStyleSlideFromTop;
formSheet.shadowRadius = 2.0;
formSheet.shadowOpacity = 0.3;
formSheet.shouldDismissOnBackgroundViewTap = YES;
formSheet.shouldCenterVerticallyWhenKeyboardAppears = YES;
[formSheet presentAnimated:YES completionHandler:^(UIViewController *presentedFSViewController) {
}];
}
in viewDidLoad:
// selectedCountryIndex2 is a static NSString
if (selectedCountryIndex != 0) {
selectedCountryIndex2 = selectedCountryIndex;
}
NSLog(#"selectedCountryIndex2: %d", selectedCountryIndex2);
if (selectedCountryIndex2 == 0) {
NSLog(#"no country selected");
}else{
NSLog(#"the selected country: %#", [countryArray objectAtIndex:selectedCountryIndex2]);
[countrySelect setTitle:[countryArray objectAtIndex:selectedCountryIndex2] forState: UIControlStateNormal];
}
in CountriesPickerViewController.m:
- (NSInteger) numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 1;
}
- (NSInteger) pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
return [countryArray count];
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
return [countryArray objectAtIndex:row];
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
NSLog(#"in pickerView: %#", [countryArray objectAtIndex:row]);
ContactUsViewController *contactUsViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"contactUsViewController"];
contactUsViewController.selectedCountry = [countryArray objectAtIndex:row];
contactUsViewController.selectedCountryIndex = row;
[contactUsViewController.view setNeedsDisplay];
// to close the custom dialog
UIViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"countriesPickerViewController"];
MZFormSheetController *formSheet = [[MZFormSheetController alloc] initWithViewController:vc];
[formSheet dismissFormSheetControllerAnimated:YES completionHandler:nil];
}
The expected thing is that the countrySelect button change its title when selectedCountryIndex2 is not equal 0 but this never happen although that the title is passed successfully and I got it by NSLog.
I have a UIPickerView that is being "pushed" to UINavigationController like this:
[self.navigationController pushViewController:vc animated:YES];
I would like to set the selected row.
I added in ViewDidAppear:
for (int i = 0; i < [countryCodes count]; i++)
{
if ([[countryCodes objectAtIndex:i] isEqualToString:selectedCountryCode]){
[_countryPicker selectRow:i inComponent:0 animated:YES];
countrySelectedRow = i;
break;
}
}
[_countryPicker reloadAllComponents];
where i is dynamic (being changed based on data that is changing in that view controller)
It works only if I restart the app.
If I go back and forth in the navigation it doesn't work
How can I make the UIPickerView choose the the correct row?
I can see in debug mode that the lines in viewDidAppear are called. Maybe the component is being created and I can't change it?
This is how I create the UIPickerView:
- (void)viewDidLoad
{
_countryPicker = [[UIPickerView alloc] init];
[self initPicker:_countryPicker textField:_countryText];
}
- (void)initPicker:(UIPickerView*)pickerView textField:(UITextField*) textField
{
CGRect pickerFrame = CGRectMake(0, 0, 200, 216);
pickerView.frame = pickerFrame;
pickerView.userInteractionEnabled = YES;
pickerView.dataSource = self;
pickerView.hidden = YES;
pickerView.delegate = self;
pickerView.showsSelectionIndicator = YES;
[self.view addSubview:pickerView];
[textField setInputView:pickerView];
textField.delegate = self;
[pickerView removeFromSuperview];
}
You wrote: "where i is dynamic (being changed based on data that is changing in that view controller)""
In your code i is a local variable. Did you mean selectedCountryCode here?
for (int i = 0; i < [countryCodes count]; i++)
{
if ([[countryCodes objectAtIndex:i] isEqualToString:selectedCountryCode]){
[_countryPicker selectRow:i inComponent:0 animated:YES];
countrySelectedRow = i;
break;
}
}
[_countryPicker reloadAllComponents];
I am pretty sure selectedCountryCode is not updated correctly. Add NSLog(selectedCountryCode); to check it.
UPDATE:
It seems that problem is somewhere inside a code you did not post in the question. To check your code I created and share a project. Please find it here https://github.com/Avtolic/SOHelper If you will check it you will find that everything works ok.
After you set the selected row you then call this...
[_countryPicker reloadAllComponents];
Thats going to wipe out your selection? I would remove that line
If you make the selectedCountryCode variable part of a singleton class (for example AppDelegate or preferebly some other), and then equate the value, this is surely going to work. Here I don't understand how the selectedCountryCode is expected to be retained even after the view is popped.
I tried with making the string a part of AppDelegate (which is of course not a good practice. One should put it in another singleton class).
#import "CViewController.h"
#import "AppDelegate.h"
#interface CViewController ()<UITextFieldDelegate, UIPickerViewDelegate, UIPickerViewDataSource>
#property(nonatomic, strong) UIPickerView *countryPicker;
#property (nonatomic, weak) IBOutlet UITextField *countryText;
#property (nonatomic, strong) NSArray *countryCodes;
#property (nonatomic, assign) int countrySelectedRow;
#property (nonatomic,strong) AppDelegate *delegate;
#end
#implementation CViewController
- (void)viewDidLoad
{
self.delegate = [[UIApplication sharedApplication] delegate];
_countryPicker = [[UIPickerView alloc] init];
[self initPicker:_countryPicker textField:_countryText];
self.countryCodes = #[#"A", #"B", #"C", #"D", #"E"];
}
- (void)initPicker:(UIPickerView*)pickerView textField:(UITextField*) textField
{
CGRect pickerFrame = CGRectMake(0, 0, 200, 216);
pickerView.frame = pickerFrame;
pickerView.userInteractionEnabled = YES;
pickerView.dataSource = self;
pickerView.hidden = YES;
pickerView.delegate = self;
pickerView.showsSelectionIndicator = YES;
[self.view addSubview:pickerView];
[textField setInputView:pickerView];
textField.delegate = self;
[pickerView removeFromSuperview];
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return [self.countryCodes objectAtIndex:row];
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
// returns the # of rows in each component..
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return [self.countryCodes count];
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
self.delegate.selectedCountryCode = [self.countryCodes objectAtIndex:row];
NSLog(#"picker was(is): %d",[_countryPicker selectedRowInComponent:0]);
}
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
for (int i = 0; i < [self.countryCodes count]; i++)
{
if ([[self.countryCodes objectAtIndex:i] isEqualToString:self.delegate.selectedCountryCode]){
[_countryPicker selectRow:i inComponent:0 animated:YES];
self.countrySelectedRow = i;
break;
}
}
[_countryPicker reloadAllComponents];
}
-(void)textFieldDidBeginEditing:(UITextField *)textField
{
self.countryPicker.hidden = NO;
}
I have created two UITextFields and want to create two different UIPickerViews for both the textFields with different values and how to map the individual textFields to each pickerView specifically?
any help ?
how about textField.inputview, to select the option for your respectively like this.
textField.inputView = pickerView1;
textField1.inputView = pickerView2;
If I write a code in this situation, then instead of creating two pickerView, I will create a one pickerview and change the datasource for each textfield
First of all create two array that contain different value that you want to display in the diff picker, we say aray1 and ary2 .
Now add this in .h file
#interface YourViewController : UIViewController<UITextFieldDelegate,UIPickerViewDelegate, UIPickerViewDataSource>
{
UIToolbar* keyboardDoneButtonView;
UIPickerView *pickerView;
NSString * txtFieldSelected;
NSArray *ary2;
NSArray *ary1;
}
And in .h file
- (void)viewDidLoad
{
[super viewDidLoad];
firstTF.delegate = self;
secondTF.delegate = self;
ary1 =[NSArray arrayWithObjects:#"1",#"2",#"3",#"4",#"5",#"6",#"7",#"8", nil];
ary2 =[NSArray arrayWithObjects:#"a",#"s",#"d",#"f",#"g",#"h",#"x",#"c", nil];
}
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
if (textField == firstTF) {
txtFieldSelected = #"firstTF";
}else if (textField == secondFF) {
txtFieldSelected = #"secondTF";
}
CGRect pickerFrame = CGRectMake(0, 40, 0, 0);
pickerView = [[UIPickerView alloc] initWithFrame:pickerFrame];
pickerView.showsSelectionIndicator = YES;
pickerView.dataSource = self;
pickerView.delegate = self;
keyboardDoneButtonView = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
keyboardDoneButtonView.barStyle = UIBarStyleBlackTranslucent;
[keyboardDoneButtonView sizeToFit];
NSMutableArray *barItems = [[NSMutableArray alloc] init];
UIBarButtonItem *cancelBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:#selector(cancelButtonPressed:)];
[barItems addObject:cancelBtn];
UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
[barItems addObject:flexSpace];
UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(doneButtonPressed:)];
[barItems addObject:doneBtn];
[keyboardDoneButtonView setItems:barItems animated:YES];
textField.inputAccessoryView = keyboardDoneButtonView;
textField.inputView = pickerView;
return YES;
}
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component;
{
if (txtFieldSelected == #"firstTF") {
return ary1.count;
}else if (txtFieldSelected == #"secondTF") {
return ary2.count;
}
return 1;
}
-(void)doneButtonPressed:(id)sender{
if (txtFieldSelected == #"firstTF") {
[firstTF resignFirstResponder];
}else if (txtFieldSelected == #"secondTF") {
[secondTF resignFirstResponder];
}
}
-(void)cancelButtonPressed:(id)sender{
if (txtFieldSelected == #"firstTF") {
[firstTF resignFirstResponder];
}else if (txtFieldSelected == #"secondTF") {
[secondTF resignFirstResponder];
}
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow: (NSInteger)row inComponent:(NSInteger)component {
// called when a row is selected
if (txtFieldSelected == #"firstTF") {
firstTF.text = [ary1 objectAtIndex:row];
}else if (txtFieldSelected == #"secondTF") {
secondTF.text = [ary2 objectAtIndex:row];
}
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
if (txtFieldSelected == #"firstTF") {
return [ary1 objectAtIndex:row];
}else if (txtFieldSelected == #"secondTF") {
return [ary2 objectAtIndex:row];
}
return #"Good Day";
}
textField1.inputView = pickerView1;
textField2.inputView = pickerView2;
pickerView.tag = 1;
pickerView.tag = 2;
Use UIPickerView delegate methods with tags.