How to Use UISearchBar for Custom Cells in UITableView - iphone

I'm populating my tableview from an array. And this array is created by SQLite query.
So in my array, I have objects from my user-defined class.
And I use custom cells in my table. Like object.name in one layer, object.id near this layer.
So far everything's good. But if I try to use UISearchBar, how will I re-populate my table?
This is the code I create my table.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"SpeakersCell";
SpeakersCell *cell = (SpeakersCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"SpeakersCell" owner:self options:nil];
for (id currentObject in topLevelObjects) {
if ([currentObject isKindOfClass:[SpeakersCell class]]) {
cell = (SpeakersCell *) currentObject;
break;
}
}
}
// Set up the cell
ProjectAppDelegate *appDelegate = (ProjectAppDelegate *)[[UIApplication sharedApplication] delegate];
Speaker *speakerObject = (Speaker *)[appDelegate.speakers objectAtIndex:indexPath.row];
cell.lblSpeakerName.text = speaker.speakerName;
cell.lblSpeakerCity.text = speaker.speakerCity;
return cell;
}
When I add a search bar and define searchBar textDidChange event, I successfully get items that contains the key letters. But I can't re-populate my table because I only have searched items' names.
Tutorials I got help from are built on default cells and the datasource of tableview is NSString array. But my array is NSObject array, this is my problem.
I consider getting indexes of searched items but how can I use these values either? Do you have any idea or any related link?

I think you should take a look at Bobgreen's blog, his tutorial helped me quite a lot.
http://www.cocoabob.net/?p=67
Check his delegeate function for UISearchDisplayController (which I guess you might want to use?)
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
[self.filteredListContent removeAllObjects];
for (Product *product in listContent)
{
if ([scope isEqualToString:#"All"] || [product.type isEqualToString:scope])
{
NSComparisonResult result = [product.name compare:searchText options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch) range:NSMakeRange(0, [searchText length])];
if (result == NSOrderedSame)
{
[self.filteredListContent addObject:product];
}
}
}
}
He has an array of NSObject's (product) there which he loops thru. Each time a result matches the search string he puts the value in an second array called filteredListContent and he'll show upp the filtered content. Works like a charm for me.

Related

Array not showing in Table View

Can anyone tell me why my code isn't showing any results in my table view. Here is my code. I already tried to change the #"#" into indexPath.row without any luck. I 'm looking for any answer into the right direction. I'm fairly new to xcode and objective-c. I would really appreciate any help.
-(void)waitAndFillPlaylistPool {
// arrPlaylist -> mutablearray which stores the value of loaded playlist in order to use it later
[SPAsyncLoading waitUntilLoaded:[SPSession sharedSession] timeout:kSPAsyncLoadingDefaultTimeout then:^(NSArray *loadedession, NSArray *notLoadedSession)
{
// The session is logged in and loaded — now wait for the userPlaylists to load.
NSLog(#"[%# %#]: %#", NSStringFromClass([self class]), NSStringFromSelector(_cmd), #"Session loaded.");
[SPAsyncLoading waitUntilLoaded:[SPSession sharedSession].userPlaylists timeout:kSPAsyncLoadingDefaultTimeout then:^(NSArray *loadedContainers, NSArray *notLoadedContainers)
{
// User playlists are loaded — wait for playlists to load their metadata.
NSLog(#"[%# %#]: %#", NSStringFromClass([self class]), NSStringFromSelector(_cmd), #"Container loaded.");
NSMutableArray *playlists = [NSMutableArray array];
[playlists addObject:[SPSession sharedSession].starredPlaylist];
[playlists addObject:[SPSession sharedSession].inboxPlaylist];
[playlists addObjectsFromArray:[SPSession sharedSession].userPlaylists.flattenedPlaylists];
[SPAsyncLoading waitUntilLoaded:playlists timeout:kSPAsyncLoadingDefaultTimeout then:^(NSArray *loadedPlaylists, NSArray *notLoadedPlaylists)
{
// All of our playlists have loaded their metadata — wait for all tracks to load their metadata.
NSLog(#"[%# %#]: %# of %# playlists loaded.", NSStringFromClass([self class]), NSStringFromSelector(_cmd),
[NSNumber numberWithInteger:loadedPlaylists.count], [NSNumber numberWithInteger:loadedPlaylists.count + notLoadedPlaylists.count]);
NSLog(#"loadedPlaylists >> %#",loadedPlaylists);
arrPlaylist = [[NSMutableArray alloc] initWithArray:loadedPlaylists];
NSLog(#"arrPlaylist >> %#",arrPlaylist);
}];
}];
}];
}
- (NSInteger) tableView:(UITableView *) tableView numberOfRowsInSection:(NSInteger)section {
return [arrPlaylist count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [arrPlaylist objectAtIndex:indexPath.row];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
It's hard to tell what you're doing in the method, waitAndFillPlaylistPool, but if this is taking any time to get this data, then you need to call reloadData on your table view ([self.tableView reloadData]) as the last line in that method (or when any async method returns -- I can't tell where that might be in your code).

UITableView not reversing

I'm working on information retrieval where in the latest information in on top of UITableView. The code goes like this.
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
LoanModel* loan = _feed.products[indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" ];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:#"Cell"];
}
NSString *myString = [NSString stringWithFormat:#"%#",[loan name]];
NSArray *myWords = [myString componentsSeparatedByString:#","];
NSMutableArray *reversed = [NSMutableArray arrayWithCapacity:[myWords count]];
NSEnumerator *enumerator = [myWords reverseObjectEnumerator];
for (id element in enumerator) {
[reversed addObject:element];
}
NSMutableString *reverseString = [reversed componentsJoinedByString:#","];
cell.textLabel.text = reverseString;
return cell;
}
I'm getting the JSON object which contain two fields cid and name respectively. I'm showing only the name is tableview. But I want to show it in reverse i,e last update should show at first. But above code showing the content in reverse. IF "hello" is the content, then it shows "olleh". Please suggest me how to get the UITableView in reverse list. I'm a newbie to iOS.
If you want to have the reversed order of cells / objects they represent, you have to change
LoanModel* loan = _feed.products[indexPath.row];
to
LoanModel* loan = _feed.products[_feed.products.count - 1 - indexPath.row];
assuming that _feed.products is an NSArray.
The array you are using to display the the data in tableView, you'll need to reverse that and then display the data in tableView
NSArray* reversed = [[myArray reverseObjectEnumerator] allObjects];
you can use this to make your array objects order in reverse.
Try This:
NSArray* reversedArray = [[myWords reverseObjectEnumerator] allObjects];

NSArray count not working

So I have a UITableView, and I populate the tableview with data from a .plist. This has been working fine for me until today, when I tried to do the same and I can't get the numberOfRowsInSection, method to work. Here is my code:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if...
else if (segmentOptions == exchange){
NSArray *array = [NSArray arrayWithArray:[exchangeDictionary objectForKey:[listOfExchanges objectAtIndex:section]]];
return [array count];
}
//Else
return contentArray.count;
}
So in that code, everytime I run it, the code crashs. But, I use basiacally the same code to set the tableview text and that works fine:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
if...
else if (segmentOptions == exchange) {
NSArray *array = [NSArray arrayWithArray:[exchangeDictionary objectForKey:[listOfExchanges objectAtIndex:indexPath.section]]];
cell.textLabel.text = [array objectAtIndex:indexPath.row];
}
return cell;
}
And that code works fine, which is why I'm so confused. When I set the number of rows to return to a specific number, and run the rest of the code, everything works fine. So I'm really lost. Thands in advance
UPDATE
I tried it with the proper count notation, return [array count];, and I still get the same crash and the same console output.
First, count is not a property so you should not be using dot syntax to access it.
I would suggest changing your code so that you are not accessing the count method like a property.
Second,
Test to see if your array is nil and that it is even an array.
Third,
Post the actual complete stack trace.
Break it down and debug, if console message is not being helpful. It helps sometimes, specially when it's late. i.e.
// NSArray *array = [NSArray arrayWithArray:[exchangeDictionary objectForKey:[listOfExchanges objectAtIndex:section]]];
NSLog(#"%d", section);
id objAtIndex = [listOfExchanges objectAtIndex:section];
NSLog(#"%#", listOfExchanges);
NSLog(#"%#", objAtIndex);
id objForKey = [exchangeDictionary objectForKey:objAtIndex];
NSLog(#"%#", exchangeDictionary);
NSLog(#"%#", objForKey);
Try this:
[array count]
count is not a property, it is a method you run on the array.

how to remove object from array at particular index

I am doing parsing on xml file and fetched data from xml file and store that in array and further to rows of UITableView. I want to remove the extra word at 5th index '\U2019' and want to merge word 'i' and 'm all alone' to one row f UITableView.
"WHERE DOES LOVE LIVE",
"TRANSFORMATION OF THE SELF",
"EMPATHY STRUCTURES",
"MORE QUESTIONS THAN ANSWERS",
I,
"\U2019",
"M ALL ALONE",
"THE WILL TO LIVE",
"THE GUILT OF SELF DENIAL",
HOPELESSNESS,
"SOCIAL WANNABIES",
"THE POWER OF HOPE"
bunch of code:
- (UITableViewCell *)tableView:(UITableView *)tableViewcellForRowAtIndexPath:
(NSIndexPath *)indexPath
{ static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithFrame:CGRectZero];
}
if(indexPath.row > 0)
{ cell.textLabel.text = [blogtitle objectAtIndex: indexPath.row];
}}`
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSMutableString *)string
{
NSString *newString = [string stringByTrimmingCharactersInSet:
[NSCharacterSet whitespaceAndNewlineCharacterSet]];
// save the characters for the current item...
if ( [currentElement isEqualToString:#"title"])
{
if ([newString length] > 0)
{
// NSMutableString *base64String = [newString base64EncodedString];
[blogtitle addObject:newString];
}
NSLog(#"blogtiltlearray...%#",blogtitle);
}}`
It's easy to remove an object at a specific index. Try:
[blogtitle removeObjectAtIndex:index];
EDIT: You can call [tableView reloadData]; in order to remove the row, assuming you've already loaded the tableView BEFORE you manipulated the array.
You can merge 2 strings together via:
NSString * mergedString = [NSString stringWithFormat:#"%#%#", string1, string2];
and you can replace one object in an array with another via:
[blogtitle replaceObjectAtIndex:index withObject:mergedString];
Hope that helps!
You can use NSMutable array and the method of it named removeObjectAtIndex:

Unable to view table in RootViewController

I have a navigation app that I am working on which for some reason is not allowing me to view my table on my initial screen (i.e. from the RootViewController). I have the following method that is called by my "viewDidLoad" method:`
- (void) locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
`
which does some work, and then calls the method:
- (void) readRestaurantsFromDatabase:(double)userLatitude
withUserLocation:(double)userLongitude{
This method does some work with an NSArray called "sortedArray" which is a property declared, and synthesized in RootViewController:
//compile a list of categories
NSMutableArray *categoryList = [[NSMutableArray alloc] init];
[categoryList addObject:#"All Types"];
for (Restaurant *restCat in restaurants){
[categoryList addObject:restCat.category];
}
//remove duplicates
NSArray *copy = [categoryList copy];
NSInteger index = [copy count] - 1;
for (NSString *restCategory in [copy reverseObjectEnumerator]) {
if ([categoryList indexOfObject:restCategory inRange:NSMakeRange(0, index)] != NSNotFound) {
[categoryList removeObjectAtIndex:index];
}
index--;
}
[copy release];
//put list in alphabetical order
sortedArray = [categoryList sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
This is how the above method ends. I then have the following code for my "cellForRowAtIndexPath" method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell.
NSString *cellValue = [sortedArray objectAtIndex:indexPath.row];
cell.textLabel.text = cellValue;
return cell;
}
To me, everything looks fine. When I run my code, I have NSLog statements that issue output to the console which clearly shows me that the NSArray sortedArray contains data. Yet, when I run the code on my iPhone simulator in XCode, I get an empty table. Can anyone see what I'm doing wrong?
Thanks in advance to all who reply.
Have you connected your tableView to a property in interface builder?
Also, when your sorted array changes, you might want to call [myTabelView reloadData]; to refresh the table. Do this each time you change your sortedArray i.e.
//put list in alphabetical order
sortedArray = [categoryList sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
// The sorted array has changed, get the table view to refresh
[myTabelView reloadData];
Have you implemented tableView:numberOfRowsInSection: ?
This should probably return [sortedArray count].
Did you fill numbersOfRowInSection?
On a side note, I don't understand why you're copying everything then removing duplicates instead of skipping adds when your array contains the object.
Double check your tableview datasource property. If the datasource isn't set for your UITableView. Make sure that you are setting that to your object and make sure your object defines the -(NSInteger)tableView:numberOfRowsInSection: method.
That should return [sortedArray count].