sectioned table view returning blank table - ios

I found code examples online for creating a tableview with alphabetical sections and i have tried to adapt for my tableview.
However, now the simulator is returning a blank table.
I've obviously gone wrong, anyone mind pointing out the mistakes?
Every change I make doesn't help.
Thank you
#import "RCViewController.h"
#interface RCViewController ()
#end
#implementation RCViewController
#synthesize content = _content;
#synthesize sectionData;
#synthesize sectionNames;
-(NSArray *)content {
NSArray *words = [NSArray arrayWithObjects:#"Tee", #"Club", #"Green", #"Putt", nil];
NSArray *sortedWords = [words sortedArrayUsingSelector:#selector(caseInsensitiveCompare:)];
NSString *currentLetter = #"";
for (NSString *string in sortedWords) {
if (string.length>0) {
NSString *letter = [string substringToIndex:1];
if (![letter isEqualToString:currentLetter]) {
[sectionNames addObject:letter];
currentLetter = letter;
NSMutableArray *oneSection = [NSMutableArray array];
[sectionData addObject:oneSection];
[[sectionData lastObject]addObject:string];
}
}
}
return _content;
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return sectionNames.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [[sectionData objectAtIndex:section]count];
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return [sectionNames objectAtIndex:section];
}
-(NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
return sectionNames;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *simpleTableIdentifier = #"simpleTableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
cell.textLabel.text =[[self.sectionData objectAtIndex:indexPath.section]objectAtIndex:indexPath.row];
}
return cell;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end

There are a bunch of things that are not optimal with your code but what is causing the table to be blank is most likely that you are never populating sectionData and sectionName and so it returns a table with no section names or section data. Try this:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSArray *words = [NSArray arrayWithObjects:#"Tee", #"Club", #"Green", #"Putt", nil];
NSArray *sortedWords = [words sortedArrayUsingSelector:#selector(caseInsensitiveCompare:)];
NSString *currentLetter = #"";
for (NSString *string in sortedWords) {
if (string.length>0) {
NSString *letter = [string substringToIndex:1];
if (![letter isEqualToString:currentLetter]) {
[sectionNames addObject:letter];
currentLetter = letter;
NSMutableArray *oneSection = [NSMutableArray array];
[sectionData addObject:oneSection];
[[sectionData lastObject]addObject:string];
}
}
}
}

Related

Deleting tableview row and section if empty with commitEdittingStyle

I can't seem to find too much on this. I'm currently trying to create a swipable delete button that will delete the row that is swiped, and if that row is now empty from the section header it will delete the section header as well. For example, "Bread" is swiped to delete, and there is nothing else under the section header "B". Then this will delete both Bread, and the "B" section header. My code is below.
#interface ChoicesTableViewController () <UITableViewDelegate, UITableViewDataSource>
#property (weak, nonatomic) IBOutlet UITableView *myTableView;
#property (strong, nonatomic) NSMutableArray *items;
#property (strong, nonatomic) NSMutableDictionary *alphabetizedItems;
#end
#implementation ChoicesTableViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.myTableView.delegate = self;
self.myTableView.dataSource = self;
self.items = [[NSMutableArray alloc] init];
[self.items addObject:#"Apples"];
[self.items addObject:#"Bread"];
self.alphabetizedItems = [self alphabetizeItems:self.items];
}
//Segue if the item is tapped
//- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
//{
// MyDataChoices *currentRow = self.arrayNames[indexPath.row];
// self.mySelectedCell = currentRow.myNameChoices;
//
// [self performSegueWithIdentifier:#"unwindSegueAction" sender:self];
//
//}
////unwind segue from add choice
- (IBAction)unwindSegueToChoices:(UIStoryboardSegue *)segue
{
AddChoiceViewController *sourceVC = segue.sourceViewController;
NSString *myNewItem = sourceVC.myTextField.text;
//NSString *myFinalString = [[myNewItem substringToIndex:1] capitalizedString];
NSString *stringCapitalized = [myNewItem capitalizedString];
[self.items addObject:stringCapitalized];
self.alphabetizedItems = [self alphabetizeItems:self.items];
//[self.arrayNames addObjectsFromArray:#[[MyDataChoices itemWithNewName:stringCapitalized]]];
[self.tableView reloadData];
}
//titles for talble view
#pragma mark Helper Methods
- (NSMutableDictionary *)alphabetizeItems:(NSArray *)items {
NSMutableDictionary *buffer = [[NSMutableDictionary alloc] init];
// Put Fruits in Sections
for (int i = 0; i < [items count]; i++) {
NSString *fruit = [items objectAtIndex:i];
NSString *firstLetter = [[fruit substringToIndex:1] uppercaseString];
if ([buffer objectForKey:firstLetter]) {
[(NSMutableArray *)[buffer objectForKey:firstLetter] addObject:fruit];
} else {
NSMutableArray *mutableArray = [[NSMutableArray alloc] initWithObjects:fruit, nil];
[buffer setObject:mutableArray forKey:firstLetter];
}
}
// Sort Fruits
NSArray *keys = [buffer allKeys];
for (int j = 0; j < [keys count]; j++) {
NSString *key = [keys objectAtIndex:j];
[(NSMutableArray *)[buffer objectForKey:key] sortUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
}
NSMutableDictionary *result = [NSMutableDictionary dictionaryWithDictionary:buffer];
return result;
}
#pragma mark title indexing
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
NSArray *keys = [[self.alphabetizedItems allKeys] sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
NSString *key = [keys objectAtIndex:section];
return key;
}
# pragma mark main table view
-(NSInteger) numberOfSectionsInTableView:(UITableView *) tableView
{
NSArray *keys = [self.alphabetizedItems allKeys];
return [keys count];
}
-(NSInteger) tableView:(UITableView *) tableView numberOfRowsInSection:(NSInteger)section
{
//return self.arrayNames.count;
NSArray *unsortedKeys = [self.alphabetizedItems allKeys];
NSArray *sortedKeys = [unsortedKeys sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
NSString *key = [sortedKeys objectAtIndex:section];
NSArray *fruitsForSection = [self.alphabetizedItems objectForKey:key];
return [fruitsForSection count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//MyDataChoices *currentRow = self.arrayNames[indexPath.row];
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:#"mainCell2" forIndexPath:indexPath];
//cell.textLabel.text = currentRow.myNameChoices;
NSArray *unsortedKeys = [self.alphabetizedItems allKeys];
NSArray *sortedKeys = [unsortedKeys sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
NSString *key = [sortedKeys objectAtIndex:[indexPath section]];
NSArray *fruitsForSection = [self.alphabetizedItems objectForKey:key];
NSString *fruit = [fruitsForSection objectAtIndex:[indexPath row]];
[cell.textLabel setText:fruit];
return cell;
}
# pragma Mark delete slide button
//Delete Swipe Button
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
int index = indexPath.row;
//[self.items removeObjectAtIndex:index];
[self.alphabetizedItems removeObjectForKey:indexPath];
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
} else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
The basic approach is to see how many rows are in the section for the row being deleted. If the section has two or more rows, simply delete the row as you are doing now. If the section only has one row (the one being deleted), then remove the section from the data model and then delete the section from the table instead of deleting the row.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
NSArray *unsortedKeys = [self.alphabetizedItems allKeys];
NSArray *sortedKeys = [unsortedKeys sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
NSString *key = [sortedKeys objectAtIndex:[indexPath section]];
NSArray *fruitsForSection = [self.alphabetizedItems objectForKey:key];
if (fruitsForSection.count == 1) {
// Delete the whole section
[self.alphabetizedItems removeObjectForKey:key];
[tableView deleteSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationFade];
} else {
// Delete the row from the data source
NSInteger index = indexPath.row;
//[self.items removeObjectAtIndex:index];
[self.alphabetizedItems removeObjectForKey:indexPath];
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
} else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}

self.objects is empty in PFQueryTableViewController

I am trying to display data in different sections using PFQueryTableViewController. The code suggested in https://parse.com/questions/using-pfquerytableviewcontroller-for-uitableview-sections seemed to work, but I couldn't get the data to load on self.objects. Here is my code:
#import "AKAdminViewStudentsViewController.h"
#interface AKAdminViewStudentsViewController ()
#property (strong, nonatomic) NSMutableDictionary *sections;
#property (strong, nonatomic) NSMutableDictionary *sectionToClassMap;
#end
#implementation AKAdminViewStudentsViewController
#synthesize sections = _sections;
#synthesize sectionToClassMap = _sectionToClassMap;
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
self.parseClassName = #"Students";
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[self.tableView reloadData];
NSLog(#"sections found: %#", self.sections); // returns null
NSLog(#"sectionToClassMap: %#", self.sectionToClassMap); // returns null
NSLog(#"objects in table: %#", self.objects); // this found to be empty
}
...
#pragma mark - Tableview methods
- (PFQuery *)queryForTable
{
PFQuery *queryStudents = [PFQuery queryWithClassName:#"Students"];
[queryStudents whereKey:#"student_admin" equalTo:[PFUser currentUser]];
if ([self.objects count]==0) {
queryStudents.cachePolicy = kPFCachePolicyCacheThenNetwork;
}
[queryStudents orderByAscending:#"class_name"];
return queryStudents;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return self.sections.allKeys.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSString *className = [self classForSection:section];
NSArray *rowIndicesInSection = [self.sections objectForKey:className];
return rowIndicesInSection.count;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
NSString *className = [self classForSection:section];
return className;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object
{
static NSString *CellIdentifier = #"Students";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell==nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
// Configure cell
cell.textLabel.text = [NSString stringWithFormat:#"%#", object[#"full_name"]];
NSDateFormatter *formatDate = [[NSDateFormatter alloc] init];
[formatDate setDateStyle:NSDateFormatterShortStyle];
cell.detailTextLabel.text = [NSString stringWithFormat:#"%#", [formatDate stringFromDate:object[#"createdAt"]]];
return cell;
}
#pragma mark - Helper methods
- (void)objectsDidLoad:(NSError *)error
{
[super objectsDidLoad:error];
// Clear data before loading
[self.sections removeAllObjects];
[self.sectionToClassMap removeAllObjects];
NSInteger section = 0;
NSInteger rowIndex = 0;
for (PFObject *object in self.objects) {
NSString *className = [object objectForKey:#"class_name"];
NSMutableArray *objectsInSection = [self.sections objectForKey:className];
if (!objectsInSection) {
objectsInSection = [NSMutableArray array];
// Create new section for new class found
[self.sectionToClassMap setObject:className forKey:[NSNumber numberWithInt:section++]];
}
[objectsInSection addObject:[NSNumber numberWithInt:rowIndex++]];
[self.sections setObject:objectsInSection forKey:className];
}
}
- (PFObject *)objectAtIndexPath:(NSIndexPath *)indexPath
{
NSString *className = [self classForSection:indexPath.section];
NSArray *rowIndicesInSection = [self.sections objectForKey:className];
NSNumber *rowIndex = [rowIndicesInSection objectAtIndex:indexPath.row];
return [self.objects objectAtIndex:[rowIndex intValue]];
}
- (NSString *)classForSection:(NSInteger)section
{
return [self.sectionToClassMap objectForKey:[NSNumber numberWithInt:section]];
}
#end
When I look at the NSLog data, self.objects is empty. I know this is the reason why data isn't displayed, and would like some advice to sort this out please! Thanks.

PFQueryTableViewController loading for 5 minutes

I followed this tutorial here https://parse.com/questions/using-pfquerytableviewcontroller-for-uitableview-sections and was able to create a beautiful table with sections, but it takes forever to load! Well, not forever, 5 minutes to be exact. My table in parse has 587 rows in it and it takes 5 minutes to load all of the objects into sections. The first few minutes shows the "Loading..." on the blank view, then there is an empty tableview, and finally all of the objects load. Is there a reason something like this is taking so long? I can't have my users wait 5 minutes for something to load. This tableview is displayed during the register process. It is a list of schools and the new user must select which school they are from. The sections organize the schools based on location, and there are about 30 sections. Any suggestions for getting this to load faster?
Here is the code for the SchoolFinderViewController.m file
#import "SchoolFinderViewController.h"
#interface SchoolFinderViewController ()
#property (nonatomic, retain) NSMutableDictionary *sections;
#property (nonatomic, retain) NSMutableDictionary *sectionToRegionMap;
#end
#implementation SchoolFinderViewController
#synthesize sections = _sections;
#synthesize sectionToRegionMap = _sectionToRegionMap;
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
self.parseClassName = #"School";
self.textKey = #"Name";
self.pullToRefreshEnabled = NO;
self.paginationEnabled = YES;
self.objectsPerPage = 600;
self.sections = [NSMutableDictionary dictionary];
self.sectionToRegionMap = [NSMutableDictionary dictionary];
}
return self;
}
-(void)viewDidLoad
{
[super viewDidLoad];
self.title = #"Schools";
}
#pragma mark - PFQueryTableViewController
- (void)objectsDidLoad:(NSError *)error {
[super objectsDidLoad:error];
// This method is called every time objects are loaded from Parse via the PFQuery
NSLog(#"Count in objectsDidLoad: %lu", (unsigned long)[self.objects count]);
[self.sections removeAllObjects];
[self.sectionToRegionMap removeAllObjects];
NSInteger section = 0;
NSInteger rowIndex = 0;
int i = 0;
for (PFObject *object in self.objects) {
PFObject *obj = [object objectForKey:#"region"];
[obj fetchIfNeeded];
NSLog(#"School %#", [object objectForKey:#"Name"]);
NSString *Region = [obj objectForKey:#"name"];
NSLog(#"Reg: %#", Region);
NSMutableArray *objectsInSection = [self.sections objectForKey:Region];
if (!objectsInSection) {
objectsInSection = [NSMutableArray array];
NSLog(#"Is this called? %d", i);
// this is the first time we see this Region - increment the section index
[self.sectionToRegionMap setObject:Region forKey:[NSNumber numberWithInt:section++]];
}
[objectsInSection addObject:[NSNumber numberWithInt:rowIndex++]];
[self.sections setObject:objectsInSection forKey:Region];
}
NSLog(#"Finally done...");
}
- (PFQuery *)queryForTable {
PFQuery *query = [PFQuery queryWithClassName:self.parseClassName];
query.cachePolicy = kPFCachePolicyCacheThenNetwork;
// If no objects are loaded in memory, we look to the cache first to fill the table
// and then subsequently do a query against the network.
if (self.objects.count == 0) {
query.cachePolicy = kPFCachePolicyCacheThenNetwork;
}
// Order by name
[query orderByAscending:#"Name"];
return query;
}
- (PFObject *)objectAtIndexPath:(NSIndexPath *)indexPath {
NSString *Region = [self RegionForSection:indexPath.section];
NSArray *rowIndecesInSection = [self.sections objectForKey:Region];
NSNumber *rowIndex = [rowIndecesInSection objectAtIndex:indexPath.row];
return [self.objects objectAtIndex:[rowIndex intValue]];
}
#pragma mark - UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return self.sections.allKeys.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSString *Region = [self RegionForSection:section];
NSArray *rowIndecesInSection = [self.sections objectForKey:Region];
return rowIndecesInSection.count;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
NSString *Region = [self RegionForSection:section];
return Region;
}
#pragma mark - UITableViewDelegate
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
NSLog(#"CellFor %ld", (long)indexPath.row);
cell.textLabel.text = [object objectForKey:#"Name"];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[super tableView:tableView didSelectRowAtIndexPath:indexPath];
PFObject *selectedObject = [self objectAtIndexPath:indexPath];
}
#pragma mark - ()
- (NSString *)RegionForSection:(NSInteger)section {
return [self.sectionToRegionMap objectForKey:[NSNumber numberWithInt:section]];
}
Yeah, you're not going to be able to make this fast enough as-is... The client should not have to download every object first, and scrolling lists with 500+ items are not a good user experience. Perhaps you should have an initial screen where they pick some subset, and then they can query a smaller set of data on the next screen. What you're currently using as a section might be a good candidate.

How do I retrieve information from cell in table view?

I want to be able to set a label's text to be what is selected from the table view.
#interface STAdvancedBACViewController ()
#property (nonatomic, copy) NSDictionary *brand;
#property (nonatomic, copy) NSArray *keys;
#property (nonatomic, copy) NSMutableArray *filteredNames;
#property (nonatomic, strong) UISearchDisplayController *searchController;
#property (nonatomic, copy) NSDictionary *beerValues;
#property (nonatomic, copy) NSArray *beerKeys;
#end
#implementation STAdvancedBACViewController {
}
#synthesize brand, keys, filteredNames, searchController, beerValues, beerKeys;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
UITableView *tableView = (id)[self.view viewWithTag:1];
[tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"Cell"];
NSString *path = [[NSBundle mainBundle] pathForResource:#"A" ofType:#"plist"];
brand = [NSDictionary dictionaryWithContentsOfFile:path];
keys = [[brand allKeys]sortedArrayUsingSelector:#selector(compare:)];
filteredNames = [[NSMutableArray alloc]init];
searchController = [[UISearchDisplayController alloc]init];
searchController.searchResultsDataSource = self;
NSString *path2 = [[NSBundle mainBundle] pathForResource:#"BEER2" ofType:#"plist"];
beerValues = [NSDictionary dictionaryWithContentsOfFile:path2];
beerKeys = [[beerValues allKeys] sortedArrayUsingSelector:#selector(compare:)];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
if (tableView.tag == 1) {
return [keys count];
}
else{
return 1;
}
}
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (tableView.tag == 1) {
NSString *key = keys[indexPath.section];
NSArray *keyValues = brand[key];
cell.textLabel.text = keyValues[indexPath.row];
}
else{
cell.textLabel.text = filteredNames[indexPath.row];
}
return cell;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (tableView.tag == 1) {
NSString *key = keys[section];
NSArray *keyValues = brand[key];
return [keyValues count];
}
else {
return [filteredNames count];
}
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
if (tableView.tag ==1) {
return keys;
}
else {
return nil;
}
}
- (NSString *) tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if (tableView.tag ==1) {
return keys[section];
}
else {
return nil;
}
}
#pragma mark
- (void)searchDisplayController:(UISearchDisplayController *)controller didLoadSearchResultsTableView:(UITableView *)tableView {
[tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"Cell"];
}
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
[filteredNames removeAllObjects];
if (searchString.length > 0) {
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF contains [search] %#", self.searchBar.text];
for (NSString *key in keys) {
NSArray *matches = [brand[key]filteredArrayUsingPredicate:predicate];
[filteredNames addObjectsFromArray:matches];
}
}
return YES;
}
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {
_testLabel.text = keys[indexPath.row];
}
#end
For some reason this does not return the value in the cell but returns a letter from the Plist file. The plist file was organized such that there were 26 objects that were arrays for each letter of the alphabet and then those were arrays containing the beer names. Basically I want to retrieve the beer name selected by the user.
Though your question is a bit unclear, but I guess you want a label to be the name of the brand that the user selected. In your cellForRowAtIndexPath you are doing this:
if (tableView.tag == 1) {
NSString *key = keys[indexPath.section];
NSArray *keyValues = brand[key];
cell.textLabel.text = keyValues[indexPath.row];
}
else{
cell.textLabel.text = filteredNames[indexPath.row];
}
But in your didDeselectRowAtIndexPath you are just doing this:
_testLabel.text = keys[indexPath.row];
Shouldn't you be doing this in didDeselectRowAtIndexPath:
//Plan your logic accordingly. Its just a rough
if (tableView.tag == 1) {
NSString *key = keys[indexPath.section];
NSArray *keyValues = brand[key];
_testLabel.text = keyValues[indexPath.row];
}
else{
_testLabel.text = filteredNames[indexPath.row];
}
Hope this helps.. :)

Adding additional data to inner array with sorted outer array

I have a plist with contacts: the root is an array, items 0-150 are dictionaries, each dictionary is a single contact with a "name", "number", and "email" string.
The code below sorts the contacts alphabetically into sections based upon the "name" string. Then uses the inner array to populate the cells for each section. I then pass the name from the inner array to my detail view.
However, I can not figure out how to pass the correct number and email for each contact into the detail view. I've been working on this issue for a long while and can not find a solution.
#interface ContactsViewController ()
-(void)configureSectionData;
#end
#implementation ContactsViewController
#synthesize tableData;
#synthesize collation;
#synthesize outerArray;
#synthesize indexTitlesArray, namesDictionary;
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - Table view methods
-(void)configureSectionData {
NSUInteger sectionTitlesCount = [collation.sectionTitles count];
self.outerArray = [NSMutableArray arrayWithCapacity:sectionTitlesCount];
for (NSUInteger index = 0; index < sectionTitlesCount; index++) {
NSMutableArray *array = [NSMutableArray array];
[self.outerArray addObject:array];
}
for (NSString *nameString in tableData)
{
NSInteger sectionNumber = [collation sectionForObject:nameString collationStringSelector:#selector(lowercaseString)];
NSMutableArray *sectionNames = [outerArray objectAtIndex:sectionNumber];
[sectionNames addObject:nameString];
}
for (NSUInteger index = 0; index < sectionTitlesCount; index++) {
NSMutableArray *namesForSection = [outerArray objectAtIndex:index];
NSArray *sortedNamesForSection = [collation sortedArrayFromArray:namesForSection collationStringSelector:#selector(lowercaseString)];
[self.outerArray replaceObjectAtIndex:index withObject:sortedNamesForSection];
}
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [self.collation.sectionTitles count];
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
NSString *theLetter = [self.collation.sectionTitles objectAtIndex:section];
if (![theLetter isEqualToString:#"#"]) {
NSString *titleString = [NSString stringWithFormat:#"%#", theLetter];
return titleString;
}
return nil;
}
-(NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
return self.collation.sectionTitles;
}
-(NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
return [self.collation sectionForSectionIndexTitleAtIndex:index];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSArray *innerArray = [self.outerArray objectAtIndex:section];
return [innerArray count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"cellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
// Get the inner array for this section
NSArray *innerArray = [self.outerArray objectAtIndex:indexPath.section];
// Get the name from the inner array
NSString *theName = [innerArray objectAtIndex:indexPath.row];
cell.textLabel.text = theName;
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainiPhoneStoryboard" bundle:nil];
DetailViewController *detailView = (DetailViewController *)[storyboard instantiateViewControllerWithIdentifier:#"DetailViewController"];
// Get the inner array for this section
NSArray *innerArray = [self.outerArray objectAtIndex:indexPath.section];
// Get the name from the inner array
NSString *tmpname = [innerArray objectAtIndex:indexPath.row];
detailView.lblname = tmpname;
[self presentViewController:detailView animated:YES completion:nil];
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.namesDictionary = [NSMutableArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"contacts" ofType:#"plist"]];
self.tableData = [namesDictionary valueForKey:#"name"];
self.collation = [UILocalizedIndexedCollation currentCollation];
[self configureSectionData];
}
Since you're populating your table from an array of just the names from your plist, you'll have to search that array using the name to find the dictionary that it belongs to, so you can pass that to the detail view controller (you would need to create a property in your detail view controller, passedInDictionary in my example):
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainiPhoneStoryboard" bundle:nil];
DetailViewController *detailView = (DetailViewController *)[storyboard instantiateViewControllerWithIdentifier:#"DetailViewController"];
// Get the inner array for this section
NSArray *innerArray = [self.outerArray objectAtIndex:indexPath.section];
// Get the name from the inner array
NSString *tmpname = [innerArray objectAtIndex:indexPath.row];
NSInteger indx = [self.namesDictionary indexOfObjectPassingTest:^BOOL(NSDictionary *dict, NSUInteger idx, BOOL *stop) {
return [dict[#"name"] isEqualToString:tmpname];
}];
NSDictionary *dict = self.namesDictionary[indx];
detailView.passedInDictionary = dict;
[self presentViewController:detailView animated:YES completion:nil];
}

Resources