Displaying Elements in UITableView like iPhone contacts, separated into alphabetical sections? - iphone

I've been looking around on-line for a solution to this, but I can't seem to find anything, and I'm stuck.
I have a NSMutableArray:
productsToDisplay
Which consists of a heap of Product objects that each have a 'name' attribute e.g.
Product *product = ....
NSLog(#"%#", product.name);
Each cell displays a products name and when clicked, displays more information about the product.
However I have a lot of products and would like to split them up into alphabetical sections in the UITableView (like the Contacts on your iPhone are).
Can someone point me in the right direction?
Thanks a lot,
Jack
[EDIT]
I realise I could just sort the array on the name attribute, but I would also like the quick search bar that runs down the right hand side of the UITableView so a user can easily find the section they are looking for.

use this delegate to display the right hand sections list:-
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
return searchArray;
}
use this delegate to associate table content (section) according to right hand list:-
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
if (index == 0) {
[tableView scrollRectToVisible:[[tableView tableHeaderView] bounds] animated:NO];
return -1;
}
return index;
}

Add alphabetic sections to ur tableview, then You have to create array of alphabets corresponding to the section in tableview. Like section[0] - 'A', section[1] - 'B', etc.
Add
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
return keys;
}
//the delegate is asking for an array of the values to display in the index.
So the first item in this array will take the user to the first section, which is section 0.

Related

How to move labels in ios

Here i need to hide the phone number, email , birthDate, anniversary date and other labels in case there is no values for those fields. How can i do this?
Many ways, starting with the simplest:
self.emailLabel.hidden = YES;
But you probably want to reformat the other parts of the view to fit the empty space. Keeping it simple, you would then do something like this:
self.phoneLabel.frame = CGRectOffset(self.phoneLabel.frame, 0, -self.emailLabel.bounds.size.height);
... and so on for anything below. But you can see how this would become tedious. The next and probably best alternative is a UITableView that adjusts it's section count based on whether some of that data is present. That would go like this. Prepare a mutable array of arrays with the parts of your model and their values.
- (void)prepareModel {
self.model = [NSMutableArray array];
[self.model addObject:#[#"Name", #"Judy"]; // get "Judy" from your data
if (/* model has email */) {
[self.model addObject:#[#"Email", #"judy#gmail.com"]; // get email from your model
}
// and so on for conditional parts of your model
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return self.model.count;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
return self.model[section][0];
}
And the cellForRow would init the cell using self.model[section][1].
What you can do is simply hide the UILabel's if the value for the NSStrings that you are putting them in is NULL/nil .
NSString *labelString;
if([labelString length]>0)
{
}
else
Label.hidden = YES;
It is probably a better idea to use a UITableView to do this, by putting the labels in rows of the tables. If the labels are empty, you can delete the table rows and iOS will dynamically resize the table height for you.

indexPath Adjustment iPhone

I have a UITableView that, under certain conditions, needs to have something added to the top of it. All data (except for what is inserted at the top of the UITableView under certain conditions) is brought in from an array.
Because everything is brought in from an array, I need to modify the indexPath that fetches those array objects each and every time the method - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath is called. If I try to create a local variable and update the local version of indexPath.row, it tells me it is read only.
What would be the best way to implement this?
Drawing below (this is not intended to be code, but a drawing of the table view):
(REGULAR SITUATION) (3 lines)
array objectAtIndex:0;
-----
array objectAtIndex:1;
-----
array objectAtIndex:2;
etc. etc
(MODIFIED SITUATION) (4 lines)
blah blah modified insertion text here
-----
array objectAtIndex:0;
-----
array objectAtIndex:1;
-----
array objectAtIndex:2;
etc etc
Thanks in advance.
Why not just add your new item at the start of your array?
// Create a mutable copy and add the item at index 0
NSMutableArray *mutable = [myData mutableCopy];
[mutable insertObject:newItem atIndex:0];
// Then store the new array and reload the table
[myData autorelease];
myData = mutable;
[self.tableView reloadData];
Then you don't have to do anything funny at all with index paths :)
THIS is a great tutorial that addresses your issue.
Use
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
OR
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
Return the String/View as something or empty depending on the condition that you use while deciding when to show it or not.
Don't go down that path. Just use the tableHeaderView property of UITableView to add something on top of the table. It will scroll just like a UITableViewCell.
self.tableView.tableHeaderView = aView;
To remove it, just set it to nil.
If you insist in this method, just keep a BOOL around to tell you in which state you are and if you need the extra line just subtract 1 from indexPath.row, like
[myArray objectAtIndex:indexPath.row-1];

The # symbol in UITableView index

I have searched high and low for the answer to this. In the iPhone Phone app on the Contacts tab there is a little magnifying glass symbol for search and a # symbol for the number of rows in the contacts table view.
I have implemented the search symbol ok but my # gets sorted to the top of the index. Does anyone know a way to get it to get sorted to the bottom of the index.
Ive been trying for hours and no luck so far. Any help/suggestions really appreciated. Thanks for your time.
Implement this into your codes:
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView{
return [[NSArray arrayWithObject:UITableViewIndexSearch] arrayByAddingObjectsFromArray:
[[UILocalizedIndexedCollation currentCollation] sectionIndexTitles]];
}
implement this in your TableViewDataSource
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView{
return [NSArray arrayWithObjects:#"A",#"B",#"C",#"D",#"E",#"F",#"G",#"H",#"I",#"J",#"K",#"L",#"M",#"N",#"O",#"P",#"Q",#"R",#"S",#"T",#"U",#"V",#"W",#"X",#"Y",#"Z",#"#",nil];
}
likewise use this for your headings:
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
switch(section){
case 0:
return #"A";
case 1:
return #"B";
... (all the way through the alphabet)
case 26:
return #"#";
default:
return #"";
}
}
Then just arrange your data accordingly. I would use a 2-dimensional array with the outer being the section and the inner being the row in that section. Then you can sort the inner arrays and manage the outer arrays yourself.
Hope this helps!

I want alphabet strip (like in addressBook) on UITableViewControler

I want an alphabet strip (like in addressBook) on UITableViewController. Please help.
You need to implement the TableView delegate method
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
}
Cheers
I think the correct answer is
- (NSArray *) sectionIndexTitlesForTableView:(UITableView *)tableView {
}
just for the record!
Apple documentation:
Return Value
An array of strings that serve as the title of sections in the table view and appear in the index list on the right side of the table view. The table view must be in the plain style (UITableViewStylePlain). For example, for an alphabetized list, you could return an array containing strings ā€œAā€ through ā€œZā€.

sectionIndexTitlesForTableView line up correctly with sections

I've got a table view with many sections, the title for these sections is just A-Z and # just like in the iPhone address book App. I have implemented sectionIndexTitlesForTableView to have the quick move to particular letter and basically just return an array of Letters A - Z and #.
This would work if my list always contains an item for every letter of the alphabet but it won't and this screws up the section index titles because hitting C in the list might go to D if the 3th section is D (ie if there is nothing in section C).
I know I could return the array in sectionIndexTitlesForTableView with only the letters that are sections but this would look a bit odd and not the same functionality as the iPhone Address book app.
How can I rectify this?
I don't see how #Rudiger's method would work if you have only have sections A, C, F, S, T and section index titles for A-Z. Such a situation might arise when using MPMediaQuery.
To get around this I've implemented this method as follows, the tableview will scroll to the correct section or the next if the one you are looking for doesn't exist.
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index
{
NSString *sectionTitle = nil;
NSComparisonResult result;
int i;
for(i = 0; i < tableView.numberOfSections; i++)
{
sectionTitle = [self tableView:tableView titleForHeaderInSection:i];
result = [title compare:sectionTitle];
if(result != NSOrderedDescending)
break;
}
return (MIN (i, (tableView.numberOfSections - 1)));
}
UPDATE
Changed the return value to fix the situation described by Eric D'Souza.
Basically you have to implement:
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
return [sections indexOfObject:title];
}
and return based on the index and title what section it should be on. Where sections is the array storing the list of sections