I am loading an array from a web service and displaying them in picker and all works fine. My array contains random number of questions for every category of questions. Now what i want is that i wanna add one more entry "Your own question" at the end of array so that the last row of picker displays "Your own question". How can i do this
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view {
UILabel *retval = (id)view;
if (!retval) {
retval= [[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f, [pickerView rowSizeForComponent:component].width, [pickerView rowSizeForComponent:component].height)];
}
// retval.text = [idAndNameArray objectAtIndex:row];
if([pickerType isEqualToString:#"picker"])
{
retval.text = [idAndNameArray objectAtIndex:row];
}
else
{
retval.text = [quesArray objectAtIndex:row];
}
retval.font = [UIFont boldSystemFontOfSize:14];
retval.numberOfLines = 3;
return retval;
}
This code only displays number of rows(questions) fetched from the web service.
EDIT 1:
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)thePickerView
{
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)thePickerView numberOfRowsInComponent:(NSInteger)component
{
if([pickerType isEqualToString:#"picker"])
{
return [idAndNameArray count];
}
else
{
return [quesArray count];
}
}
EDIT 2:
Resolved by making another NSMutableArray with my custom object "Your own question" and then appending it with the array fetched from web service
NSMutableArray *customObj = [NSMutableArray arrayWithObject: #"test"];
[quesArray addObjectsFromArray:customObj];
In UIPickerViewDataSource's method called pickerView:numberOfRowsInComponent: return your array's count plus one value(return arr.count+1;), and in the method of UIPickerVIewDelegatethat you have implemented return your label with the text when the component is greater than arr.count-1 (if(row>(arr-1)){//return the label with 'Your own question'}). Good Luck!
EDIT:
- (NSInteger)pickerView:(UIPickerView *)thePickerView numberOfRowsInComponent:(NSInteger)component
{
if([pickerType isEqualToString:#"picker"])
{
return [idAndNameArray count];
}
else
{
return [quesArray count]+1;
}
}
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view {
UILabel *retval = (id)view;
if (!retval) {
retval= [[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f, [pickerView rowSizeForComponent:component].width, [pickerView rowSizeForComponent:component].height)];
}
// retval.text = [idAndNameArray objectAtIndex:row];
if([pickerType isEqualToString:#"picker"])
{
retval.text = [idAndNameArray objectAtIndex:row];
}
else
{
if(row>quesArray.count-1){
retval.text = #"You own question";
}
else{
retval.text = [quesArray objectAtIndex:row];
}
}
retval.font = [UIFont boldSystemFontOfSize:14];
retval.numberOfLines = 3;
return retval;
}
Related
I have three UIPickerviews. I have a json response. I have a three text fields. If user select first picker view the related data is displaying in first textfields. And second and third picker view also same. My requirement Is if user select the the particular item in first picker view second and third picker view does not showing the item. And second and third also same.
-(void)viewDidLoad
{
dataArray = [[NSMutableArray alloc]initWithObjects:#"A+",#"A-",#"B+",#"B-",#"O+",#"O-", nil];
bloodGroup = [[UITextField alloc]initWithFrame:CGRectMake(10, logoImg.frame.origin.y+logoImg.frame.size.height+45, screenWidth-20, 50)];
bloodGroup.borderStyle = UITextBorderStyleRoundedRect;
bloodGroup.font = [UIFont systemFontOfSize:15];
bloodGroup.placeholder = #"Please Select Your Option";
bloodGroup.delegate = self;
[self.view addSubview:bloodGroup];
txtField1 = [[UITextField alloc]initWithFrame:CGRectMake(10, ansField1.frame.origin.y+ansField1.frame.size.height+45, screenWidth-20, 50)];
txtField1.borderStyle = UITextBorderStyleRoundedRect;
txtField1.font = [UIFont systemFontOfSize:15];
txtField1.placeholder = #"Please Select Your Option";
txtField1.delegate = self;
[self.view addSubview:txtField1];
txtField2 = [[UITextField alloc]initWithFrame:CGRectMake(10, ansField2.frame.origin.y+ansField2.frame.size.height+45, screenWidth-20, 50)];
txtField2.borderStyle = UITextBorderStyleRoundedRect;
txtField2.font = [UIFont systemFontOfSize:15];
txtField2.placeholder = #"Please Select Your Option";
txtField2.delegate = self;
[self.view addSubview:txtField2];
myPickerView = [[UIPickerView alloc] init];
[myPickerView setDataSource: self];
[myPickerView setDelegate: self];
myPickerView.showsSelectionIndicator = YES;
bloodGroup.inputView = myPickerView;
bloodGroup.inputAccessoryView = toolBar;
// txtField1
txtField1.inputView = myPickerView;
txtField1.inputAccessoryView = toolBar;
txtField2.inputView = myPickerView;
txtField2.inputAccessoryView = toolBar;
}
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
if (isBloodGroupFieldSelected) {
return 1;
}
else if(!isBloodGroupFieldSelected){
return 1;
}
else if(!isGenderGroupFieldSelected)
{
return 1;
}
return 0;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
if (isBloodGroupFieldSelected) {
return [dataArray count];
}
else if(!isBloodGroupFieldSelected)
{
return [dataArray count];
}
else if (!isGenderGroupFieldSelected)
{
return [dataArray count];
}
return 0;
}
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
if (isBloodGroupFieldSelected)
{
return dataArray[row];
}
else if((!isBloodGroupFieldSelected) && (isGenderGroupFieldSelected))
{
return dataArray[row];
}
else if(!isGenderGroupFieldSelected)
{
return dataArray[row];
}
return 0;
}
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
if (isBloodGroupFieldSelected) {
bloodGroup.text = dataArray[row];
}
else if((!isBloodGroupFieldSelected) && (isGenderGroupFieldSelected))
{
txtField1.text = dataArray[row];
}
else if(!isGenderGroupFieldSelected)
{
txtField2.text= dataArray[row];
}
}
- (void)textFieldDidBeginEditing:(UITextField *)textField {
if (textField == bloodGroup) {
isBloodGroupFieldSelected = YES;
}
else if (textField == txtField1){
isBloodGroupFieldSelected = NO;
isGenderGroupFieldSelected = YES;
}
else if (textField == txtField2) {
isGenderGroupFieldSelected = NO;
isBloodGroupFieldSelected = NO;
}
[myPickerView reloadAllComponents];
}
You have most of the code you need already. The pickerView:didSelectRow:inComponent: delegate method will be called when any of your pickers have been changed, assuming they each have their delegates set to the controller above. Although, I only see one picker view defined in the code above. Let's assume your picker views are called myPickerView, myPickerView2, and myPickerView3. The code would roughly be:
- (void)pickerView:(UIPickerView *)pickerView
didSelectRow:(NSInteger)row
inComponent:(NSInteger)component
{
if (pickerView == pickerView1) {
// the first picker view lseection has changed
// update myPickerView2 and myPickerView3 to reflect
// the values you want based on this selection
} else if (pickerView == pickerView2) {
// update the other views based on this selection
} else ...
....
}
In my app, I query Parse.com to get a list of groups to populate a UIPickerView. I want to add one more option to the UIPickerView at the very top that is called "Create New Group", in which it will pull up a UITextField to make a new group and move from there. How do I go about adding this to all the other fields? Here is how I have it created 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;
}
#pragma mark - Picker View Data source
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
return 1;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView
numberOfRowsInComponent:(NSInteger)component{
return [pickerArray count];
}
#pragma mark- Picker View Delegate
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:
(NSInteger)row inComponent:(NSInteger)component{
[self.theView.signUpView.additionalField setText:self.theGroup];
}
- (NSString*)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
PFObject *object = pickerArray[row];
//Assuming "Category" is a string here for your title
self.theGroup = object[#"GroupName"];
return object[#"GroupName"];
}
You can add achieve that in two ways:
Add an extra object at the first index of your array for showing "Create New Group"
You can use tweak the datasource and delegate methods of UIPickerView. Like:
-(NSInteger)pickerView:(UIPickerView *)pickerView
numberOfRowsInComponent:(NSInteger)component
{
return [pickerArray count] + 1; // +1 for the additional row
}
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:
(NSInteger)row inComponent:(NSInteger)component
{
if (row == 0)
{
// Create New Group clicked
}
else
{
// Some other option selected
}
}
- (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;
}
Here is my code:
#synthesize pickerLetter, pickerNumber, pickerSymbol;
- (void)viewDidLoad {
[super viewDidLoad];
letters = [[NSArray alloc]initWithObjects:#"a", #"b", #"c", nil];
numbers = [[NSArray alloc]initWithObjects:#"1", #"2", #"3", nil];
symbols = [[NSArray alloc]initWithObjects:#"+", #"-", #"/", nil];
}
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
if (pickerView == pickerLetter) {
return letters.count;
} else if (pickerView == pickerNumber){
return numbers.count;
} else {
return symbols.count;
}
}
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
if (pickerView == pickerLetter) {
return [letters objectAtIndex:row];
} else if (pickerView == pickerNumber){
return [numbers objectAtIndex:row];
} else {
return [symbols objectAtIndex:row];
}
}
This is giving me
Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 1 beyond bounds [0 .. 0]'
when I use the pickers in the Simulator.
The code that is causing the crash is
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
label.text = [NSString stringWithFormat:#"%# %# %#",[letters objectAtIndex:[pickerLetter selectedRowInComponent:0]],[numbers objectAtIndex:[pickerNumber selectedRowInComponent:1]],[symbols objectAtIndex:[pickerSymbol selectedRowInComponent:2]]];
}
You've narrowed down your issue to this code:
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
label.text = [NSString stringWithFormat:#"%# %# %#",[letters objectAtIndex:[pickerLetter selectedRowInComponent:0]],[numbers objectAtIndex:[pickerNumber selectedRowInComponent:1]],[symbols objectAtIndex:[pickerSymbol selectedRowInComponent:2]]];
}
But this line has several calls to objectAtIndex: so it's hard to know the exact issues. Plus this code is hard to read and impossible to debug. Start by splitting up this code as follows:
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
NSInteger letterIndex = [pickerLetter selectedRowInComponent:0];
NSString *letter = letters[letterIndex];
NSInteger numberIndex = [pickerNumber selectedRowInComponent:1];
NSString *number = numbers[numberIndex];
NSInteger symbolIndex = [pickerSymbol selectedRowInComponent:2];
NSString *symbol = symbols[symbolIndex];
label.text = [NSString stringWithFormat:#"%# %# %#", letter, number, symbol];
}
Doing this you will be able to narrow down the real cause of your issue.
As you can see, the problem is that you are referencing the wrong component number from the pickerNumber and pickerSymbol. All three pickers only have 1 component so you need to select component 0 from all three pickers.
The needed code is:
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
NSInteger letterIndex = [pickerLetter selectedRowInComponent:0];
NSString *letter = letters[letterIndex];
NSInteger numberIndex = [pickerNumber selectedRowInComponent:0];
NSString *number = numbers[numberIndex];
NSInteger symbolIndex = [pickerSymbol selectedRowInComponent:0];
NSString *symbol = symbols[symbolIndex];
label.text = [NSString stringWithFormat:#"%# %# %#", letter, number, symbol];
}
Avoid putting more than one or two method calls on a single line of code. It makes the code less readable and much harder to debug if there is a problem.
you are calling a wrong way to implement the method
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
if (pickerView == pickerLetter) {
return [letters objectAtIndex:row];
} else if (pickerView == pickerNumber){
return [numbers objectAtIndex:row];
} else {
return [symbols objectAtIndex:row];
}
}
change it to
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
if (component == 0) {
return [letters objectAtIndex:row];
} else if (component == 1){
return [numbers objectAtIndex:row];
} else {
return [symbols objectAtIndex:row];
}
}
I am new here and I am getting my hands dirty on some iPhone applications on XCODE. I am currently creating an app but I am stuck on a particular part that involves a pickerview. Here's the code.
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
if ([pickerView tag] == 0){
return [firstColumn count];
}
else if ([pickerView tag] == 1){
return [OnFirstMin count];
return [OnSecMin count];
return [OnSecSec count];
return [OnFirstSec count];
}
else {
return [OffFirstMin count];
return [OffSecMin count];
return [OffFirstSec count];
return [OffSecSec count];
}
return 0;
}
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{
if([pickerView tag] == 0){
if(component == FIRST){
return [firstColumn objectAtIndex:row];
}
}
else if ([pickerView tag] == 1){
if(component == ON1){
return [OnSecMin objectAtIndex:row];
}
else if (component == ON2){
return [OnFirstMin objectAtIndex:row];
}
else if (component == ON3){
return [OnSecSec objectAtIndex:row];
}
else {
return [OnFirstSec objectAtIndex:row];
}
}
else {
if(component == OFF1){
return [OffSecMin objectAtIndex:row];
}
else if (component == OFF2){
return [OffFirstSec objectAtIndex:row];
}
else if (component == OFF3){
return [OffSecSec objectAtIndex:row];
}
else {
return [OffFirstSec objectAtIndex:row];
}
}
return 0;
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
if ([pickerView tag] == 0){
if(sets == TRUE && reps != TRUE){
numofsets = row;
SetsTextField.text = [firstColumn objectAtIndex:row];
}
else{
numofreps = row;
RepsTextField.text = [firstColumn objectAtIndex:row];
}
}
else if ([pickerView tag] == 1){
if(component == ON1){
onsecmin = row;
}
else if (component == ON2){
onfirstmin = row;
}
else if (component == ON3){
onsecsec = row;
}
else {
onfirstsec = row;
}
}
else {
if (component == OFF1){
offsecmin = row;
}
else if (component == OFF2){
offfirstmin = row;
}
else if (component == OFF3){
offsecsec = row;
}
else {
offfirstsec = row;
}
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
firstColumn = [[NSMutableArray alloc] init];
for(i=0; i<=30; i++){
[firstColumn addObject: [NSString stringWithFormat:#"%d", i]];
}
OnSecMin = [[NSMutableArray alloc] init];
OnFirstMin = [[NSMutableArray alloc] init];
for(j=0; j<60; j++){
[OnSecMin addObject:[NSString stringWithFormat:#"%i", j]];
[OnFirstMin addObject: [NSString stringWithFormat:#"%i", j]];
}
OnSecSec = [[NSMutableArray alloc] init]; //Part where I need help.
k =0;
while (k<60){
[OnSecSec addObject: [NSString stringWithFormat:#"%i",k]];
k = k+15;
}
PickerViewSetsRepsContainer.frame = CGRectMake(0, 600, 320, 206);
PickerViewOnContainer.frame = CGRectMake(0, 610, 320, 206);
PickerViewOffContainer.frame = CGRectMake(0, 620, 320, 206);
}
So, for OnSecSec, I want the rows to display 0, 15, 30, and 45 for that component. However, when I run it, the application is aborted. However, when I change that part to a for loop like I did for OnSecMin and OnFirstMin, it works. How come I can't use a while loop like above? Also, can someone help me with this dilemma? Thank you very much for your assistance in advance!
try this
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return 1050;
}
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view {
NSString *arrayName = [[NSString alloc] initWithFormat:#"column%d", component];
NSArray *array = [self valueForKey:arrayName];
[arrayName release];
UIImage *image = [array objectAtIndex:row%7];
if (!view){
view = [[[UIImageView alloc] init] autorelease];
}
[(UIImageView*)view setImage:image];
return view;
}
I want to fill the content of a TableView according to selections made in a PickerView view. The code I have so far is:
- (IBAction)findOwnerButtonPressed:(id)sender
{
findShip.hidden = NO;
shipOwners.hidden = NO;
boatsTableView.hidden = YES;
boatOwners = [NSArray arrayWithObjects:#"Owner1",#"Owner2",#"Owner3", nil];
}
- (IBAction)findShipButtonPressed:(id)sender
{
shipOwners.hidden = YES;
findShip.hidden = YES;
boatsTableView.hidden = NO;
}
PickerView Data Source
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return [boatOwners count];
}
- (NSString *)pickerView:(UIPickerView *)pickerView
titleForRow:(NSInteger)row
forComponent:(NSInteger)component
{
return [boatOwners objectAtIndex:row];
}
PickerView Delegate
- (void)pickerView:(UIPickerView *)pickerView
didSelectRow:(NSInteger)row
inComponent:(NSInteger)component
{
NSString *boatsFromOwner = [boatOwners objectAtIndex:[shipOwners selectedRowInComponent:0]];
boatsForOwner = [NSMutableArray arrayWithObjects:nil];
if ([boatsFromOwner isEqualToString:#"Owner1"]) {
[self.boatsForOwner addObject:#"Titanic"];
}
NSLog(#"%#",boatsFromOwner);
}
TableView DataSource & Delegate
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [boatsForOwner count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableItem";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = [boatsForOwner objectAtIndex:indexPath.row];
return cell;
}
This is supposed to return the boat owner company from a PickerWheel, and give me their boats in the table. This code returns nothing in the table. The PickerWheel logs 'Owner1' when I select it.
Is my error in how I add objects to the array or how I initialize the table or how I compare PickerWheel result to a word?
After you do
[self.boatsForOwner addObject:#"Titanic"];
You will manually need to refresh you tableview.. so after that do
[_yourTableView reloadData];
I would also initialize your arrays like this:
boatsForOwner = [NSMutableArray new];
I think first alloc & init the array "boatsForOwner "
replace your picker didSelectRow method with
-(void)pickerView:(UIPickerView *)pickerView
didSelectRow:(NSInteger)row
inComponent:(NSInteger)component
{
NSString *boatsFromOwner = [boatOwners objectAtIndex:[shipOwners selectedRowInComponent:0]];
if(boatsForOwner) {
[boatsForOwner release];
boatsForOwner = nil;
}
boatsForOwner = [NSMutableArray alloc] init];
if ([boatsFromOwner isEqualToString:#"Owner1"]) {
[self.boatsForOwner addObject:#"Titanic"];
}
NSLog(#"%#",boatsFromOwner);
[tableObject reloadData];
}
and release boatsForOwner when you dealloc.