I need to create three independent pickerView's. The first pickerView is categoryPickerView. When a value is selected it should load other 2 pickerView's (productPickerview and modelPickerview) are not loading the data correctly.
The didSelectRow callback is being fired but my NSLog's have shown that its not getting passed the first if statement checking if its equal to "Audio"
For catogeryPickerView I have written following array for it in viewDidLoad:-
devicecatogery=[[NSArray alloc]initWithObjects:#"Audio",#"Video", nil];
//code for numeric keypad done button
UIToolbar* numberToolbar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 44, 320, 300)];
numberToolbar.barStyle = UIBarStyleBlackTranslucent;
numberToolbar.items = [NSArray arrayWithObjects:
[[UIBarButtonItem alloc]initWithTitle:#"Cancel" style:UIBarButtonItemStyleBordered target:self action:#selector(cancelNumberPad)],
[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil],
[[UIBarButtonItem alloc]initWithTitle:#"Apply" style:UIBarButtonItemStyleDone target:self action:#selector(doneWithNumberPad)],
nil];
[numberToolbar sizeToFit];
// catogery pickerview
categoryPickerView=[[UIPickerView alloc]init];
categoryPickerView.delegate=self;
categoryPickerView.tag=1;
txtCategory.inputView=categoryPickerView;
txtCategory.inputAccessoryView=numberToolbar;
//product pickerview
productPickerView=[[UIPickerView alloc]init];
productPickerView.delegate=self;
productPickerView.tag=2;
txtProduct.inputView=productPickerView;
txtProduct.inputAccessoryView=numberToolbar;
//model pickerview
modelPickerView=[[UIPickerView alloc]init];
modelPickerView.delegate=self;
modelPickerView.tag=3;
txtModel.inputView=modelPickerView;
txtModel.inputAccessoryView=numberToolbar;
}//end of view did load
this is my event for picker view:-
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
if (pickerView.tag == 1) {
return [devicecatogery count]; //<-----------this is for category picker view
}else if(pickerView.tag == 2)
return [commanProductArray count]; //<-----------this is for product picker view
else
return [commanModelArray count]; //<-------------- this is for model picker view
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
if (pickerView.tag == 1)
return [devicecatogery objectAtIndex:row];//<----this is for category picker view
else if (pickerView.tag == 2)
return [commanProductArray objectAtIndex:row];//<--------this is for product picker view
else
return [commanModelArray objectAtIndex:row];//<--------- this is for model picker view
}
Here is my didSelect callback:
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
if ([[categoryArray objectAtIndex:[categoryPickerView selectedRowInComponent:0] ] isEqual:#"Audio"]) {
commanProductArray=[[NSMutableArray alloc]initWithObjects:#"walkman",#"mp3",#"ipod", nil];
if ([[commanProductArray objectAtIndex:[productPickerView selectedRowInComponent:0]] isEqual:#"walkman"]) {
// walkman list display
[productPickerView reloadAllComponents];
commanModelArray=[[NSMutableArray alloc]initWithObjects:#"walkman1",#"walkman2",#"walkman3",#"walkman4", nil];
[modelPickerView reloadAllComponents];
}else if ([[commanProductArray objectAtIndex:[productPickerView selectedRowInComponent:0]] isEqual:#"mp3"]){
//mp3 list display
[productPickerView reloadAllComponents];
[modelPickerView reloadAllComponents];
commanModelArray=[[NSMutableArray alloc]initWithObjects:#"mp3",#"mp3",#"mp3",#"mp3", nil];
}else if ([[commanProductArray objectAtIndex:[productPickerView selectedRowInComponent:0]] isEqual:#"ipod"]){
//ipod list display
[productPickerView reloadAllComponents];
[modelPickerView reloadAllComponents];
commanModelArray=[[NSMutableArray alloc]initWithObjects:#"ipod1",#"ipod2",#"ipod3",#"ipod4", nil];
}
}else if ([[categoryArray objectAtIndex:[categoryPickerView selectedRowInComponent:0]] isEqual:#"Video"]){
commanProductArray=[[NSMutableArray alloc]initWithObjects:#"TV",#"Moniter",#"Projector", nil];
if ([[commanProductArray objectAtIndex:[productPickerView selectedRowInComponent:0]]isEqual:#"TV"]) {
//for tv model display
[productPickerView reloadAllComponents];
commanModelArray=[[NSMutableArray alloc]initWithObjects:#"TV1",#"TV2",#"TV3", nil];
[modelPickerView reloadAllComponents];
}else if ([[commanProductArray objectAtIndex:[productPickerView selectedRowInComponent:0]]isEqual:#"Moniter"]){
//for moniter model display
[productPickerView reloadAllComponents];
commanModelArray=[[NSMutableArray alloc]initWithObjects:#"Moniter1",#"Moniter2",#"Moniter3", nil];
[modelPickerView reloadAllComponents];
}else if ([[commanProductArray objectAtIndex:[productPickerView selectedRowInComponent:0]] isEqual:#"Projector"]){
//for projector display
[productPickerView reloadAllComponents];
commanModelArray=[[NSMutableArray alloc]initWithObjects:#"Projector1",#"Projector2",#"Projector3", nil];
[modelPickerView reloadAllComponents];
}
}
}
This code doesn't make sense to me, I suspect your issue is here:
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
if ([[categoryArray objectAtIndex:[categoryPickerView selectedRowInComponent:0] ] isEqual:#"Audio"]) {
commanProductArray=[[NSMutableArray alloc]initWithObjects:#"walkman",#"mp3",#"ipod", nil];
if ([[commanProductArray objectAtIndex:[productPickerView selectedRowInComponent:0]] isEqual:#"walkman"]) {
// walkman list display
[productPickerView reloadAllComponents];
All of the pickerView's are going into this callback when selected. You are first of all not checking the tags to see which pickerView it was that fired, then you check if the row selected is audio / video, if its the second / third pickers, the code will never get passed this as they will not have audio / video selected.
Following the logic, if "Audio" is selected you set commanProductArray to the given values, then you immediately check the selected value is equal to "walkman" before loading it.
[productPickerView reloadAllComponents]; should be called directly after commanProductArray is set I suspect, as you set the array and check which value is selected before loading it.
This issue could have been spotted by simply putting 2 or 3 NSlog's to see was it getting into the loop
EDIT:
Your code should follow something more like this:
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
// If first picker
if(pickerView.tag == 1)
{
// If Audio
if(row == 0)
{
// Load result for audio
}
// If Video
else if (row == 1)
{
// load result for video
}
}
// If second picker
else if(pickerView.tag == 2)
{
// if Walkman
if(row == 0)
{
// load result for walkman
}
// etc etc etc
}
else if (pickerView.tag == 3)
{
}
}
Try this one:
- (void)viewDidLoad
{
devicecatogery=[[NSArray alloc]initWithObjects:#"Audio",#"Video", nil];
commanProductArray=[[NSMutableArray alloc]initWithObjects:#"walkman",#"mp3",#"ipod", nil];
commanModelArray=[[NSMutableArray alloc]initWithObjects:#"walkman1",#"walkman2",#"walkman3",#"walkman4", nil];
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
// tell the picker how many rows are available for a given component
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
if (pickerView.tag==1) {
return devicecatogery.count;
}
else if(pickerView.tag==2){
return commanProductArray.count;
}
else if (pickerView.tag==3)
{
return commanModelArray.count;
}
return 0;
}
// tell the picker how many components it will have
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 1;
}
// tell the picker the title for a given component
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
NSString *title;
if (pickerView.tag==1)
{
title = [NSString stringWithFormat:#"%#",[devicecatogery objectAtIndex:row]];
}
else if (pickerView.tag==2)
{
if([categoryPickerView selectedRowInComponent:0]==0)
{
commanProductArray=[[NSMutableArray alloc]initWithObjects:#"walkman",#"mp3",#"ipod", nil];
}
else{
commanProductArray=[[NSMutableArray alloc]initWithObjects:#"TV",#"Moniter",#"Projector", nil];
}
title = [NSString stringWithFormat:#"%#",[commanProductArray objectAtIndex:row]];
}
else if (pickerView.tag==3)
{
if ([[devicecatogery objectAtIndex:[categoryPickerView selectedRowInComponent:0]] isEqualToString:#"Audio"]) {
if([productPickerview selectedRowInComponent:0]==0)
{
commanModelArray=[[NSMutableArray alloc]initWithObjects:#"walkman1",#"walkman2",#"walkman3",#"walkman4", nil];
}
else if([productPickerview selectedRowInComponent:0]==1)
{
commanModelArray=[[NSMutableArray alloc]initWithObjects:#"mp31",#"mp32",#"mp33",#"mp34", nil];
}
else if([productPickerview selectedRowInComponent:0]==2)
{
commanModelArray=[[NSMutableArray alloc]initWithObjects:#"ipod1",#"ipod2",#"ipod3",#"ipod4", nil];
}
}
else
{
if([productPickerview selectedRowInComponent:0]==0)
{
commanModelArray=[[NSMutableArray alloc]initWithObjects:#"TV1",#"TV2",#"TV3",#"TV4", nil];
}
else if([productPickerview selectedRowInComponent:0]==1)
{
commanModelArray=[[NSMutableArray alloc]initWithObjects:#"Moniter1",#"Moniter2",#"Moniter3",#"Moniter4", nil];
}
else if([productPickerview selectedRowInComponent:0]==2)
{
commanModelArray=[[NSMutableArray alloc]initWithObjects:#"Projector1",#"Projector2",#"Projector3",#"Projector4", nil];
}
}
title = [NSString stringWithFormat:#"%#",[commanModelArray objectAtIndex:row]];
}
return title;
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
if (pickerView.tag==1)
{
[productPickerview reloadAllComponents];
[modelPickerview reloadAllComponents];
}
if (pickerView.tag==2) {
[modelPickerview reloadAllComponents];
}
// Handle the selection
}
For more detail you have to check it : Sample code
May it will help you.
Happy coding...:)
Related
I have a textfield in my app in which a user can choose a Group they belong to, along with several other fields. When they get to the Group TextField, it pops up a UIPickerView that has several choices that have already been created, along with an option to "Create New Group". When that option is chosen, I want the UIPickerView to go away, and have the keyboard pop back up so they can type again. I can get the picker view to appear and to go away, but can't get the keyboard back. Here is code so far.
-(void)addPickerView{
__block NSMutableArray *arr = [[NSMutableArray alloc] init];
PFQuery *rejectedNumber = [PFQuery queryWithClassName:#"Group"];
[rejectedNumber orderByAscending:#"GroupName"];
[rejectedNumber findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!objects) {
// Did not find any UserStats for the current user
NSLog(#"NotFound");
} else {
pickerArray = objects;
[myPickerView reloadAllComponents];
}
}];
//pickerArray = GoGo;
self.theView.signUpView.additionalField.delegate = self;
[self.theView.signUpView.additionalField setPlaceholder:#"Choose Group"];
myPickerView = [[UIPickerView alloc]init];
myPickerView.dataSource = self;
myPickerView.delegate = self;
myPickerView.showsSelectionIndicator = YES;
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc]
initWithTitle:#"Done" style:UIBarButtonItemStyleDone
target:self action:#selector(finishIt)];
UIToolbar *toolBar = [[UIToolbar alloc]initWithFrame:
CGRectMake(0, self.view.frame.size.height-
self.theView.signUpView.additionalField.frame.size.height-50, 320, 50)];
[toolBar setBarStyle:UIBarStyleBlackOpaque];
NSArray *toolbarItems = [NSArray arrayWithObjects:
doneButton, nil];
[toolBar setItems:toolbarItems];
self.theView.signUpView.additionalField.inputView = myPickerView;
self.theView.signUpView.additionalField.inputAccessoryView = toolBar;
}
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
return 1;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView
numberOfRowsInComponent:(NSInteger)component{
return [pickerArray count] + 1;
}
#pragma mark- Picker View Delegate
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:
(NSInteger)row inComponent:(NSInteger)component{
if (row == 0)
[self.theView.signUpView.additionalField.inputView removeFromSuperview];
[self.theView.signUpView.additionalField becomeFirstResponder];
}
else {
[self.theView.signUpView.additionalField setText:self.theGroup];
}
}
- (NSString*)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
NSString *groupName = #"Create New Group";
if (row != 0)
{
PFObject *object = pickerArray[row - 1]; // -1 to handle the array index
self.theGroup = object[#"GroupName"];
groupName = object[#"GroupName"];
}
return groupName;
}
First thing i noticed is, you missed a braces here after if condition:
if (row == 0)
[self.theView.signUpView.additionalField.inputView removeFromSuperview];
[self.theView.signUpView.additionalField becomeFirstResponder];
}
Instead use this:
if (row == 0) {
[self.theView.signUpView.additionalField resignFirstResponder];
self.theView.signUpView.additionalField.inputView = nil;
[self.theView.signUpView.additionalField becomeFirstResponder];
}
In my app a user can change the number of picker view elements by clicking some buttons. Everything is ok with that. But after that I want to show a word in it but the picker view is probably not ready and the app just crashes. Here is the cod for that
- (IBAction)changeNumberOfLettersToShow:(id)sender {
int numberOfLetters = (int)((UIBarButtonItem *)sender).tag;
switch (numberOfLetters) {
case 0:
[self setNumberOfLetters:[NSNumber numberWithInt: 10] andLanguage:nil];
break;
default:
[self setNumberOfLetters:[NSNumber numberWithInt: numberOfLetters] andLanguage:nil];
break;
}
[self showTheFirstWordForNumberOfLetters:numberOfLetters];
}
- (void) showTheFirstWordForNumberOfLetters: (int) numberOfLetters{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:[NSArray arrayWithObjects:[NSNumber numberWithInt:numberOfLetters], [NSNumber numberWithInt:0], nil] forKey:#"currentPositon"];
NSArray *words = [allWordsForCurrentLanguage objectForKey:[NSString stringWithFormat:#"%#%d",[[NSUserDefaults standardUserDefaults] objectForKey:#"language"], numberOfLetters]];
[self displayWord:[[words objectAtIndex:0] uppercaseString] animated:YES];
}
- (void) setNumberOfLetters:(NSNumber *)numberOfLetters andLanguage: (NSString *) language {
[pickerHelper setNumberOfLettersToShow:numberOfLetters andLanguage:nil];
[self.picker reloadAllComponents];
}
- (void) displayWord:(NSString *)word animated:(BOOL)animated {
pickerHelper.pickerWorkingAutomatically = YES;
for (NSUInteger i = 0; i < [word length]; i++) {
NSString *letter = [NSString stringWithFormat:#"%c", [word characterAtIndex:i]];
[self displayLetter:letter
atComponent:i
animated:animated];
}
pickerHelper.pickerWorkingAutomatically = NO;
}
The picker looks similar to the one on the picture:
http://sourcefreeze.com/wp-content/uploads/2015/03/uipickerview-multi-selected-row.png
So I actually want to make a word from the fragments of a picker containing letters (which also user to work fine before I started doing it) and it actually works on a simulator.
UPDATED:
- (void) displayLetter:(NSString *)letter atComponent:(NSUInteger)component animated:(BOOL)animated {
NSUInteger row;
if (animated){
NSUInteger selectedRow = [self.picker selectedRowInComponent:component];
row = selectedRow + ([self.alphabet count] - selectedRow % [self.alphabet count]) + [self.alphabet indexOfObject:letter];
}
else
row = ((UINT16_MAX) / (2 * [self.alphabet count]) * [self.alphabet count]) + [self.alphabet indexOfObject:letter];
[self.picker selectRow:row
inComponent:component
animated:animated];
}
So, I have a UIPicker view which gets populated from a NSMutableArray as long as the input is not "NULL".
So my picker shows all the values except NULL.
Now, I have a UITextField box and a button. So whatever I type in the text field, and I click the button, if it matches to anything which was there in the NSMutableArray ( which was used to populate UIPickerView ), it sets it to NULL and refreshes the UIPicker so that it doesn't get displayed anymore.
For some reason, I'm able to set the value to NULL(checked using NSLog), but the picker never gets updates, and neither does the NSMutable Array.
-(void) loadthepicker
{
NSMutableArray *getarray = [NSMutableArray arrayWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:#"FilerNamesArray"]];
pickerLoaderArray=[[NSMutableArray alloc] init];
for (int j=0; j<20; j++) {
if ([[getarray objectAtIndex:j] isEqualToString:#"NULL"])
{
// do nothing..don't load
}
else // add that filter to pickerLoaderArray
{
[pickerLoaderArray addObject:[getarray objectAtIndex:j]];
}
} // end of for
[pickerView reloadAllComponents];
[pickerView selectRow:0 inComponent:0 animated:NO];
}
-(NSInteger)numberOfComponentsInPickerView:(NSInteger)component
{
return 1;
}
-(NSInteger)pickerView:(UIPickerView *)picker numberOfRowsInComponent:(NSInteger)component
{
return [pickerLoaderArray count];
}
-(NSString *)pickerView:(UIPickerView *)picker titleForRow:(NSInteger)row forComponent:(NSInteger)component{
return [pickerLoaderArray objectAtIndex:row];
}
The button:
- (IBAction)deleteButton:(id)sender {
NSUserDefaults *CheckFiltersUsed = [NSUserDefaults standardUserDefaults];
NSInteger myInt = [CheckFiltersUsed integerForKey:#"FiltersUsed"];
if (myInt<=20 && myInt>0) {
NSLog(#"number of filters used before deleting %ld",(long)myInt);
[CheckFiltersUsed setInteger:myInt-1 forKey:#"FiltersUsed"];
[CheckFiltersUsed synchronize];
// get names array
NSMutableArray *getarray = [NSMutableArray arrayWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:#"FilerNamesArray"]];
NSArray *get=getarray;
// at location where name matches with selectedfilter..put NULL
for (int j=0; j<20; j++) {
if ( [[getarray objectAtIndex:j] isEqualToString:_filterToDelete.text] && isFilterDeleted==NO )
{
NSLog(#"------currently %d is %#",j,[getarray objectAtIndex:j]);
[getarray insertObject:#"NULL" atIndex:j];
NSLog(#"------now %d is %#",j,[getarray objectAtIndex:j]);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle: #"" message: #"Deleted" delegate: nil cancelButtonTitle:#"Ok" otherButtonTitles:nil]; [alert show];
isFilterDeleted=YES;
[[NSUserDefaults standardUserDefaults] setObject:getarray forKey:#"FilerNamesArray"];
[[NSUserDefaults standardUserDefaults]synchronize];
[self loadthepicker];
}
else
{
NSLog(#"No matching filter name");
}
} // end of for
//now save this array back.
}
else
{
NSUserDefaults *CheckFiltersUsed = [NSUserDefaults standardUserDefaults];
NSInteger myInt = [CheckFiltersUsed integerForKey:#"FiltersUsed"];
NSLog(#"Wrong number of filters!!!... %d",myInt);
}
}
If i get what you are trying to do, you want to delete the equal string from the array and the picker as well. But instead of that you just insert another NSString object into index 'j'
In the deleteButton method:
Instead of this line
[getarray insertObject:#"NULL" atIndex:j];
Call
[getarray removeObjectAtIndex:j];
**Update
In the loadPicker just remove the if statment to check if the string is equal to #"NULL"
So instead of:
for (int j=0; j<20; j++) {
if ([[getarray objectAtIndex:j] isEqualToString:#"NULL"])
{
// do nothing..don't load
}
else // add that filter to pickerLoaderArray
{
[pickerLoaderArray addObject:[getarray objectAtIndex:j]];
}
}
Do:
for(NSString *pickerValue in getarray){
[pickerLoaderArray addObject:pickerValue];
}
I have a screen with two text fields (category, subcategory), each hooked up to a custom UIPickerView. The options present in the subcategory view depend on the category selected as the value of the first field.
If the user has not selected a category, selecting the subcategory field brings up the standard keyboard (this behavior is fine).
If the user selects a category and then interacts with the subcategory field everything works fine.
The problem happens when the user puts in a category, brings up the subcategory picker, and then goes back and clears the category field. At this point, if the user selects the subcategory field, the picker will appear without any data and interacting with it will cause the app to crash.
The error text:
*** Assertion failure in -[UITableViewRowData rectForRow:inSection:], /SourceCache/UIKit_Sim/UIKit-2380.17/UITableViewRowData.m:1630
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'request for rect at invalid index path (<NSIndexPath 0x719eb60> 2 indexes [0, 0])'
*** First throw call stack:
(0x1cc3012 0x1100e7e 0x1cc2e78 0xb96665 0x22df20 0xf12de 0x481086 0x480f7a 0xa440d 0xa69eb 0x30f85a 0x30e99b 0x3100df 0x312d2d 0x312cac 0x30aa28 0x77972 0x77e53 0x55d4a 0x47698 0x1c1edf9 0x1c1ead0 0x1c38bf5 0x1c38962 0x1c69bb6 0x1c68f44 0x1c68e1b 0x1c1d7e3 0x1c1d668 0x44ffc 0x2acd 0x29f5)
libc++abi.dylib: terminate called throwing an exception
Here is my code:
- (IBAction)showYourPicker:(id)sender {
isCategoryPicker = true;
// create a UIPicker view as a custom keyboard view
UIPickerView* pickerView = [[UIPickerView alloc] init];
[pickerView sizeToFit];
pickerView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
pickerView.delegate = self;
pickerView.dataSource = self;
pickerView.showsSelectionIndicator = YES;
self.catPickView = pickerView; //UIPickerView
categoryField.inputView = pickerView;
// create a done view + done button, attach to it a doneClicked action, and place it in a toolbar as an accessory input view...
// Prepare done button
UIToolbar* keyboardDoneButtonView = [[UIToolbar alloc] init];
keyboardDoneButtonView.barStyle = UIBarStyleBlack;
keyboardDoneButtonView.translucent = YES;
keyboardDoneButtonView.tintColor = nil;
[keyboardDoneButtonView sizeToFit];
UIBarButtonItem* doneButton = [[UIBarButtonItem alloc] initWithTitle:#"Done"
style:UIBarButtonItemStyleBordered target:self
action:#selector(pickerDoneClicked:)];
[keyboardDoneButtonView setItems:[NSArray arrayWithObjects:doneButton, nil]];
// Plug the keyboardDoneButtonView into the text field...
categoryField.inputAccessoryView = keyboardDoneButtonView;
}
- (IBAction)showYourSubPicker:(id)sender {
isCategoryPicker = false;
WCSharedCache *sharedManager = [WCSharedCache sharedManager];
BOOL iLLAllowIt = false;
for(int i = 0; i < [sharedManager.categories count]; i++) {
if([[[sharedManager categories] objectAtIndex:i] isEqualToString:[categoryField text]]) {
iLLAllowIt = true;
}
}
if(!iLLAllowIt) {
return;
}
// create a UIPicker view as a custom keyboard view
UIPickerView* pickerView = [[UIPickerView alloc] init];
[pickerView sizeToFit];
pickerView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
pickerView.delegate = self;
pickerView.dataSource = self;
pickerView.showsSelectionIndicator = YES;
self.subCatPickView = pickerView; //UIPickerView
subcategoryField.inputView = pickerView;
// create a done view + done button, attach to it a doneClicked action, and place it in a toolbar as an accessory input view...
// Prepare done button
UIToolbar* keyboardDoneButtonView = [[UIToolbar alloc] init];
keyboardDoneButtonView.barStyle = UIBarStyleBlack;
keyboardDoneButtonView.translucent = YES;
keyboardDoneButtonView.tintColor = nil;
[keyboardDoneButtonView sizeToFit];
UIBarButtonItem* doneButton = [[UIBarButtonItem alloc] initWithTitle:#"Done"
style:UIBarButtonItemStyleBordered target:self
action:#selector(pickerDoneClicked:)];
[keyboardDoneButtonView setItems:[NSArray arrayWithObjects:doneButton, nil]];
// Plug the keyboardDoneButtonView into the text field...
subcategoryField.inputAccessoryView = keyboardDoneButtonView;
}
- (void) pickerDoneClicked: (id) picker {
if(isCategoryPicker) {
[categoryField resignFirstResponder];
} else {
[subcategoryField resignFirstResponder];
}
}
- (void) pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
WCSharedCache *sharedManager = [WCSharedCache sharedManager];
if(isCategoryPicker) {
[categoryField setText:[[sharedManager categories] objectAtIndex:row]];
} else {
#try {
int idx = 0;
for(int i = 0; i < [sharedManager.categories count]; i++) {
if([[[sharedManager categories] objectAtIndex:i] isEqualToString:[categoryField text]]) {
idx = i;
break;
}
}
[subcategoryField setText:[[[sharedManager subcategories]objectAtIndex:idx] objectAtIndex:row]];
} #catch (NSException *e) {
NSLog(#"Exception: %#",e);
[subcategoryField setText:#"" ];
}
}
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
WCSharedCache *sharedManager = [WCSharedCache sharedManager];
if(isCategoryPicker) {
return [[sharedManager categories]count];
} else {
for(int i = 0; i < [sharedManager.categories count]; i++) {
if([[[sharedManager categories] objectAtIndex:i] isEqualToString:[categoryField text]]) {
return [[[sharedManager subcategories] objectAtIndex:i] count];
}
}
}
return 0;
}
- (NSString *)pickerView: (UIPickerView *)pickerView titleForRow: (NSInteger)row forComponent:(NSInteger)component
{
WCSharedCache *sharedManager = [WCSharedCache sharedManager];
if(isCategoryPicker) {
return [[sharedManager categories] objectAtIndex:row];
} else {
for(int i = 0; i < [sharedManager.categories count]; i++) {
if([[[sharedManager categories] objectAtIndex:i] isEqualToString:[categoryField text]]) {
return [[[sharedManager subcategories] objectAtIndex:i] objectAtIndex:row];
}
}
}
return #"";
}
Is there a method I can implement, or a try-catch, or revival of original keyboard, or somewhere I can prevent the user from hitting this field if there is no data any of those would work. The data for categories is in an NSArray. The data for subcategories is in a two-dimensional NSArray indexed off of the index of the associated category.
If fixed this problem by changing the default value in:
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
WCSharedCache *sharedManager = [WCSharedCache sharedManager];
if(isCategoryPicker) {
return [[sharedManager categories]count];
} else {
for(int i = 0; i < [sharedManager.categories count]; i++) {
if([[[sharedManager categories] objectAtIndex:i] isEqualToString:[categoryField text]]) {
return [[[sharedManager subcategories] objectAtIndex:i] count];
}
}
}
return 1;
}
from zero to one. Apparently, UIPickerView (at least in the implementation above) cannot handle scrolling without throwing an exception if the number of rows in the component is 0. This is curious, because according the Apple's documentation of the UIPickerView class, the default value for this method is 0.
I am trying to make a simple converter for some unit stuff, and i can't seem to manage getting the data out of both columns and making them into a variable i can calculate with. I also get some errors, which i would really appreciate if anyone would look into. The errors are at the #pragma mark - PickerView Delegate, where i think about 90% of my code is wrong.
Here is the full .h file. (Hoping i did this the right way this time)
And here is the full project if anyone has got the time to look into it. http://www.mediafire.com/download.php?ss706o783ioa59u
#import "MainViewController.h"
#interface MainViewController ()
#end
#implementation MainViewController
#synthesize _convertFrom, _convertTo, _convertRates;
#synthesize dollarText, picker, resultLabel;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_convertFrom = #[#"Australia (AUD)", #"China (CNY)",
#"France (EUR)", #"Great Britain (GBP)", #"Japan (JPY)"];
_convertRates = #[ #0.9922f, #6.5938f, #0.7270f,
#0.6206f, #81.57f];
_convertTo = #[#"Australia (AUD)", #"China (CNY)",
#"France (EUR)", #"Great Britain (GBP)", #"Japan (JPY)"];
_convertRates = #[ #0.9922f, #6.5938f, #0.7270f,
#0.6206f, #81.57f];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
//dont forget to put something in here later
}
- (IBAction)textFieldReturn:(id)sender {
[sender resignFirstResponder];
}
#pragma mark -
#pragma mark PickerView DataSource
- (NSInteger)numberOfComponentsInPickerView:
(UIPickerView *)pickerView
{
return 2;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent: (NSInteger)component
{
if (component == 0) {
return [_convertFrom count];
}
return [_convertTo count];
}
- (NSString *) pickerView: (UIPickerView *)pickerView
titleForRow:(NSInteger)row
forComponent:(NSInteger)component
{
if (component == 0) {
return [_convertFrom objectAtIndex:[pickerView selectedRowInComponent:0]];
}
return [_convertTo objectAtIndex:[pickerView selectedRowInComponent:1]];
}
#pragma mark -
#pragma mark PickerView Delegate
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row
inComponent:(NSInteger)component
{
float from = [[_convertRates objectAtIndex:[pickerView selectedRowInComponent:0] floatValue]];
float to = [[_convertRates objectAtIndex:[pickerView selectedRowInComponent:1] floatValue]];
float input = [dollarText.text floatValue];
// This stuff is from some guide.
//float rate = [_convertRates[row] floatValue];
//float dollars = [dollarText.text floatValue];
//float result = dollars * rate;
NSString *resultString = [[NSString alloc] initWithFormat:
#"%.2f #% = %.2f %#", input, [[_convertRates objectAtIndex:[pickerView selectedRowInComponent:0] floatValue]], result, [[_convertRates objectAtIndex:[pickerView selectedRowInComponent:0] floatValue]]];
resultLabel.text = resultString;
}
#pragma mark - Flipside View
- (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller
{
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"showAlternate"]) {
[[segue destinationViewController] setDelegate:self];
}
}
#end
Thanks in advance :)
I just looked at your code, but still have some doubts about your calculation, but your braces was wrong and please implement it like this only:
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row
inComponent:(NSInteger)component
{
float from = [[_convertRates objectAtIndex:[pickerView selectedRowInComponent:0]] floatValue];
float to = [[_convertRates objectAtIndex:[pickerView selectedRowInComponent:1]] floatValue];
float input = [dollarText.text floatValue];
// This stuff is from some guide.
float rate = from;
float dollars = input;
float result = dollars * rate;
NSString *resultString = [[NSString alloc] initWithFormat:
#"result = %f = %f * %f", result, dollars, rate];
resultLabel.text = resultString;
}
-(IBAction)clear
{
}
These two lines:
float from = [[_convertRates objectAtIndex:[pickerView selectedRowInComponent:0] floatValue]];
float to = [[_convertRates objectAtIndex:[pickerView selectedRowInComponent:1] floatValue]];
should be:
float from = [[_convertRates objectAtIndex:[pickerView selectedRowInComponent:0]] floatValue];
float to = [[_convertRates objectAtIndex:[pickerView selectedRowInComponent:1]] floatValue];
You have bracket in the wrong spot. And it looks like the 'resultString' line has the same problem, multiple times.