I am dynamically adding data to a pickerview as information becomes available. Though I am adding data to my array and calling [picker reloadAllComponents] the pickerview does not show any data.
I also noticed that neither of the following Delegates are getting called:
- (NSString*)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
-(UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view{
Here is my viewDidLoad:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_pickerData = [[NSMutableArray alloc] init];
_ActiveDevice = [[NSString alloc]init];
// Connect data
self.DevicePicker.dataSource = self;
self.DevicePicker.delegate = self;
}
Here is the method that loads my hidden PickerView (I have it defaulted to hide until a button is pushed)
- (IBAction)FanDrop:(id)sender {
[self printFromCoreData];
[self.DevicePicker reloadAllComponents];
if (_DeviceBox) _DeviceBox.hidden = !_DeviceBox.hidden;
}
I load the array the is the datasource for the DevicePicker using what is found in coredata This all seems to work as I can find information when logging what is in the array. Also when clicking the accept button even though nothing is showing the correct data gets loaded thus telling me that everything but the display portion of my code is working correct.
Any insight - I'm open to try almost anything.
After one comment I realized I neglected to include, in my question, the delegates. SO here they are:
// The number of columns of data
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
// The number of rows of data
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return _pickerData.count;
}
// The data to return for the row and component (column) that's being passed in
- (NSString*)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
//return _pickerData[row];
return [_pickerData objectAtIndex:row];
}
-(UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view{
return [_pickerData objectAtIndex:row];
}
Here is how I am adding the array pickerData:
#interface CMTViewController ()
{
NSMutableArray *_pickerData;
}
Here is the CoreData method I use to load _pickerData:
-(void)printFromCoreData{
NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:#"DeviceData"];
self.devices = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];
for (NSManagedObject *info in _devices) {
NSString *item = [NSString stringWithFormat:#"%1$# %2$#",[info valueForKey:#"name"], [info valueForKey:#"ipAddress"]];
if (![_pickerData containsObject:item]) {
[_pickerData addObject:item];
}
}
NSLog(#"_pickerData length %lu", (unsigned long)[_pickerData count]);
[self.DevicePicker reloadAllComponents];
}
Here is the view of what happens in the simulator (or on my phone) when I push the fans button:
Fuji sir,
My recommendation would be as follows based on our conversation:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self printFromCoreData];
_ActiveDevice = [[NSString alloc]init];
// Connect data
self.DevicePicker.dataSource = self;
self.DevicePicker.delegate = self;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return _pickerData.count;
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
- (NSString*)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return _pickerData[row];
}
And don't include reusingView unless you want to change the layout and add custom labels etc
You need to add following methods
- (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{
return [_pickerData objectAtIndex:row];
}
}
Related
I have a UIPickerView which returns an NSArray with 4 strings. When the user scrolls the UIPickerView, a UITextField gets updated with the selected row. I would like to return the first character of each string in the NSArray and update the UITextField with that character.
As you can see from my code, I have tried to achieve this functionality by using self.noiseLevelArray = [noiseArray sortedArrayUsingSelector:#selector(caseInsensitiveCompare:)];, which I found on a few different stack overflow questions.
Here is the code for the picker:
// Noise picker
self.noisePicker = [[UIPickerView alloc]init];
[noisePicker setDataSource:self];
[noisePicker setDelegate:self];
self.noiseArray = [[NSArray alloc]initWithObjects:#"4: Extreme Noise (Impossible)", #"3: Very Noisy (Loud Shouting)", #"2: Noisy (Shouting)", #"1: Not Noisy (Normally)", nil];
//self.noiseLevelArray = [noiseArray sortedArrayUsingSelector:#selector(caseInsensitiveCompare:)];
// Call noisePicker method
[self noisePickerTextField];
Here is the code for my picker:
// Picker components
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
return [noiseArray count];
//return [noiseLevelArray count];
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
return [noiseArray objectAtIndex:row];
//return [noiseLevelArray objectAtIndex:row];
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
NSString *noiseString = [[NSString alloc]initWithFormat:#"%#", [noiseArray objectAtIndex:row]];
//NSString *noiseString = [noiseLevelArray objectAtIndex:0];
if ([self.empNoise1 isFirstResponder]) {
self.empNoise1.text = noiseString;
}
else if ([self.empNoise2 isFirstResponder]) {
self.empNoise2.text = noiseString;
}
...
As you can see, the UITextField gets updated with the full string of whichever row is selected in the UIPickerView. I would like it to still display the full string, but update the UITextField with the first character only (in this case 1, 2, 3, or 4). Any help is much appreciated!
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
NSString *noiseString = [[NSString alloc]initWithFormat:#"%#", [[noiseArray objectAtIndex:row] substringToIndex:1]];
//NSString *noiseString = [noiseLevelArray objectAtIndex:0];
if ([self.empNoise1 isFirstResponder]) {
self.empNoise1.text = noiseString;
}
else if ([self.empNoise2 isFirstResponder]) {
self.empNoise2.text = noiseString;
}
}
Try this. It uses the following method:
NSString * firstLetter = [word substringToIndex:1];
Try this.. `
self.empNoise1.text = [noiseString substringToIndex:1];`
Returns a new string containing the characters of the receiver up to, but not including, the one at a given index.
Link
Every example I find shows me how to populate a UIPickerView in viewDidLoad. However, when I try to populate the picker with items from an HTTP Request in another function, it ends up being blank (even though I've tested that the data actually does come back as I want it).
- (IBAction)btnClick:(id)sender
{
NSDictionary *courseNames;
if(![_txtBox.text isEqual:#""]) //if not empty
{
courseNames = [self retrieveCourseNamesForSemester:_txtBox.text];
for (NSString *key in courseNames)
{
NSString *val = [NSString stringWithFormat:#"%# - %#",key,[courseNames objectForKey:key]];
_txtView.text = val;
[courseArray addObject:val];
}
}
_coursePicker.hidden=false;
[_txtBox resignFirstResponder];
}
_coursePicker is created on the storyboard itself, so it's not added programmatically or anything. I'm adding to the array courseArray, which is assigned in the UIPickerView methods, as follows:
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
//set number of rows
return courseArray.count;
}
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return [courseArray objectAtIndex:row];
}
How do I repopulate the UIPickerView at this point?
After you get your data and before _coursePicker.hidden = NO; try calling
[_coursePicker reloadAllComponents];
That should make the picker repopulate with your data.
Hi I have one picker view. This picker view from web services came
to loading data. This picker view is 2 part. Picker view 1. part is
Project name. and Picker view 2. part is Project number. When open
screen Project no label is no data. when open screen Project name
label no data. But when i rotate my picker view came to data this like
Proje Adı: "A1 Unitesi" Proje No: "002". How i can When open screen
came to data like rotate my picker ?
When open screen Project Name and Project No Labels no data. I want
to came data when open screen
When I rotate picker view came to data like this.
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 2;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
if (component == 0) {
return [RaporlarList count];
}
return [RaporlarList count];
}
#pragma mark Picker Delegate Methods
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
if (component == 0) {
eObje = [RaporlarList objectAtIndex:row];
return eObje.ProjeAdii;
}
eObje = [RaporlarList objectAtIndex:row];
return eObje.ProjeNoo;
}
#pragma mark -
#pragma mark PickerView Delegate
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if (component == 0)
{
NSString *resultString = [[NSString alloc] initWithFormat:#"Proje Adı : %#", [[RaporlarList objectAtIndex:row] ProjeAdii]];
lblProjeAdi.text = [NSString stringWithFormat:#"%#", resultString];
}
else
{
NSString *resultString = [[NSString alloc] initWithFormat:#"Proje No: %#", [[RaporlarList objectAtIndex:row] ProjeNoo]];
lblProjeNo.text = resultString;
}
}
You have selected wrong datasource for pickerview.
You are returning string, instead return the label
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component
{
// return your UILabel
}
The correct answer to my question is as follows:
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if (component == 0)
{
NSString *resultString = [[NSString alloc] initWithFormat:#"Proje Adı : %#", [[RaporlarList objectAtIndex:row] ProjeAdii]];
lblProjeAdi.text = [NSString stringWithFormat:#"%#", resultString];
}
else
{
NSString *resultString = [[NSString alloc] initWithFormat:#"Proje No: %#", [[RaporlarList objectAtIndex:row] ProjeNoo]];
lblProjeNo.text = resultString;
}
}
I have 2 picker views on my story board, everything done separately. However for some reason my second viewer is exactly copying the first one.
#import <UIKit/UIKit.h>
#interface MaisOuiViewController : UIViewController <UITextFieldDelegate, UIPickerViewDataSource, UIPickerViewDelegate>
#property (strong, nonatomic) IBOutlet UIPickerView *from;
#property (strong, nonatomic) IBOutlet UIPickerView *to;
#property (strong, nonatomic) NSArray * fromlang;
#property (strong,nonatomic) NSArray * tolang;
#end
#synthesize from;
#synthesize to;
#synthesize fromlang = _fromlang;
#synthesize tolang= _tolang;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.inWord.delegate = self;
//Load NSArray fromlang
_fromlang= [[NSArray alloc] initWithObjects:#"English",#"Spanish",#"German", nil];
//Load NSArray tolang
_tolang= [[NSArray alloc] initWithObjects:#"Hindi",#"Chinese",#"Check", nil];
}
#pragma mark - UIPickerView Methods
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
- (NSInteger)numberOfComponentsInPickerView1:(UIPickerView *)pickerView1
{
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return _fromlang.count;
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return [_fromlang objectAtIndex:row];
}
- (NSInteger)pickerView1:(UIPickerView *)pickerView1 numberOfRowsInComponent1:(NSInteger)component1
{
return _tolang.count;
}
- (NSString *)pickerView1:(UIPickerView *)pickerView1 titleForRow:(NSInteger)row forComponent1:(NSInteger)component1
{
return [_tolang objectAtIndex:row];
}
#end
Can somebody please point out where am I going wrong ?
Thanks
The UIPickerViews from and to looks same because the delegate and datasource methods are same. iOS will call only the methods which are mentioned below as per the apple iOS documents refers
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return _fromlang.count;
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return [_fromlang objectAtIndex:row];
}
You can instead set tag for to and from and use the code mentioned below
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.inWord.delegate = self;
//Set tags to differentiate
from.tag=1;
to.tag=2;
//Load NSArray fromlang
_fromlang= [[NSArray alloc] initWithObjects:#"English",#"Spanish",#"German", nil];
//Load NSArray tolang
_tolang= [[NSArray alloc] initWithObjects:#"Hindi",#"Chinese",#"Check", nil];
}
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
if(pickerView.tag==1)
{
return 1;
}
else
{
return 1;
}
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
if(pickerView.tag==1)
{
return _fromlang.count;
}
else
{
return _tolang.count;
}
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
if(pickerView.tag==1)
{
return [_fromlang objectAtIndex:row];
}
else
{
return [_tolang objectAtIndex:row];
}
}
Hope this will help.
If you have two buttons to show that then take one integer variable and set some value or take BOOL value to make the difference or set the tag of your picker then after based on your condition call your array in picker view.
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
NSString *titleString;
if (currentSelectedDropDown == 1) {
AIFillAccountTypeParserModel *modal = [[AIFillAccountTypeParserModel alloc]init];
if (isSearching) {
modal = [filteredArray objectAtIndex:row];
}else{
modal = [accountTypesPickerArray objectAtIndex:row];
}
titleString = modal.accountType;
accountTypeTxtField.text = titleString;
}
else if(currentSelectedDropDown == 2) {
AIFillRatingParserModel *modal = [[AIFillRatingParserModel alloc]init];
if (isSearching) {
modal = [filteredArray objectAtIndex:row];
}else{
modal = [accountTypesPickerArray objectAtIndex:row];
}
titleString = modal.rating_Description;
ratingTxtField.text = titleString;
}
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if (currentSelectedDropDown == 1) {
AIFillAccountTypeParserModel *modal = nil;
if (isSearching) {
modal = [filteredArray objectAtIndex:row];
}
else{
modal = [accountTypesPickerArray objectAtIndex:row];
}
NSString *titleString = modal.accountType;
accountTypeTxtField.text = titleString;
accountTypeId = modal.accountId;
NSUserDefaults *accountType = [NSUserDefaults standardUserDefaults];
[accountType setObject:modal.accountId forKey:#"SavedaccountType"];
}
else if (currentSelectedDropDown == 2) {
AIFillOwnershipParserModel *modal = nil;
if (isSearching) {
modal = [filteredArray objectAtIndex:row];
}
else{
modal =[accountTypesPickerArray objectAtIndex:row];
}
NSString *titleString = modal.ownership;
ownershipTypeTxtField.text = titleString;
ownerShipId = modal.ownerShipID;
}
}
This is just a example to make you understand
I want to show some color name in PickerView, which are constant from UIColr class
pickerContent = [[NSArray alloc] initWithObjects:[UIColor redColor],[UIColor orangeColor],[UIColor purpleColor],[UIColor yellowColor], nil ];
and my implemented function for PickerView label is
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return [(UIColor *)[self.pickerContent objectAtIndex:row] description];
}
i Know description will not give me my desired output.
so please help with your valuable suggestion.
if you want to Show only colour names in Picker view Then Just take another NSArray
NSArray *colourArray=[[NSArray alloc] initWithObjects:#"redColor",#"orangeColor",#"purpleColor",#" yellowColor", nil ];
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{ return [colourArray objectAtIndex:row];
}