I am having an issue with the header and the cellForRow in Arabic codes below.
The codes work in English.
Can anyone see what I am doing wrong and resolve the problem?
Thanks.
Unfortunately I am unable to post the image due to the 10 reputation things..
e.g from the UITableView
A
B
Abha
Abu Dhabi
C
Bahrain
Beirut
D
- (void)setupIndexData:objects {
self.collation = [UILocalizedIndexedCollation currentCollation];
NSInteger index, sectionTitleCount = [[self.collation sectionTitles] count];
NSMutableArray *newSectionArray = [[NSMutableArray alloc] initWithCapacity:sectionTitleCount];
for (index = 0; index < sectionTitleCount; index++) {
[newSectionArray addObject:[NSMutableArray array]];
}
for (NSString *airportList in objects) {
NSInteger sectionNumber = [self.collation sectionForObject:airportList collationStringSelector:#selector(city)];
[[newSectionArray objectAtIndex:sectionNumber] addObject:airportList];
}
for (index = 0; index < sectionTitleCount; index++) {
NSMutableArray *airportListArrayForSection = [newSectionArray objectAtIndex:index];
[newSectionArray replaceObjectAtIndex:index withObject:[self.collation sortedArrayFromArray:airportListArrayForSection collationStringSelector:#selector(city)]];
}
self.sectionArray = newSectionArray;
[self.table reloadData];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [[[self.collation sectionTitles] sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)] count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSMutableArray *airportListsInSection = (self.sectionArray)[section];
return [airportListsInSection count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return [[[self.collation sectionTitles] sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)] objectAtIndex:section];
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
return [[self.collation sectionIndexTitles] sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
return [self.collation sectionForSectionIndexTitleAtIndex:index];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
....
Aiports *airportLists = (self.sectionArray)[indexPath.section][indexPath.row];
cell.textLabel.text = airportLists.city;
}
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 am getting the array from JSON. I have implemented section index in UITableView and when I tap the section it throws me an error.
Note: Passing array is from JSON and alphabet array is abcd like that. The error I am getting is [__NSDictionaryM substringToIndex:]: unrecognized selector sent to instance.
Please help me out. I am retrieving this from contacts and passing those contact in my JSON:
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return alphabetsArray.count;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 30;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if ([passingArray count] > 0) {
return [passingArray count];
}
else
return 1;
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
return alphabetsArray;
}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
for (int i = 0; i < [passingArray count]; i++) {
NSString *letterString = [[passingArray objectAtIndex:i] substringToIndex:1];
if ([letterString isEqualToString:title]) {
[tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:YES];
break;
}
}
return -1;
}
- (void)CreateIndexArray {
NSMutableArray *tempFirstLetterArray = [[NSMutableArray alloc] init];
for (int i = 0; i < [passingArray count]; i++) {
NSString *letterString = [[passingArray objectAtIndex:i] substringToIndex:1];
if (![tempFirstLetterArray containsObject:letterString]) {
[tempFirstLetterArray addObject:letterString];
}
}
passingArray = tempFirstLetterArray;
}
Your logic for sectionForSectionIndexTitle: is flawed. That method expects an integer return value - the index to which the tableview should scroll down to.
Also is passingArray an array of dictionaries? That is what the error suggests
[passingArray objectAtIndex:i] should return a string if you wish to use it with substringToIndex:, not a dictionary. If the object is a dictionary, get the correct value from in there using whatever key you have and then run string operations on that value.
The following code will hang.
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (_empty) {
return 0;
} else {
return 25000;
}
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
return [tableView dequeueReusableCellWithIdentifier:#"Cell"];
}
- (IBAction)buttonPressed:(id)sender {
NSMutableArray *collector = [#[] mutableCopy];
for (NSInteger i = 0; i < 25000; i++) {
[collector addObject:[NSIndexPath indexPathForRow:i inSection:0]];
}
_empty = YES;
[self.tableView deleteRowsAtIndexPaths:[collector copy]
withRowAnimation:UITableViewRowAnimationNone];
}
I have filed a radar with apple for this (22865658).
Example project can be found here https://www.dropbox.com/s/upn9ee5svp11a1t/asdf.zip?dl=0
I have Implemented multi select row but what i have to do is when we click on row it will move on another section , Here's my code what i have tried is ?
can anyone help me out from this ? Thanks in advance ...
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 2; //assuming you have only two sections
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (section == 0)
return self.firstSectionDataSource.count;
else if (section == 1)
return self.dataArray.count;
else
return 0;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Here, Have to move row to another section while clcking ..
// other multiselect code
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Configure a cell to show the corresponding string from the array.
static NSString *kCellID = #"cellID";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellID];
cell.textLabel.text = [self.dataArray objectAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{
#try {
NSMutableArray *sourceArray = nil;
if (sourceIndexPath.section == 0) {
sourceArray = self.firstSectionDataSource;
}
else if (sourceIndexPath.section == 1)
{
sourceArray = self.dataArray;
}
NSMutableArray *destinationArray = nil;
if (destinationIndexPath.section == 0) {
destinationArray = self.firstSectionDataSource;
}
else if (destinationIndexPath.section == 1)
{
destinationArray = self.dataArray;
}
NSString *stringToMov = [sourceArray objectAtIndex:sourceIndexPath.row];
[sourceArray removeObject:stringToMov];
[destinationArray insertObject:stringToMov atIndex:destinationIndexPath.row];
}
#catch (NSException *exception) {
NSLog(#"exception = %# \n reason = %#",exception,exception.reason);
}
}
In cellForRowAtIndexPath
[cell setShowsReorderControl:YES];
And you need to implement the following UITableView delegate and data source methods properly
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 2; //assuming you have only two sections
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (section == 0)
return firstSectionDataSource.count;
else if (section == 1)
return secondSectionDataSource.count;
else
return 0;
}
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{
#try {
NSMutableArray *sourceArray = nil;
if (sourceIndexPath.section == 0) {
sourceArray = firstSectionDataSource;
}
else if (sourceIndexPath.section == 1)
{
sourceArray = secondSectionDataSource;
}
NSMutableArray *destinationArray = nil;
if (destinationIndexPath.section == 0) {
destinationArray = firstSectionDataSource;
}
else if (destinationIndexPath.section == 1)
{
destinationArray = secondSectionDataSource;
}
NSString *stringToMov = [[sourceArray objectAtIndex:sourceIndexPath.row] retain];
[sourceArray removeObject:stringToMov];
[destinationArray insertObject:stringToMov atIndex:destinationIndexPath.row];
[stringToMov release];
}
#catch (NSException *exception) {
NSLog(#"exception = %# \n reason = %#",exception,exception.reason);
}
}
You can do the next:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView moveRowAtIndexPath:indexPath toIndexPath:[NSIndexPath indexPathForRow:row inSection:section]];
// other multiselect code
}
Try this -
NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithObjects:[NSArray arrayWithObjects:[NSArray arrayWithObjects:#"a",#"b",#"c", nil],[NSArray arrayWithObjects:#"d",#"e",#"f", nil], nil] forKeys:[NSArray arrayWithObjects:#"firstSection",#"secondsection", nil]];
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [[dict allKeys] count]; //assuming you have only two sections
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [[dict objectForKey:[dict allKeys][section]] count];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSMutableArray *arr = [dict objectForKey:[dict allKeys][indexPath.section]];
NSString *str = arr[indexPath.row];
if (indexPath.row!=0) {
[arr removeObject:str];
}
NSMutableArray *arr1 = [dict objectForKey:[dict allKeys][0]];
[arr1 addObject:str];
[tableView reloadData];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSArray *arr = [dict objectForKey:[dict allKeys][indexPath.section]];
NSString *str = arr[indexPath.row];
static NSString *kCellID = #"cellID";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellID];
cell.textLabel.text = str;
return cell;
}
I have tableView, which I am getting data from array and also the number of section and section title also from array, but when I give section title from array it breaks the App.
Getting values in array:
NSArray *tempArray =[[DataController staticVersion] startParsing:#"http://www.celeritas-solutions.com/pah_brd_v1/productivo/getCategory.php"];
for (int i = 0; i<[tempArray count]; i++) {
id *item = [tempArray objectAtIndex:i];
NSDictionary *dict = (NSDictionary *) item;
ObjectData *theObject =[[ObjectData alloc] init];
[theObject setCategoryID:[dict objectForKey:#"CategoryID"]];
[theObject setCategoryTitle:[dict objectForKey:#"CategoryTitle"]];
[theObject setCategoryDescription:[dict objectForKey:#"CategoryDescription"]];
[theObject setCategoryAddedByUserID:[dict objectForKey:#"CategoryAddedByUserID"]];
[theObject setCategoryAddedDateTime:[dict objectForKey:#"CategoryAddedDateTime"]];
[categoryArray addObject:theObject];
[theObject release];
theObject=nil;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [categoryArray count] ;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
[categoryArray objectAtIndex:section];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
expect a string in return.
Try
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
ObjectData *theObject =[categoryArray objectAtIndex:section];
return theObject.categoryTitle;
}
try like this ,
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection(NSInteger)section
{
return [[categoryArray objectAtIndex:section] valueForKey:#"title"];//replace title with your key value
}
You are adding an instance of ObjectData class into the categoryArray. The tableView:titleForHeaderInSection:method asks for an NSString object to set it as the header of the section. Check what you are returning in the titleForHeaderInSection: method. It has to be an NSString object.If you want to set the category title as your section header title, return the categoryTitle as
return [(ObjectData*)[categoryArray objectAtIndex:section] categoryTitle];