Evening,
I am in the process of configuring my detail view. The data is held in a plist file, each item having a word and definition. The cells in the tableview are labelled with the word. I am looking for each word to lead to the detail view showing both word and definition.
At the moment the code is showing the wrong word. I have been trying to set word and definition in the tableview.m and then use these to set the label in detail view.
So my query is why the wrong word is showing and how I can grab the correct definition to match the word.
My code is below.
Thank you.
#import "RCViewController.h"
#import "detailViewController.h"
#interface RCViewController ()
#end
#implementation RCViewController
static NSString *CellIdentifier = #"Cell Identifier";
#synthesize words;
#synthesize alphabetizedWords;
#synthesize wordDictionary;
-(NSDictionary *)alphabetizedWords:(NSArray *)wordsArray {
NSMutableDictionary *buffer = [[NSMutableDictionary alloc]init];
for (int i=0; i <words.count; i++) {
NSString *word = [words objectAtIndex:i];
NSString *firstLetter = [[word substringToIndex:1]uppercaseString];
if ([buffer objectForKey:firstLetter]) {
[(NSMutableArray *)[buffer objectForKey:firstLetter]addObject:word];
}
else {
NSMutableArray *mutableArray = [[NSMutableArray alloc]initWithObjects:word, nil];
[buffer setObject:mutableArray forKey:firstLetter];
}
}
NSArray *keys = [buffer allKeys];
for (int j; j<keys.count; j++) {
NSString *key = [keys objectAtIndex:j];
[(NSMutableArray *)[buffer objectForKey:key]sortUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
}
NSDictionary *result = [NSDictionary dictionaryWithDictionary:buffer];
return result;
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
NSArray *keys = [self.alphabetizedWords allKeys];
return [keys count];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSArray *unsortedKeys = [self.alphabetizedWords allKeys];
NSArray *sortedKeys = [unsortedKeys sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
NSString *key = [sortedKeys objectAtIndex:section];
NSArray *wordsForSection = [self.alphabetizedWords objectForKey:key];
return [wordsForSection count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
NSArray *unsortedKeys = [self.alphabetizedWords allKeys];
NSArray *sortedKeys = [unsortedKeys sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
NSString *key = [sortedKeys objectAtIndex:[indexPath section]];
NSArray *wordsForSection = [self.alphabetizedWords objectForKey:key];
NSString *word = [wordsForSection objectAtIndex:[indexPath row]];
[cell.textLabel setText:word];
return cell;
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
NSArray *keys = [[self.alphabetizedWords allKeys]sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
NSString *key = [keys objectAtIndex:section];
return key;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// perform the segue by getting the cell selected and passing it to the prepareForSegue method
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[self performSegueWithIdentifier:#"showDetail" sender:cell];
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([segue.identifier isEqualToString:#"showDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
detailViewController *destViewController = segue.destinationViewController;
destViewController.word = [words objectAtIndex:indexPath.row];
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSString *path = [[NSBundle mainBundle]pathForResource:#"words" ofType:#"plist"];
NSArray *wordsDictionary = [NSArray arrayWithContentsOfFile:path];
self.words = [wordsDictionary valueForKey:#"Word"];
self.alphabetizedWords = [self alphabetizedWords:self.words];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:CellIdentifier];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
#import <UIKit/UIKit.h>
#interface detailViewController : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *wordLabel;
#property (nonatomic, strong) NSString *word;
#property (weak, nonatomic) IBOutlet UILabel *definitionLabel;
#property (strong, nonatomic)NSString *definition;
#end
#import "detailViewController.h"
#interface detailViewController ()
#end
#implementation detailViewController
#synthesize word;
#synthesize wordLabel;
#synthesize definition;
#synthesize definitionLabel;
- (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.
wordLabel.text = word;
definitionLabel.text = definition;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
#end
You need to use the same logic in prepareForSegue to get your word that you use in cellForRowAtIndexPath,
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([segue.identifier isEqualToString:#"showDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
detailViewController *destViewController = segue.destinationViewController;
NSArray *unsortedKeys = [self.alphabetizedWords allKeys];
NSArray *sortedKeys = [unsortedKeys sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
NSString *key = [sortedKeys objectAtIndex:[indexPath section]];
NSArray *wordsForSection = [self.alphabetizedWords objectForKey:key];
NSString *word = [wordsForSection objectAtIndex:[indexPath row]];
destViewController.word = word;
}
}
Having a dictionary called alphabetizedWords is pretty pointless, since dictionaries are inherently unordered. You should set up your data structure in an array. Perhaps you want an array of dictionaries, where each dictionary contains a word in one key and the definition in the other key. You can sort the array and use to feed the table view data source, and also to respond to a tap and pass the info to your detail view controller.
Related
I am using Tableview to display Name from recipes Array which works great and displays all name in table view from recipes Array. When i tap on one of the recipe it displays the name on detailed view.
What i am stuck of is, how to display other fields in the detailed view.I have an Array ( array name: ingredients ) which has contents of that specific recipe, example ingredients.
I tried with
cell.textLabel.text = [ingredients objectAtIndex:indexPath.row];
RecipeDetailViewController.h
#import <UIKit/UIKit.h>
#interface RecipeDetailViewController : UIViewController
#property (nonatomic, strong) IBOutlet UILabel *recipeLabel;
#property (nonatomic, strong) NSString *recipeName;
#property (strong, nonatomic) IBOutlet UILabel *recipeCountry;
#property (nonatomic, strong) NSString *recipeCountryName;
#end
but it doesn't show anything in RecipeBookViewController.m
Here is my Original code
#import "RecipeBookViewController.h"
#import "RecipeDetailViewController.h"
#interface RecipeBookViewController ()
#end
#implementation RecipeBookViewController {
NSArray *recipes;
}
#synthesize tableView;
- (void)viewDidLoad
{
[super viewDidLoad];
NSData *allCourseData=[[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:#"http://api.kivaws.org/v1/loans/search.json?status=fundraising"]];
NSError *error;
NSMutableDictionary *JsonObject = [NSJSONSerialization
JSONObjectWithData:allCourseData options:NSJSONReadingMutableContainers
error:&error];
NSArray *loans = JsonObject[#"loans"];
// Create a new loans array for store the new items
NSMutableArray *newLoans = [NSMutableArray array];
NSMutableArray *arrCountry = [NSMutableArray array];
for (NSDictionary *loan in loans) {
NSNumber *ident = loan[#"id"];
NSString *name = loan[#"name"];
NSDictionary *description = loan[#"description"];
NSDictionary *location = loan[#"location"];
NSString *country = location[#"country"];
NSString *status = loan[#"status"];
NSDictionary *geo = location[#"geo"];
NSString *geoprint = geo[#"pairs"];
[newLoans addObject:name];
[arrCountry addObject:country];
}
recipes=newLoans;
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [recipes count];
}
//Display Name in Detail View
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"RecipeCell";
//Displays name
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = [recipes objectAtIndex:indexPath.row];
return cell;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showRecipeDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
RecipeDetailViewController *destViewController = segue.destinationViewController;
destViewController.recipeName = [recipes objectAtIndex:indexPath.row];
}
}
#end
RecipeDetailViewController.m
#import "RecipeDetailViewController.h"
#interface RecipeDetailViewController ()
#end
#implementation RecipeDetailViewController
#synthesize recipeLabel;
#synthesize recipeName;
#synthesize recipeCountry;
#synthesize recipeCountryName;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Set the Label text with the selected recipe
recipeLabel.text = recipeName;
recipeCountry.text=recipeCountryName;
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
Here are the screenshots of both Views
Changes in your loop;
for (NSDictionary *loan in loans) {
NSNumber *ident = loan[#"id"];
NSString *name = loan[#"name"];
NSDictionary *description = loan[#"description"];
NSDictionary *location = loan[#"location"];
NSString *country = location[#"country"];
NSString *status = loan[#"status"];
NSDictionary *geo = location[#"geo"];
NSString *geoprint = geo[#"pairs"];
[newLoans addObject:#[
#"name":name,
#"description":description,
#"country ":country
]]; // Same way add all keys
//Or
/*
NSMutableDictionary* dicData = [NSMutableDictionary dictionary];
newLoans[#"name"] = name;
newLoans[#"description"] = description;
newLoans[#"country"] = country;
[newLoans addObject:dicData];
*/
}
recipes=newLoans;
Change when retrieving;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
. . .
NSDictionary * dict = [recipes objectAtIndex:indexPath.row];
cell.textLabel.text = dict[#"name"];
return cell;
}
Same way pass the complete dictionary to the RecipeDetailViewController and show other information there.
i got a problem with my tableview segue and the detail view controller. i managed to populate my table view with titles and subtitles with nsdictionary. however i could not push my title and subtitle to the detail view. i need my title to go on the navigation bar and the subtitle to a label in the detail view. here is the code and the screenshots of my table view and the detail view:
#import "TableViewController.h"
#import "DetailViewController.h"
#interface TableViewController (){
NSDictionary *sarkilar;
NSArray *sarkilarSectionTitles;
NSArray *sarkilarIndexTitles;
}
#end
#implementation TableViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIBarButtonItem *newButton = [[UIBarButtonItem alloc] initWithTitle:#"" style:UIBarButtonItemStylePlain target:nil action:nil];
[[self navigationItem] setBackBarButtonItem:newButton];
sarkilar = #{
#"A" : #[#{#"title":#"Alayına İsyan",#"subtitle":#"Seslendiren: Mustafa Sandal"},
#{#"title":#"Ardindan",#"subtitle":#"Seslendiren: Sinasi Gurel"}],
#"B" : #[#{#"title":#"Birak Gitsin",#"subtitle":#"Seslendiren: Tarkan"},
#{#"title":#"Buralar",#"subtitle":#"Seslendiren: Duman"}],
#"C" : #[#{#"title":#"Cephaneler",#"subtitle":#"Seslendiren: Burak Kut"},
#{#"title":#"Cari Acik",#"subtitle":#"Seslendiren: Kristal"}],
};
sarkilarSectionTitles = [[sarkilar allKeys] sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
sarkilarIndexTitles = #[#"A", #"B", #"C",#"Ç", #"D", #"E", #"F", #"G", #"H", #"I",#"İ", #"J", #"K", #"L", #"M", #"N", #"O", #"Ö", #"P", #"R", #"S",#"Ş", #"T", #"U",#"Ü", #"V", #"Y", #"Z"];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [sarkilarSectionTitles count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSString *sectionTitle = [sarkilarSectionTitles objectAtIndex:section];
NSArray *sectionSarkilar = [sarkilar objectForKey:sectionTitle];
return [sectionSarkilar count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return [sarkilarSectionTitles objectAtIndex:section];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
NSString *sectionTitle = [sarkilarSectionTitles objectAtIndex:indexPath.section];
NSArray *sectionSarkilar = [sarkilar objectForKey:sectionTitle];
NSDictionary *dict = [sectionSarkilar objectAtIndex:indexPath.row];
NSString *title = [dict objectForKey:#"title"];
NSString *subtitle = [dict objectForKey:#"subtitle"];
cell.textLabel.text = title;
cell.detailTextLabel.text = subtitle;
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
// return animalSectionTitles;
return sarkilarIndexTitles;
}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index
{
return [sarkilarSectionTitles indexOfObject:title];
}
//-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
//
// if ([[segue identifier] isEqualToString:#"ShowDetails"]) {
// DetailViewController *detailView = [segue destinationViewController];
//
// NSIndexPath *myindexpath = [self.tableView indexPathForSelectedRow];
//
// int row = [myindexpath row];
// detailView.DetailModal = #[_title[row], subtitle[row],];
// }
//
//
//
//}
//
#end
as you can see i couldn't figure out how to set my segue up. and here are the screenshots. i hope it is not too much to ask how to set up the segue
You can get the currently selected cell and pass the values in the prepareForSegue: method.
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
UIViewController *destinationViewController = segue.destinationViewController;
UITableViewCell *selectedCell = [self.tableView cellForRowAtIndexPath:self.tableView.indexPathForSelectedRow];
destinationViewController.title = selectedCell.textLabel.text;
//Add code to set label to selectedCell.detailTextLabel.text
}
To be clear, you will need to implement the delegate method for when a cell is selected, then call your segue. (Assuming this is the way your app will operate)
//TableViewController.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self performSegueWithIdentifier:#"ShowDetails" sender:self];
}
Then before the transition the method prepareForSegue will be called, where you can set up any properties on your DetailViewController.
//TableViewController.m
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"ShowDetails"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
DetailViewController *detailVC = segue.destinationViewController;
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
detailVC.myTitle = cell.textLabel.text;
detailVC.mySubtitle = cell.detailTextLabel.text;
}
}
Add these properties to your DetailViewController header file to pass the references to your title and subtitle.
//DetailViewController.h
#property (nonatomic, strong) NSString *myTitle;
#property (nonatomic, strong) NSString *mySubtitle;
Then in the viewDidLoad method of your DetailViewController set the navigation title and label properties
//DetailViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.title = self.myTitle;
self.myLabelName.text = self.mySubtitle;
}
I have the following code. It results in a sectioned uitableview. However, the words in each section are in reverse order (r before a, x before t). I have tried to use nsdescriptor and selectors in various parts of the code but it results in Xcode throwing nsexception ncsf dictionary invalid selector sent localisedcaseinsensitivecompare. This only occurs when I fiddle with the above - even if I don't add localisedCaseInsensitiveCompare (it works with those instances that are already in place).
Any fresh eyes able to solve this.
Thanks
#implementation RCViewController
static NSString *CellIdentifier = #"Cell Identifier";
#synthesize words;
#synthesize alphabetizedWords;
#synthesize wordDictionary;
#synthesize keys;
-(NSDictionary *)alphabetizedWords:(NSArray *)wordsArray {
NSMutableDictionary *buffer = [[NSMutableDictionary alloc]init];
for (int i=0; i <wordsArray.count; i++) {
NSDictionary *keyValue = [wordsArray objectAtIndex:i];
NSString *word = [[wordsArray objectAtIndex:i]objectForKey:#"Word"];
NSString *firstLetter = [[word substringToIndex:1]uppercaseString];
if ([buffer objectForKey:firstLetter]) {
[(NSMutableArray *)[buffer objectForKey:firstLetter]addObject:keyValue];
}
else {
NSMutableArray *mutableArray = [[NSMutableArray alloc]initWithObjects:keyValue, nil];
[buffer setObject:mutableArray forKey:firstLetter];
}
}
NSArray *bufferKeys = [buffer allKeys];
for (int j; j<bufferKeys.count; j++) {
NSString *bufferkey = [bufferKeys objectAtIndex:j];
[(NSMutableArray *)[buffer objectForKey:bufferkey]sortUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
}
NSDictionary *result = [NSDictionary dictionaryWithDictionary:buffer];
return result;
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [keys count];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSString *key = [_sortedKeys objectAtIndex:section];
NSArray *wordsForSection = [self.alphabetizedWords objectForKey:key];
return [wordsForSection count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
NSString *key = [_sortedKeys objectAtIndex:[indexPath section]];
NSArray *wordsForSection = [self.alphabetizedWords objectForKey:key];
NSString *word = [[wordsForSection objectAtIndex:[indexPath row]]objectForKey:#"Word"];
[cell.textLabel setText:word];
return cell;
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
NSString *key = [_sortedKeys objectAtIndex:section];
return key;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[self performSegueWithIdentifier:#"showDetail" sender:cell];
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([segue.identifier isEqualToString:#"showDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
detailViewController *destViewController = segue.destinationViewController;
NSString *key = [_sortedKeys objectAtIndex:[indexPath section]];
NSArray *wordsForSection = [self.alphabetizedWords objectForKey:key];
NSString *word = [[wordsForSection objectAtIndex:[indexPath row]]objectForKey:#"Word"];
destViewController.word = word;
destViewController.definition = [[wordsForSection objectAtIndex:[indexPath row] ]objectForKey:#"Definition"];
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSString *path = [[NSBundle mainBundle]pathForResource:#"words" ofType:#"plist"];
NSArray *wordsDictionary = [NSArray arrayWithContentsOfFile:path];
self.words = wordsDictionary;
self.alphabetizedWords = [self alphabetizedWords:self.words];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:CellIdentifier];
self.keys = [self.alphabetizedWords allKeys];
self.sortedKeys = [keys sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
You are creating an array of dictionaries. Dictionaries don't support the compare method. You therefore can't use a selector based sort. You need to use a different sort method, like sortUsingComparator, or a predicate. (There are lots of different ways to sort arrays.)
If you just have to reverse the position of element of array you could use following
NSArray *wordArray = [[NSArray alloc] initWithObjects:#"Brian",#"Job",#"Bob",#"Ben",#"Robert", nil];
wordArray = [[wordArray reverseObjectEnumerator] allObjects];
Your output will be : Robert, Ben, Bob, Job, Brian.
Evening,
I have managed to section my table alphabetically (:D) but now the cells do not select.
The idea is that the first view presents a list of words. A word is then selected and that leads to a detail view featuring a glossary. But, the cell doesn't select (turns grey not blue?) and the segue in storyboard running from prototype cell to new view doesn't do anything (clicking a cell in simulator doesn't cause the segue).
Does anyone have a suggestion?
I have included my code below, with the prepareforsegue code ready for when needed.
Thanks guys :)
#interface RCViewController ()
#end
#implementation RCViewController
static NSString *CellIdentifier = #"Cell Identifier";
#synthesize fruits;
-(NSDictionary *)alphabetizedFruits:(NSArray *)fruitsArray {
NSMutableDictionary *buffer = [[NSMutableDictionary alloc]init];
for (int i=0; i <fruits.count; i++) {
NSString *fruit = [fruits 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];
}
}
NSArray *keys = [buffer allKeys];
for (int j; j<keys.count; j++) {
NSString *key = [keys objectAtIndex:j];
[(NSMutableArray *)[buffer objectForKey:key]sortUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
}
NSDictionary *result = [NSDictionary dictionaryWithDictionary:buffer];
return result;
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
NSArray *keys = [self.alphabetizedFruits allKeys];
return [keys count];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSArray *unsortedKeys = [self.alphabetizedFruits allKeys];
NSArray *sortedKeys = [unsortedKeys sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
NSString *key = [sortedKeys objectAtIndex:section];
NSArray *fruitsForSection = [self.alphabetizedFruits objectForKey:key];
return [fruitsForSection count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
NSArray *unsortedKeys = [self.alphabetizedFruits allKeys];
NSArray *sortedKeys = [unsortedKeys sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
NSString *key = [sortedKeys objectAtIndex:[indexPath section]];
NSArray *fruitsForSection = [self.alphabetizedFruits objectForKey:key];
NSString *fruit = [fruitsForSection objectAtIndex:[indexPath row]];
[cell.textLabel setText:fruit];
return cell;
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
NSArray *keys = [[self.alphabetizedFruits allKeys]sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
NSString *key = [keys objectAtIndex:section];
return key;
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([segue.identifier isEqualToString:#"showDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
detailViewController *destViewController = segue.destinationViewController;
destViewController.word = [fruits objectAtIndex:indexPath.row];
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSString *path = [[NSBundle mainBundle]pathForResource:#"words" ofType:#"plist"];
NSArray *wordsDictionary = [NSArray arrayWithContentsOfFile:path];
self.fruits = [wordsDictionary valueForKey:#"Word"];
self.alphabetizedFruits = [self alphabetizedFruits:self.fruits];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:CellIdentifier];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
you need to add the didSelectRowAtIndexPath method:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// confirm cell is being selected
NSLog(#"didSelectRowAtIndexPath");
// perform the segue by getting the cell selected and passing it to the prepareForSegue method
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[self performSegueWithIdentifier:#"showDetail" sender:cell];
}
I cant find results using my search bar. See my code attached:
// ViewController.m
#import "ViewController.h"
#implementation ViewController
#synthesize names;
#synthesize keys;
#pragma mark - View lifecycle
- (void)viewDidLoad
{
NSString *path = [[NSBundle mainBundle] pathForResource:#"sortednames"ofType:#"plist"];
NSDictionary *dict = [[NSDictionary alloc]initWithContentsOfFile:path];
self.names = dict;
NSArray *array = [[names allKeys] sortedArrayUsingSelector:#selector(compare:)];
self.keys = array;
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
#pragma mark -
#pragma mark Table View Data Source Methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [keys count];
}
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
{
NSString *key = [keys objectAtIndex:section];
NSArray *nameSection = [names objectForKey:key];
return [nameSection count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSUInteger section = [indexPath section];
NSUInteger row = [indexPath row];
NSString *key = [keys objectAtIndex:section];
NSArray *nameSection = [names objectForKey:key];
static NSString *SectionsTableIdentifier = #"SectionsTableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:
SectionsTableIdentifier ];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier: SectionsTableIdentifier ];
}
cell.textLabel.text = [nameSection objectAtIndex:row];
return cell;
}
- (NSString *)tableView:(UITableView *)tableView
titleForHeaderInSection:(NSInteger)section
{
NSString *key = [keys objectAtIndex:section];
return key;
}
http://i.stack.imgur.com/ZBzJZ.png
http://i.stack.imgur.com/ktevQ.png
here is my "h" file:
//
// ViewController.h
// Sections
//
// Created by t r on 3/17/12.
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
<UITableViewDataSource, UITableViewDelegate, UISearchBarDelegate>
{
NSDictionary *names;
NSArray *keys;
}
#property (nonatomic, retain) NSDictionary *names;
#property (nonatomic, retain) NSArray *keys;
#end
The UIsearchBar does not automatically do a search on the tabelview content. You have to implement the UISearchbarDelegate methods to detect the entered text, then reload the table view and return values in the table view delegate methods according to the new array filtered with the search criteria.