How to Search multiple NSArray from UITableView in IOS - ios

What I want is to be able to search a UITableView, and have other arrays be narrowed down to the results of the cell's textlabel array. That probably just made no sense to no one. Here's an example.
An array called titleArray that fills the cell's textLabel:
"Toyota Yaris"
"Ford Escape"
"Ford F-150"
Another array called detailArray that fills the detail text label below the textLabel in a cell:
"Car"
"SUV"
"Truck"
When I search for "Ford" I want the UITableView to display the cells like this:
Cell 1: Ford Escape
SUV
Cell 2: Ford F-150
Truck
But it is displaying like this:
Cell 1: Ford Escape
Car
Cell 2: Ford F-150
SUV
Essentially it narrowed down the titleArray but not the detailArray so it is display objects 1 & 2 from titleArray but 0 & 1 from detailArray. If this confuses you please ask any questions!

For this you would be much better off having just one array. Two ways you could do this:
1) create a custom class (derived from NSObject) for the elements of your array, perhaps named Vehicle. Your vehicle class would have a 'name' property, and a 'type' property.
NSMutableArray *vehicleArray = [[NSMutableArray alloc] init];
Vehicle *myVehicle = [[Vehicle alloc] init];
myVehicle.name = #"Ford Escape";
myVehicle.type = #"SUV";
[vehicleArray addObject:myVehicle];
2) have the elements in your array be of type NSDictionary. Each dictionary would have a key value pair for name and type.
NSMutableArray *vehicleArray = [[NSMutableArray alloc] init];
NSDictionary *myVehicle = [[NSDictionary alloc] initWithObjectsAndKeys:#"Ford Escape", #"name", #"SUV", #"type", nil];
[vehicleArray addObject:myVehicle];

In your code, you are likely creating UITableViewCell object in a message named tableView:cellForRowAtIndexPath:. I would review this code for your issue. When you create/retrieve the UITableViewCell, you will then fill in the title and detail (check this in the debugger). I note that the example you are following is creating a pared down array of items in response to your search argument. It seems most likely that you will need to pare down the detail array at the same time you pare down the title array. You may also need to search in your detail array (depending on how you want your app to function). This could complicate your search logic some.
//Possible search logic
for (int iii = 0; iii < titleArray.count; iii++) {
if (<titleArray matches search string>) {
[titlesToDisplay addObject:[titleArray objectAtIndex:iii]];
[detailsToDisplay addObject:[detailArray objectAtIndex:iii]];
//Assuming that you have titles and details in corresponding slots.
}
}
Now when you set the title and detail settings for your UITableViewCell, you should count entries in titlesToDisplay and retrieve entries from titlesToDisplay and detailsToDisplay.

Related

Display correct objects/keys from array in string?

I'm trying to display items from an array in my tableView cells, in a string. Currently, I'm using these lines of code:
.m
id swaptime = self.filteredTotal[0][#"swaptime"];
NSString *test = swaptime;
...to grab the value located in swaptime, and display it in each of my cells. That said, in all of my cells, this line forces them all to display only the FIRST swaptime value - rather than the list of swaptime values from my array in their corresponding cells. Is this because of the [0] in my line (e.g. only grab the value located at 0)? If so, how should it be written instead so that all values are displayed?
I'm not sure of the answer since you have not provided all of your code, but if the code shown above is from the cellForRowAt method of the UITableView datasource, then this should work:
id swaptime = self.filteredTotal[indexPath.row][#"swaptime"];
(provided you do not intend on having more than 1 section)

Match clicked TableView row (string) to find corresponding unique ID

I am currently stuck on how to best find and pass the ID of a clicked table view row. I'd like to know what the best practice might be to accomplish this.
In an iPhone storyboard I want to create a tableview.
This tableview should get populated from a JSON web server response.
This JSON object will contain around 10 items, say name and
address plus a unique ID.
In my tableview I'd like to have in each tableview row one name
and address but I don't want to have the unique ID displayed.
Now here comes my question: If I don't have the unique ID displayed how do I find this ID again based on which row has been clicked? Is there a way of assigning hidden fields? I'd like to send the unique ID via POST back to web server.
The directions I've been investigating in so far are...
...parse JSON object into NSDictionary and match clicked tableview row back to it to get ID.
...put JSON object into SQLlite database and match clicked row against database to get ID.
...don't do any of the above and simply send a string of name and address (instead of ID) back to web server where the matching against database would take place.
What do you think will be best in terms of getting the corresponding ID from a clicked tableview row.
Thanks a lot for your time.
This is how you can accomplish this
Call your webservice and get the json. Parse the json and keep on adding object to a NSMutableArray say itemList.
Create a model class say Itemdesc which will have 3 fields name, address and ID.
When you parse your json extract each individual product into item model object defined above and add it to itemList array.
It could be like this:
NSArray *responseArray = responsefromService;
For(int i=0;i<responseArray.count;i++)
{
//Parse your object here
NSDictionary *currentItem = [responseArray objectAtIndex:i];
Itemdesc *itemObject = [[Itemdesc alloc] init];
itemObject.name = [currentItem objectForKey:#"name"];
itemObject.address = [currentItem objectForKey:#"address"];
itemObject.ID = [currentItem objectForKey:#"ID"];
[itemList addObject:itemObject];
itemObject=nil;
}
Now pass this array as object to tableView for row count and in cellForRowAtIndexPath get your row object as below:
Itemdesc *currentIndexObj = [itemList objectAtIndex:indexpath.row];
cell.name.text = currentIndexObj.name;
cell.address.text = currentIndexObj.address;
This will display your name and address in your tableViewCell.
To get the ID when a row is select, in your didSelectRowAtIndexPath write below code:
Itemdesc *currentIndexObj = [itemList objectAtIndex:indexpath.row];
NSString *ID = currentIndexObj.ID;
NSLog(#"ID value: %#", ID);
You have got your ID, perform whatever operation you want to perform.
Model Class is nothing but simply a normal Class itself.
Code to create a Model Class:
Go to File -> New -> File ->iOS-> Source -> CocoaTouch Class
select next and given Class a name ItemDesc and make it subclass of NSObject. In your project you will get to files Itemdesc.h and Itemdesc.m
Itemdesc.h file:
#import <Foundation/Foundation.h>
#interface Itemdesc : NSObject
#property(nonatomic,strong) NSString *name;
#property(nonatomic,strong) NSString *address;
#property(nonatomic,strong) NSString *itemID;
#end
No need to make any changes in .m file.
Thats it. Import the header in your class where your tableView exists and things will work.
Json structure:
[
{
"name" : "John",
"address" : "ny",
"ID" : "xyz"
},
{
"name" : "Jane",
"address" : "dc",
"ID" : "pqr"
}
]
Typically you have a collection of model objects that determine how many UI elements to show to the user. In the simple case this could be just an NSArray but could also be fetched from Core Data or a remote backend.
As the table asks for cells, use the indexPath to look up the corresponding model object in the backing collection. You can then use the information in the object to configure the cell.
When the user selects a row, you can use the reported indexPath to do a similar lookup. Once you have the correct object, you can look up its ID and perform the necessary network request.
Lets make it in steps.
Start downloading JSON
Save JSON data in some Array/Dictionary what ever you like, here i will use responseData as name of my Collection.
Your tableView rows are responseData count.
in cellForRowAtIndexPath populate you data, only that you needed, address name, but your responseData still have id for each object, right?
in didSelectRowForIndexPath, you will get the id somehow like this
Swift
resonseObject.objectAtIndex(indexPath.row).valueForKey(id)
Objective-C
[[responseObject objectAtIndex:indexPath.row] valueForKey:#"id"]
You also can make custom UITableViewCell class and put the ID as String Property and set it in cellForRowForIndexPath, but i think the first solution is better.
Greetings.
I simplest way to accomplish this is to store the objects you get into a local array (or anything that has order and matches the display order of the table). From there you can just use the index of the table cell that was selected, to determine which object was selected and grab the ID.
So, if you have an array of sampleObjects (each of a name, address and ID) populated from your web service. Use this array as the datasource for your table. Use the tableView:didSelectRowAtIndexPath: delegate method as follows...
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
int rowSelected = indexPath.row;
id sampleObject = tableDataSource[rowSelected]; // Assuming tableDataSource is an array you created to populate the table
// ...do whatever with the object that the user selected
}

iOS Select specific entries to display in table

I have an array, which contains multiple dictionaries.
Formatted like this:-
Array
- Index
- DOW = Weekday
- Index
- DOW = Weekend
- Index
- DOW = Weekday
I want to populate a table with data from only those dictionaries containing DOW = Weekday.
What is the quickest way of enumerating this?
Note that the data will be changed via filters, and then table reloaded.
You can filter your array using NSPredicate, like this:
NSArray *data = #[
#{#"Dow":#"Weekday", #"One":#"Two"} // Item 0
, #{#"Dow":#"Weekend", #"Three":#"Four"} // Item 1
, #{#"Dow":#"Weekday", #"Five":#"Six"} // Item 2
];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"(Dow=='Weekday')"];
NSArray *res = [data filteredArrayUsingPredicate:pred];
The code above will keep NSArrays items 0 and 2, and remove item 1, because it does not contain an entry where #"Dow" is set to #"Weekday".
The data variable above represents the pre-filtered data in your example.
I'd suggest you read Apple UITableViewDataSource protocol guide here and perhaps this tutorial too.
Basically you'll want to -
Override numberOfSectionsInTableView: and return the number of sections in your table (0 if it's not relevant).
Ovveride tableView:numberOfRowsInSection: and here you can "apply" the needed filters on your dictionary and return the correct number of rows you actually want to display.
Next time you update the filters and call reloadTable again the above steps will filter the table correctly according to the new filters.

Passing array of objects to dynamic cells in Table view

I have used a Table View with Dynamic Prototype cells.
I have created a sample row in the table view with four values of a quantity:
Title
Min Value
Max Value
Current value.
I have created Table view controller and table view cell classes for accessing those properties in my code.
Now I have to set the values dynamically. I can see people suggesting to pass array of values separately for each.
Like:
Array 1 for Title : which will display title for all items in the row
Array 2 for Min value and so on.....
Is there a way that we pass an array of objects to the table view and it creates the table.
Please suggest.
I can see people suggesting to pass array of values separately for each.
Don't do this it is very poor approach, instead create a single array of NSDictionnaries, for instance:
_listOfValue =
#[
#{#"Title":#"title 1", #"Min Value":#"0", #"Max Value":#"100", #"Current value":#"50"},
#{#"Title":#"title 2", #"Min Value":#"4", #"Max Value":#"90", #"Current value":#"60"},
#{#"Title":#"title 3", #"Min Value":#"6", #"Max Value":#"70", #"Current value":#"70"}
];
This will make it easy to retrieve the data you need since they are not separated.
In numberOfRowsInSection you can return [self.listOfValue count].
In cellForRowAtIndexPath or didSelectRowAtIndexPath you can easily get the dictionnary at the IndexPath then parse the value of each key.
//Get the specific value
NSDictionnary *valueDict = _listOfValue[indexPath.row];
//read data from value dictionary
valueDict[#"Title"];
//or the old syntax
[valueDict objectForKey:#"Title"];
No, you can't pass the array direct to the table. Your table view controller would usually maintain the array (often a single array containing dictionaries or custom class instances) and your code in the table view controller uses that array to configure the cells.

NSMutableArray: How add a sorting value (int) to array's objects AFTER sorting it?

Got a tableView with some player objects in it, sorted ASC by best playerTime after each game try a player makes.
Now I want to add a value (int) that shows the players placement in the playerlist (tableview), that will be reflected on the the players custom cell in the tableView. Got the custom cell working already with the dynamic data, just I need the "placement" int.
How do I handle the array to do this? Must be done after the list (NSArray) been sorted by best playerTime.
I guess, some kind of iteration step one and two maybe (like an if-then statement)?
Maybe there is a smart NSArray property for this specific need?
Any tips or suggestions? Thank's.
Just display the row's value into your custom cell's label:
- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath{
//...
myCustomCell.positionLabel.text = [NSString stringWithFormat:#"%i", (indexPath.row + 1)];
//...
}
Now if you have a player object and want to retrieve its position in your sorted array, you just do this:
int playerPosition = [mySortedArray indexOfObject:playerObject] + 1;

Resources