Displaying text from multiple components in UIPickerView - ios

I need to display the values most recently selected in a multiple component pickerview in my label
I have a pickerView with three components, populated by three NSMutableArrays (rowOneItems,rowTwoItems,rowThreeItems).
I also have an NSLog statement that is correctly showing what the user last selected from the changed component.
However, I cannot figure out how to show the most recently selected values in the label properly.
Currently, the label takes the value from the first picker and displays it, but will not properly update the second and third values. Rather it selects the value that's in the same spot as it. For example, if all three arrays had the values of bird, dog, and cat, when I pick 'dog' in the picker view, the label will show three 'dog' values.
What I want to do is display the values of what the user has selected in the pickerview into a label.
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row
inComponent:(NSInteger)component {
//log which row is selected in each component
//this shows the values correctly in output
if(component ==1) {
return NSLog(#"Selected Difficulty: %#",[rowTwoItems objectAtIndex:row]);
}
else if(component ==2) {
return NSLog(#"Selected Duration: %#",[rowThreeItems objectAtIndex:row]);
}
else{
NSLog(#"Selected Type: %#",[rowOneItems objectAtIndex:row]);
}
//define chosen items
//stuck here. tried using a if else statement as above, but of course that would only return the first value in the label
NSString *chosenType = [rowOneItems objectAtIndex:row];
NSString *chosenDifficulty = [rowTwoItems objectAtIndex:row];
NSString *chosenDuration = [rowThreeItems objectAtIndex:row];
[workoutResults setText:[NSString stringWithFormat:#"%#, %#, %#", chosenType, chosenDifficulty, chosenDuration]];
}
Just started learning obj-c, so my apologies if this is a total newbie question. Thanks for any guidance you can give me.

That method you've got above is called for a single row's change, and not for all. (So the 'row' variable) isn't useful outside of the row that was just changed. You'll want to call selectedRowInComponent:
NSString *chosenType = [rowOneItems objectAtIndex:[pickerView selectedRowInComponent:0]];
NSString *chosenDifficulty = [rowTwoItems objectAtIndex:[pickerView selectedRowInComponent:1]];
NSString *chosenDuration = [rowThreeItems objectAtIndex:[pickerView selectedRowInComponent:2]];

Related

How to read uipicker multiple component when one component is changed

i have a 3component ui picker with index,days and time of consultation.
i want to read 2nd and 3rd component value when first component is changed.
What should i do to read 2nd and 3rd component in UIPicker when component 1 is changed?
days=#[#"Sunday",#"Monday",#"Tuesday",#"Wednesday",#"Thursday",#"Friday",#"Saturday"];
self.indexes=#[#"1",#"2",#"3",#"4",#"5",#"6",#"7"];
timeOfConsultation=#[#"9:00 AM",#"11:00 AM"];
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if(component == 0){
_labelValueIndex.text = [self.indexes objectAtIndex:row];
// When component 1 is spinned read component 2 and component 3 value even if they are not spinned
[days objectAtIndex:row];// incorrect value as row variable is like global if i select indexes[1] . i also get days[1] and timeOfConsultation [1]
// How to read component 2 and component 3 value from component1 change event
}else if (component == 1){
labelValueBookingDay.text = [days objectAtIndex:row];
}
else{
labelValueTimeOfConsultation.text = [timeOfConsultation objectAtIndex:row];
}
}
Use this code-
NSString *YourselectedTitle = [self.yourArrayName objectAtIndex:[self.yourPickerName selectedRowInComponent:1]];
NSLog(#"%#", YourselectedTitle);
Hope this helps!

Objective C- Loading a UIPickerview using the objects in it

i have a picker view which contains values from an NSMutableArray
NSMutableArray array=[[NSMutableArray alloc]init];
for(int t=-20 ;t<70;t++)
{
NSString *string=[NSString stringWithFormat:#"%d",t];
[array addObject:string];
}
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row{
return [array objectAtIndex:row];
}
I select a value from the picker and save it in database. Afterwards when the page is loaded picker should be loaded with the saved value.
How can I achieve it?
I have seen accessing selected row by passing index value like
[pickerview selectRow:20 inComponent:0 animated:NO];
but in my case is it possible to get the values' index ?or is there any other way?
please help
As you model will change so you can send indexOfObject message to array to get index. Try This
NSInteger index=[array indexOfObject:#"ObjectYouHave"];

IOS Searchbar returns wrong data

I am going crazy trying to get my IOS Searchbar working for the Iphone. I access data from a remote server and populate a content file. I then do a filter which creates a filtered content file. I then do a [self.tableView reloadData()]. It works fine the first time around. Then I change my scope and do another fetch of data from my server and filter it and do another reload. However, the second time the table shows the first 9 items from the previous display rather than the new 9 items from the filtered file. I console display the file count in the filtered file which in this case is 9 in the tableView numberOfRowsInSection: I also display each item going through the cellForRowAtIndexPath. In the cellForRowAtIndexPath I am displaying the correct 9 unfiltered items but they do not show up on the table! The table shows the first 9 items from the old display instead.
My question is doesn't the new data display on the table instead of the old data even though the count is correct? Why am I displaying the correct items on the console but yet the display shows items from the old display. WHat do I need to do to make the new data appear? I know this is pretty hard to comprehend but I am listing some of my code below in hopes that someone can give me a clue on why the table view is not being updated with the latest data.
// This is where I get data back from the server.
self.listContent = [[NSArray alloc] init];
if(_scopeIndex == 0)
self.listContent = [jsonObject objectForKey:#"burials"];
else
if(_scopeIndex == 1)
self.listContent = [jsonObject objectForKey:#"obits"];
else
self.listContent = [jsonObject objectForKey:#"photos"];
if(self.listContent > 0)
{
dispatch_async(dispatch_get_main_queue(), ^{
[self filterContentForSearchText:searchString scope:
[[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:[self.searchDisplayController.searchBar selectedScopeButtonIndex]]];
[self.tableView reloadData];
});
}
Below is where the data is filtered. In this case the unfiltered and filtered file are the same.
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope{
/*
Update the filtered array based on the search text and scope.
*/
[self.filteredListContent removeAllObjects];// First clear the filtered array.
/*
Search the listContent for names that match and add to the filtered array.
*/
for (int i = 0; i < [self.listContent count]; i++)
{
NSComparisonResult result = [self.listContent[i][#"LastName"] compare:searchText options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch) range:NSMakeRange(0, [searchText length])];
if (result == NSOrderedSame)
{
[self.filteredListContent addObject:self.listContent[i]];
}
// }
}
}
This is where I get the table count of filtered items.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
if (tableView == self.searchDisplayController.searchResultsTableView)
{
NSLog(#"Filtered Name count = %i", [self.listContent count]);
return [self.filteredListContent count];
}
else
{
NSLog(#"Name count = %i", [self.listContent count]);
return [self.listContent count];
}
}
ANd this is where I update the cells in my table:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *kCellID = #"cellID";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellID];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellID];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
if(indexPath.row > [self.filteredListContent count] - 1)
return cell;
NSDictionary *burial = [self.filteredListContent objectAtIndex:indexPath.row];
NSString *lastname = burial[#"LastName"];
NSString *firstname = burial[#"FirstName"];
NSString *burialname = [NSString stringWithFormat: #"%#, %#", lastname, firstname];
cell.textLabel.text = burialname;
NSLog(#"Cell name= %# index path=%i", cell.textLabel.text, indexPath.row);
return cell;
}
I changed my logic to go to the server one time to get my content and this time included scope indicators in my content table. This enables me to process scope filters without having to go back to the server for data for a specific scope. Doing this resulted in proper view tables being displayed when changing scope. I would not recommend going to the server ascynchronously whenever the scope changes on the search as it really screws up the view table.
Some things to try:
Maybe you're reloading your tableView too soon, or
Your cellForRowAtIndexPath needs to distinguish between the table views (just as your numberOfRowsInSection does), or
Maybe you don't have all of your delegates set up correctly. The searchBar is used with a UISearchDisplayController, which has 2 delegates: searchResultsDataSource and searchResultsDelegate. Make sure those are set to self (or whatever class handles these).
How are you using searchbar? Logic should be that you have tableview with all data and the you use search bar to filter out matching results and add them to search data array and while searchbar is active you display search data array.
Is
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
used somewhere?
Added following
If you have this function set up you can update search array and reload it using something like
if (self.searchDisplayController.searchResultsTableView != nil)
{
//Updates searchData array
[self searchDisplayController:self.searchDisplayController shouldReloadTableForSearchString:searchBar1.text];
//Updates display
[self.searchDisplayController.searchResultsTableView reloadData];
}
else
{
[_channelsTableView reloadData];
}
It is calling searchDisplayController with current search bar text. When new tableview data comes from server you can activate searchDisplayController to refresh search results array and then it is possible to refresh the display.

Objective C (UIPickerView): Do Action Once An Item Was Selected

On the app that I am developing I have a list of schedule on a UIPickerView and what I want to do is to enable a button once the 6th item on the list was selected.
I have this code but I it's not working
- (void)pickerView:(UIPickerView *)pickerView didSelectRow: (NSInteger)row inComponent:(NSInteger)component {
// Handle the selection
[trainSchedule setText:[NSString stringWithFormat:#"%#",[schedArray objectAtIndex:[pickerView selectedRowInComponent:0]]]];
if ([schedArray objectAtIndex:[schedArray objectAtIndex:[pickerView selectedRowInComponent:6]]]) { sendTrainRequest.enabled = YES; } else { sendTrainRequest.enabled = NO; }
}
I have this warning also...
Incompatible pointer to integer conversion sending 'id' to parameter of type 'NSUInteger' (aka 'unsigned int
How will a able to do what I want to happen?
I think you're looking for a UIPickerViewDelegate method called pickerView:didSelectRow:inComponent: documented here
I think the problem is in your if statement. If I am parsing what you are trying to say correctly, you want sendTrainRequest.enabled to be set to YES if the sixth item in the picker is selected. Your if statement now is confusing, and the warning is because you are sending on object to the objectAtIndex method of schedArray, when you should be sending an integer. Try this:
- (void)pickerView:(UIPickerView *)pickerView didSelectRow: (NSInteger)row inComponent:(NSInteger)component {
// Handle the selection
[trainSchedule setText:[NSString stringWithFormat:#"%#",[schedArray objectAtIndex:[pickerView selectedRowInComponent:0]]]];
if ([pickerView selectedRowInComponent:0] == 5)
{ sendTrainRequest.enabled = YES; }
else
{ sendTrainRequest.enabled = NO; }
}
Note that the hard-coded 5 in this snippet will evaluate to the sixth item in the picker view, since it is zero-referenced.

UIPickerView updating from UISegmentedControl

I'm attempting to update a single UIPickerView with a different NSArray of data based on which Index is selected from a UISegmentedControl. Currently when I change the control the numberOfRowsInComponent does not update, and the titleForRow will only update when scrolling the picker.
The NSArrays are populated within viewDidLoad, and I'm using the reloadAllComponents method upon an IBAction of the SegmentedControl.
#synthesize subnetView, classControl;
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
//One column
return 1;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
//set number of rows
if (classControl.selectedSegmentIndex == 0){
NSLog(#"Class A Rows %d", [classAArray count]);
return classAArray.count;
}
else if (classControl.selectedSegmentIndex == 1){
return classBArray.count;
}
else if (classControl.selectedSegmentIndex == 2){
return classCArray.count;
}
return 0;
}
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
//set item per row
if (classControl.selectedSegmentIndex == 0){
NSLog(#"Class A Rows %d", [classAArray count]);
return [classAArray objectAtIndex:row];
}
else if (classControl.selectedSegmentIndex == 1){
return [classBArray objectAtIndex:row];
}
else if (classControl.selectedSegmentIndex == 2){
return [classCArray objectAtIndex:row];
}
return 0;
}
-(IBAction)classChange{
[subnetView reloadAllComponents];
}
Based on which selector is chosen to be "selected" within interface builder, the picker is loaded with the correct array and number of rows. Based on this code when selecting an array with less elements, the numberOfRowsInComponents is not being updated, and the app will crash when reaching the end of the smaller array.
So my two problems:
Updating of elements only occurs when scrolling.
The number of rows does not update when performing the reloadAllComponents method.
Thanks for listening!
I've seen this before. Usually it is caused by the pickerview outlet not being connected, effectively calling reloadAllComponents on nothing. But when you scroll the connected data source and delegate methods still work.
This can be easily checked by login the outlet's value using:
NSLog(#"%#",subnetView);
If it logs (NULL) as I expect it will simply connect your IB outlet and you're done.

Resources