Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I had an application in which I had a response like:
{
"16-06-2016" = (
{
cccc = 16;
dddd = 17;
}
);
"17-06-2016" = (
{
cccc = 14;
dddd = 19;
},
{
cccc = 1;
dddd = 9;
}
);
"18-06-2016" = (
{
cccc = 14;
dddd = 19;
},
{
cccc = 1;
dddd = 9;
}
);
}
How will I display this NSDictionary in my UITableView. Can anybody help me?
Try something like this
self.sectionArr = [jsonDic allKeys]; //First get all section from dictionary like this
Now implement TableView delegate methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return self.sectionArr.count;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return [self.sectionArr objectAtIndex:section];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSArray *arr = [jsonDic objectForKey:[self.sectionArr objectAtIndex:section]];
return arr.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell= [tableview dequeueReusableCellWithIdentifier:#"Cell"];
NSArray *arr = [jsonDic objectForKey:[self.sectionArr objectAtIndex:indexPath.section]];
cell.textLabel.text = [[arr objectAtIndex:indexPath.row] valueForKey:#"dddd"];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSArray *arr = [jsonDic objectForKey:[self.sectionArr objectAtIndex:indexPath.section]];
NSLog(#"Selected Obj - %#",[[arr objectAtIndex:indexPath.row] valueForKey:#"dddd"]);
}
Hope this will help you.
When I display an NSDictionary in a UITableView, since delegate methods like cellForRowAtIndexPath uses indexes, I typically do something like this to get an item at a particular index:
-(UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// Get array of keys
NSArray *keys = [self.dictionary allKeys];
// Get key for the current row
NString *key = [keys objectAtIndex:indexPath.row];
// Get object for current row
id object = [self.dictionary objectForKey:key];
// Then do the typical stuff
UITableViewCell *cell = [tableview dequeueReusableCellWithIdentifier:#"Cell"
forIndexPath:indexPath];
....
Though, in your case, "object" is an NSDictionary, so do something like this:
...
// Get object for current row
NSDictionary *item = [self.dictionary objectForKey:key];
id cccc = [item objectForKey:#"cccc"];
id dddd = [item objectForKey:#"dddd"];
....
If you need the keys sorted, then use keysSortedByValueUsingSelector: rather than allKeys.
Maybe something like this?
(I put data you've provided into dict variable)
#interface MainViewController () {
NSDictionary *dict;
NSArray *sortedKeysAsSectionNames;
}
- (void)viewDidLoad {
[super viewDidLoad];
dict = #{#"16-06-2016": #[#{#"cccc": #(16), #"dddd": #(17)}],
#"17-06-2016": #[#{#"cccc": #(14), #"dddd": #(19)},
#{#"cccc": #(1), #"dddd": #(9)}],
#"18-06-2016": #[#{#"cccc": #(14), #"dddd": #(19)},
#{#"cccc": #(1), #"dddd": #(9)}]
};
NSArray *dictKeys = [dict allKeys];
sortedKeysAsSectionNames = [dictKeys sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {
NSDateFormatter *format = [[NSDateFormatter alloc] init];
format.dateFormat = #"dd-MM-yyyy";
NSDate *date1 = [format dateFromString:(NSString *)obj1];
NSDate *date2 = [format dateFromString:(NSString *)obj2];
return [date1 compare:date2];
}];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return sortedKeysAsSectionNames.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [(NSArray *)[dict objectForKey:sortedKeysAsSectionNames[section]] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
id key = sortedKeysAsSectionNames[indexPath.section];
NSArray *dataInSectionArray = [dict objectForKey:key];
NSDictionary *dataForCellDict = [dataInSectionArray objectAtIndex:indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"cell"];
}
cell.textLabel.text = [[dataForCellDict objectForKey:#"cccc"] description];
cell.detailTextLabel.text = [[dataForCellDict objectForKey:#"dddd"] description];
return cell;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return sortedKeysAsSectionNames[section];
}
Related
I'm making a title indexed event invitation list. I have an array with EventStatus objects. I'm making the _data array for table like,
for (int i = 0; i < eventStatusList.count; i++) {
NSString *firstName = ((OCEventStatus*)eventStatusList[i]).user.firstName;
[_sortedUsers setObject:((OCEventStatus*)eventStatusList[i]).user.firstName forKey:[firstName substringToIndex:1]];
}
_sortedUserTitles = [[[_sortedUsers allKeys] sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)] mutableCopy];
_data = [eventStatusList mutableCopy];
[self.dataTableView reloadData];
and I think this for loop thing is too slow. Is there a way to do this in a good manner? Following is the title index making up logic with UITablrViewDataSource methods.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return [_sortedUserTitles count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
NSString *sectionTitle = [_sortedUserTitles objectAtIndex:section];
NSArray *sectionUsers = [_sortedUsers objectForKey:sectionTitle];
return [sectionUsers count];
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
// return animalSectionTitles;
return _alphabetArray;
}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index
{
return [_sortedUserTitles indexOfObject:title];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return [_sortedUserTitles objectAtIndex:section];
}
This is error because of in the _sortedUsers dictionary has a string instead of an array. How may I fix this? And also please suggest a fast, good manner to implement this title index.
If you want to create an List of Firstnames try this perhaps.
At interface:
#property(nonatomic, strong)NSMutableDictionary *dict;
#property(nonatomic, strong)NSMutableArray *alphabet;
_dict = [NSMutableDictionary new];
_alphabet = [NSMutableArray new];
[eventStatusList sortUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) {
OCEventStatus *ev1 = (OCEventStatus*)obj1;
OCEventStatus *ev2 = (OCEventStatus*)obj2;
return [ev1.firstName compare:ev2.firstName];
}];
for(OCEventStatus *state in eventStatusList){
NSString *firstchar = [[state.firstName substringToIndex:1] lowercaseString];
if([dict objectForKey:firstchar]==nil){
NSMutableArray *tmp = [NSMutableArray new];
[tmp addObject:state];
[_dict setObject:tmp forKey:firstchar];
[_alphabet addObject:firstChar];
}else{
[[dict objectForKey:firstchar] addObject:state];
}
}
Now you have an Array of firstnames in a Dictionary which has the first letter as the key for Example: a -> ["Alfred","Albert",...]
In the Datasource methods you have to return it like this...
-(NSInteger)numberOfSectionsInTableView:(UITableView*)tableView{
return dict.count;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection;(NSInteger)section
{
return [dict objectForKey:[alphabet objectAtIndex:section]].count;
}
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
OVEventStatus *state = [[dict objectForKey:[alphabet objectAtIndex:indexPath.section]] objectAtIndex:indexPath.row];
cell.textLabel.text = state.firstName;
return cell;
}
Please try if this fits for you
Update:
If you also want to Sort the Arrays I would recommend to sort the eventListBy firstName first! So you have the correct order when you loop over the eventStatusList.
I'm sorting my array by last name alphabetically. I'd like to separate this into sections with the appropriate header above each section (A, B, C, etc.).
Here's what I've tried below:
// Here is where I refresh the data and sort it based on last name
- (void)refreshData {
[[PCMSSessionManager sharedSession] refreshPCMSDataWithCompletion:^(BOOL success, NSString *errorMessage, id resultObject) {
if (success) {
NSLog(#"yay!");
self.membersArray = [[PCMSSessionManager sharedSession] memberArr];
// Let's sort the array
self.sortedArray = [self.membersArray sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
NSString *first = [(PCMSMember*)a lastName];
NSString *second = [(PCMSMember*)b lastName];
return [first compare:second];
}];
[self.tableView reloadData];
} else {
NSLog(#"boooo!!!!");
}
}];
}
- (NSDictionary *)indexedMembers
{
NSMutableDictionary *indexedContacts = [NSMutableDictionary new];
for (PCMSMember *member in self.sortedArray)
{
NSString *sortString = member.lastName;
NSString *sortLetter = [sortString substringToIndex:1];
/* see if that letter already exists as an index */
BOOL foundKey = NO;
for (NSString *key in [indexedContacts allKeys])
{
if ([key isEqualToString:sortLetter])
{
foundKey = YES;
}
}
NSMutableArray *valueArray;
if (foundKey)
{
valueArray = [((NSArray *)indexedContacts[sortLetter]) mutableCopy];
}
else
{
valueArray = [NSMutableArray new];
}
[valueArray addObject:member];
indexedContacts[sortLetter] = [valueArray copy];
}
return [indexedContacts copy];
}
// Here's my table data
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [[[self indexedMembers] allKeys] count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSDictionary *indexedContacts = [self indexedMembers];
NSArray *myKeys = [indexedContacts allKeys];
NSString *key = myKeys[section];
return [((NSArray *)[self indexedMembers][key]) count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"cellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
// Configure the cell...
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
if (self.isPhysician == YES) {
NSString *key = [[self indexedMembers] allKeys][indexPath.section];
PCMSMember *currentMember = ((NSArray *)[self indexedMembers][key])[indexPath.row];
cell.textLabel.text = [NSString stringWithFormat:#"%# %#", currentMember.firstName, currentMember.lastName];
}
return cell;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return [[self indexedMembers] allKeys][section];
}
UPDATE:
This is getting me closer to what I want.
The data is loading, it's being grouped properly and the headers are showing.
But it's not in alphabetical order.
How can I improve this code to show alphabetically?
It's showing in alphabetical order in my console, just not in the app.
The NSMutableDictionary is unordered by definition. It is not the natural choice if you rely on the order of the stored objects. I suggest you to use NSMutableArray instead. To store the tableview data for each section you can use this mini class
#interface MembersWithSameInitial : NSObject
#property (strong) NSString* initial;
#property (strong) NSMutableArray<PCMSMember*>* members;
#end
#implementation MembersWithSameInitial
#end
After you have sorted the members, all the data for the tableview can be produced with this before tableView reload.
NSMutableArray<MembersWithSameInitial*>* groupedMembers = [[NSMutableArray alloc] init];
for (PCMSMember* member in sortedArray) {
NSString* inicial = [member.lastName substringToIndex:1];
MembersWithSameInitial* last = [groupedMembers lastObject];
if (last && [last.initial isEqualToString:inicial]) {
[last.members addObject:member];
} else {
MembersWithSameInitial* newGroup = [[MembersWithSameInitial alloc] init];
newGroup.initial = inicial;
newGroup.members = [[NSMutableArray alloc] initWithObjects:member, nil];
[groupedMembers addObject:newGroup];
}
}
Since the structure of groupedMembers fits to a grouped tableView, the dataSource methods will have trivial implementations. Assuming, that you have stored groupedMembers in a property.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return self.groupedMembers.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.groupedMembers[section].members.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//...
PCMSMember *currentMember = self.groupedMembers[indexPath.section].members[indexPath.row];
//...
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return groupedMembers[section].initial;
}
Suggestion:
Create two properties
#property NSMutableArray *keys; // for the letters in alphabetical order
#property NSMutableDictionary *indexedContacts; // same as your implementation.
In the method refreshData call the method to create the data source and then reload the table view on the main thread.
Actually you don't need the properties memberArray and sortedArray anymore. The sorted array is passed to the method to create the data source.
- (void)refreshData {
[[PCMSSessionManager sharedSession] refreshPCMSDataWithCompletion:^(BOOL success, NSString *errorMessage, id resultObject) {
if (success) {
NSLog(#"yay!");
self.membersArray = [[PCMSSessionManager sharedSession] memberArr];
// Let's sort the array
NSArray *sortedArray = [self.membersArray sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
NSString *first = [(PCMSMember*)a lastName];
NSString *second = [(PCMSMember*)b lastName];
return [first compare:second];
}];
[self indexMembers:sortedArray];
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
} else {
NSLog(#"boooo!!!!");
}
}];
}
The method indexMembers initializes the properties keys and indexedContacts and creates the data source.
- (void)indexMembers:(NSArray *)sortedMembers
{
self.keys = [[NSMutableArray alloc] init];
self.indexedContacts = [[NSMutableDictionary alloc] init];
for (PCMSMember *member in sortedMembers)
{
NSString *sortString = member.lastName;
NSString *sortLetter = [sortString substringToIndex:1];
/* see if that letter already exists as an index */
NSArray *keyArray = self.indexedContacts[sortLetter];
NSMutableArray *valueArray;
if (keyArray) {
// array for key exists, use it
valueArray = [keyArray mutableCopy];
} else {
// array for key does not exist, create a new one
valueArray = [NSMutableArray new];
// and add the letter to keys
[self.keys addObject:sortLetter];
}
[valueArray addObject:member];
self.indexedContacts[sortLetter] = [valueArray copy];
}
}
numberOfSectionsInTableView returns the number of keys
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return self.keys.count;
}
numberOfRowsInSection gets the appropriate array for the given section and returns the number of items.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSString *letter = self.keys[section];
NSArray *memberArray = self.indexedContacts[letter];
return memberArray.count;
}
In cellForRowAtIndexPath use the method dequeueReusableCellWithIdentifier: forIndexPath: to get always a valid cell. Then like in numberOfRowsInSection get the actual member array and populate the label.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"cellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
// Configure the cell...
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
if (self.isPhysician == YES) {
NSString *letter = self.keys[indexPath.section];
NSArray *memberArray = self.indexedContacts[letter];
PCMSMember *currentMember = memberArray[indexPath.row];
cell.textLabel.text = [NSString stringWithFormat:#"%# %#", currentMember.firstName, currentMember.lastName];
}
return cell;
}
titleForHeaderInSection simply returns the letter for the section
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return self.keys[section];
}
You're calling indexedMembers too much. This is very expensive.
I couldn't test the code, maybe there is a self or something else missing but you get an impression of the workflow.
I have a tableview. I want to create string from selected cell names. For example My Cell names : Row No 1 - Row No 2 - Row No 3 - Row No 4 - Row No 5. When selected Row No 1 - Row No 2 - Row No 5 mystring value = Selected Items Row No 1 , Row No 2 , Row No 5. When i deselect Row No 1 mystring value = Selected items Row No 2 , Row No 5 or Row No 5 , Row No 2. It does not matter.
Is it possible? If possible how can i do? Thanks.
//EDIT
My code is here ;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
tableData = [[NSMutableArray alloc] init];
[tableData retain];
for (int i=1; i<=10; i++)
{
NSString *rowInString= [[NSString alloc ]initWithFormat:#"Row No %d",i];
[tableData addObject:rowInString];
rowInString=nil;
}
_mytable.allowsMultipleSelectionDuringEditing = YES;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSLog(#"self.Data count: %lu", (unsigned long)[tableData count]);
return tableData.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];
}
NSString *cellValue;
cellValue=[tableData objectAtIndex:[indexPath row]];
[_mytable setEditing: YES];
cell.textLabel.text=cellValue;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *selectedText = #"Selected Items";
NSArray *selectedRows = [_mytable indexPathsForSelectedRows];
NSLog(#"%lu" , (unsigned long)selectedRows.count);
}
- (void)dealloc {
[_mytable release];
[super dealloc];
}
#end
First add in your tableview.
self.myTableView.allowsMultipleSelection = YES;
then
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//you need an array in which you can add and remove strings
//adding the selected row string to array.
[stringArray addObject:[tableData objectAtIndex:[indexPath row]];
NSString *string;
for(NSString *str in stringArray)
{
string = [NSString stringWithFormat:"%#%#",string,str];
}
NSLog(#"Selected Row %#"string);
}
- (void)tableView:(UITableView *)tableView didDeSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//removing the selected string from array
for(NSString *stringInArray in stringArray)
{
if([stringInArray isEqualToString:[tableData objectAtIndex:[indexPath row]])
{
[stringArray removeObject:stringInArray];
}
}
NSString *string;
for(NSString *str in stringArray)
{
string = [NSString stringWithFormat:"%#%#",string,str];
}
NSLog(#"Selected Row %#"string);
}
Here is how you can do it:
Create a NSString *selectedText=#"Selected Items";
Now when you press a item in tableview, didselectitematibdexpath will be called.
Using the indexpath get the cell's name. Now compare if that text exist in the selectedText string. If it exist remove it from string
NSRange check = [selectedText rangeOfString:#" one"];
if (check.location != NSNotFound) {
selectedText = [selectedText stringByReplacingCharactersInRange:check withString:#""];
}
else add it to string using
selectedText=[selectedText stringWithFormat:#" %#",cellName];
Here is your code(i have changed as per your requirement):
NSString *selectedText = #"Selected Items";
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
tableData = [[NSMutableArray alloc] init];
[tableData retain];
for (int i=1; i<=10; i++)
{
NSString *rowInString= [[NSString alloc ]initWithFormat:#"Row No %d",i];
[tableData addObject:rowInString];
rowInString=nil;
}
_mytable.allowsMultipleSelectionDuringEditing = YES;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSLog(#"self.Data count: %lu", (unsigned long)[tableData count]);
return tableData.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];
}
NSString *cellValue;
cellValue=[tableData objectAtIndex:[indexPath row]];
[_mytable setEditing: YES];
cell.textLabel.text=cellValue;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSRange check = [selectedText rangeOfString:[tableData objectAtIndex:[indexPath row]]];
if (check.location != NSNotFound) {
selectedText = [selectedText stringByReplacingCharactersInRange:check withString:#""];
} else {
selectedText = [NSString stringwithFormat:#"%# %#",selectedText, [tableData objectAtIndex:[indexPath row]]];
}
NSArray *selectedRows = [_mytable indexPathsForSelectedRows];
NSLog(#"%lu" , (unsigned long)selectedRows.count);
}
- (void)dealloc {
[_mytable release];
[super dealloc];
}
#end
dictionaryOfWebsites = [[NSMutableDictionary alloc] init];
[dictionaryOfWebsites setObject:#"http://www.site1.com" forKey:#"Site1"];
[dictionaryOfWebsites setObject:#"http://www.site2.com" forKey:#"Site2"];
[dictionaryOfWebsites setObject:#"http://www.site3.com" forKey:#"Site3"];
[dictionaryOfWebsites setObject:#"http://www.site4.com" forKey:#"Site4"];
Above is my dictionary. I want to have a tableview where the text in the UITableViewCell will say "Site1" and the subtext will have the URL.
I know this will get me all the keys
NSArray *keys = [dictionaryOfWebsites allKeys];
// values in foreach loop
for (NSString *key in keys) {
NSLog(#"%# is %#",key, [dict objectForKey:key]);
}
you're help would be greatly appreciated
If my approach is not the best one, please let me know so I can learn from your recommendations.
Try
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [[dictionaryOfWebsites allKeys] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//Initialize cell of style subtitle
NSArray *keys = [[dictionaryOfWebsites allKeys]sortedArrayUsingSelector:#selector(compare:)];
NSString *key = keys[indexPath.row];
cell.textLabel.text = key;
cell.detailTextLabel.text = dictionaryOfWebsites[key];
return cell;
}
Edit : It is better to have an array of dictionaries for these kind of representation.
Each dictionary with two key value pairs Title and Subtitle.
self.dataArray = [NSMutableArray array];
NSDictionary *dict = #{#"Title":#"Site1",#"Subtitle":#"http://www.site1.com"};
[dataArray addObject:dict];
//Add rest of the dictionaries to the dataArray
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [self.dataArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//Initialize cell of style subtitle
NSDictionary *dict = self.dataArray[indexPath.row];
cell.textLabel.text = dict[#"Title"];
cell.detailTextLabel.text = dict[#"Subtitle"];
return cell;
}
You could try:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//cell initialization code
NSString *title = [keys objectAtIndex:indexPath.row];
cell.textLabel.text = title;
cell.detailTextLabel.text = [dictionaryOfWebsites objectForKey:title];
return cell;
}
in that case declare keys array as a property.
I load data from plist to uitableview like this:
- (void)viewDidLoad {
[super viewDidLoad];
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *path = [[documentPaths lastObject] stringByAppendingPathComponent:#"data.plist"];
NSMutableDictionary *resultDic = [[NSMutableDictionary alloc] init];
NSMutableArray *resultArray = [[NSMutableArray alloc] init];
NSDictionary *myDict = [NSDictionary dictionaryWithContentsOfFile:path];
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"purpleKey"])
{
NSArray *purple = [myDict objectForKey:#"Purple"];
[resultArray addObject:#"Purple"];
[resultDic setValue:purple forKey:#"Purple"];
}
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"orangeKey"])
{
NSArray *orange = [myDict objectForKey:#"Orange"];
[resultArray addObject:#"Orange"];
[resultDic setValue:orange forKey:#"Orange"];
}
self.tableData = resultDic;
self.sectionsTitle = resultArray;
}
titleForHeaderInSection
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return [sectionsTitle objectAtIndex:section];
}
my plist structure
My question is:
How can I manually set title for Purple header and Orange header without to changing names in plist file?
like this: Purple = Category 1, Orange = Category 2
EDIT
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return sectionsTitle.count;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return [sectionsTitle objectAtIndex:section];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
int num = [[tableData objectForKey:[sectionsTitle objectAtIndex:section]] count];
if (num > 3) {
num = 3;
}
return num;
}
// Customize the appearance of table view cells.
- (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];
}
NSDictionary *dict = [[tableData objectForKey:[sectionsTitle objectAtIndex:indexPath.section]] objectAtIndex:indexPath.row];
cell.textLabel.numberOfLines = 1;
cell.textLabel.font = [UIFont systemFontOfSize:11];
cell.textLabel.text = [NSString stringWithFormat:#"%# - %#", [dict objectForKey:#"Name"], [dict objectForKey:#"Address"]];
if ([dict objectForKey:#"Address"] == (NULL)) {
//do nothing
}
return cell;
}
From the look of your code, the section headers are coming from resultsArray, which you are populating with the constant strings Orange and Purple.
You can just put different constant strings into that array, unless I'm missing something.
So, instead of
[resultArray addObject:#"Orange"];
Use
[resultArray addObject:#"Category 1"];