I made indexed list according to this apple tutorial, but I have problem with deleting items. When I delete last item in section at the bottom, the section header remain there. This happens only with last section.
Here is my code for deleting item:
- (void)tableView:(UITableView *)tableView commitEditingStyle: (UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
[[self.littleWords objectAtIndex:indexPath.section]removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
littleWords is array of sections same as states in apple tutorial.
code for making cells:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:#"MyBasicCell"];
Word * myWord = [[self.littleWords objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
cell.textLabel.text = myWord.name;
cell.detailTextLabel.text = myWord.translation;
return cell;
}
rest of tableView functions:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [self.littleWords count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [[self.littleWords objectAtIndex:section] count];
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
return [[UILocalizedIndexedCollation currentCollation] sectionIndexTitles];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if ([[self.littleWords objectAtIndex:section] count] > 0) {
NSString *str = [[[UILocalizedIndexedCollation currentCollation] sectionTitles] objectAtIndex:section];
NSLog(#"returning section header: %#", str);
return str;
}
return nil;
}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index
{
return [[UILocalizedIndexedCollation currentCollation] sectionForSectionIndexTitleAtIndex:index];
}
The problem is in the method numberOfSectionsInTableView:. The number should change when you delete all of the items in a given section. Here is an example of what you can do:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
NSInteger sections = 0;
for (NSArray *sectionArray in littleWords) {
if (sectionArray.count > 0) {
sections++;
}
}
return sections;
}
Edit: After deleting the row, you may need to call [tableView reloadData] or a similar methid to update the sections.
Related
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 one UITableView consisting of some custom UITableViewCells and one UISearchDisplayController connected to it. How can I show another custom Table View Cell if there are no results when you search for something?
Here's how the search and table view functions look like:
- (void)searchTableList:(UISearchBar*)searchBar {
NSString *searchString = searchBar.text;
for (NSArray *section in _celebs)
for (NSDictionary *row in section) {
if ([[row[#"name"] lowercaseString] rangeOfString:[searchString lowercaseString]].location!=NSNotFound)
[filteredContentList addObject:row];
}
}
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
isSearching = YES;
}
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
[filteredContentList removeAllObjects];
if (searchText.length) {
isSearching = YES;
[self searchTableList:searchBar];
} else isSearching = NO;
}
- (void)searchDisplayControllerDidEndSearch:(UISearchDisplayController *)controller{
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
isSearching = NO;
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
[self searchTableList:searchBar];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [tableView isEqual:self.searchDisplayController.searchResultsTableView]?1:_objects.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [tableView isEqual:self.searchDisplayController.searchResultsTableView]?filteredContentList.count:[_objects[section] count];
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return [tableView isEqual:self.searchDisplayController.searchResultsTableView]?0:25;
}
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForHeaderInSection:(NSInteger)section {
return [self tableView:tableView heightForHeaderInSection:section];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 55;
}
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
return [self tableView:tableView heightForRowAtIndexPath:indexPath];
}
- (NSDictionary *)getObjectFromIndexPath:(NSIndexPath*)indexPath tableView:(UITableView*)tableView {
BOOL search = [tableView isEqual:self.searchDisplayController.searchResultsTableView];
if (search)
return indexPath.row<filteredContentList.count?filteredContentList[indexPath.row]:nil;
else return indexPath.section<_objects.count?
(indexPath.row<[_objects[indexPath.section] count]?_objects[indexPath.section][indexPath.row]:nil)
:nil;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
BOOL search = [tableView isEqual:self.searchDisplayController.searchResultsTableView];
FirstTableViewCell *cell;
NoResultsTableViewCell *cell1;
if (tableView == self.searchDisplayController.searchResultsTableView) {
cell = (FirstTableViewCell*)[self.tableView dequeueReusableCellWithIdentifier:#"FirstTableViewCell"];
} else {
cell = (FirstTableViewCell*)[self.tableView dequeueReusableCellWithIdentifier:#"FirstTableViewCell" forIndexPath:indexPath];
}
NSDictionary *object = [self getObjectFromIndexPath:indexPath tableView:tableView];
if (!object) return cell;
cell.object = celeb;
cell.objectName.text = [object objectForKey:#"name"];
}
}
return cell;
}
Make some changes like below:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if ([tableView isEqual:self.searchDisplayController.searchResultsTableView]){
if (filteredContentList.count > 0){
return filteredContentList.count;
}else{
return 1; // the number of custom cells when there're no results
}
}else{
return [_objects[section] count];
}
}
- (NSDictionary *)getObjectFromIndexPath:(NSIndexPath*)indexPath tableView:(UITableView*)tableView {
BOOL search = [tableView isEqual:self.searchDisplayController.searchResultsTableView];
if (search)
return indexPath.row < filteredContentList.count? filteredContentList[indexPath.row]: theCustomCellDict; // use theCustomCellDict instead of nil
else return indexPath.section < _objects.count?
(indexPath.row < [_objects[indexPath.section] count]? _objects[indexPath.section][indexPath.row]: nil)
:nil;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
BOOL isSearch = [tableView isEqual:self.searchDisplayController.searchResultsTableView];
FirstTableViewCell *cell;
NoResultsTableViewCell *noReultsCell;
if ((isSearch && filteredContentList.count > 0) || !isSearch){
cell = (FirstTableViewCell *)[self.tableView dequeueReusableCellWithIdentifier:#"FirstTableViewCell" forIndexPath:indexPath];
NSDictionary *object = [self getObjectFromIndexPath:indexPath tableView:tableView];
if (!object) return cell;
cell.object = celeb;
cell.objectName.text = [object objectForKey:#"name"];
return cell;
}else{
noResultsCell = (NoResultsTableViewCell *)[self.tableView dequeueReusableCellWithIdentifier:#"NoResultsTableViewCell" forIndexPath:indexPath];
NSDictionary *object = [self getObjectFromIndexPath:indexPath tableView:tableView];
if (!object) return noResultsCell;
noResultsCell.object = celeb;
noResultsCell.objectName.text = [object objectForKey:#"name"];
return noResultsCell
}
}
If you want to just show information (for example there is no result found 'something' ) You don't need to use UITableViewCells. I will reccomend you to look DZNEmptyDataSet library.
GitHub link https://github.com/dzenbot/DZNEmptyDataSet
I would like to create a tableview where I can move people from different departments into other departments, and I have some code posted below.
I have an issue with this, I can never seem to get it to get the usual ui gadget to move rows. I don't want the user to edit/delete the rows; simply move them about however the "move" buttons never seem to appear.
Is there something I am doing wrong?
Also I am not sure if I am doing the move code right.
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = #"Departments";
self.tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
self.tableView.allowsSelectionDuringEditing = YES;
_objects = [NSMutableArray array];
NSDictionary *sales = #{ #"name" : #"sales",
#"employees" : #[ #"Mike", #"Tom", #"Alex"] };
NSDictionary *marketing = #{ #"name" : #"marketing",
#"employees" : #[ #"Heather", #"Richard", #"Simon"] };
[_objects addObject:sales];
[_objects addObject:marketing];
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
[super setEditing:editing animated:animated];
}
#pragma mark - IBActions
-(IBAction) editButton:(id)sender
{
[self setEditing:!self.editing animated:YES];
}
#pragma mark - UITableView delegate
-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{
return [_objects count];
}
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSDictionary *department = [_objects objectAtIndex:section];
NSArray *employees = department[#"employees"];
return [employees count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cellId" forIndexPath:indexPath];
// Configure the cell...
NSDictionary *department = [_objects objectAtIndex:indexPath.section];
NSArray *employees = department[#"employees"];
NSString *employeeName = [employees objectAtIndex:indexPath.row];
cell.textLabel.text = employeeName;
return cell;
}
-(NSString *) tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
NSDictionary *department = [_objects objectAtIndex:section];
return department[#"name"];
}
- (BOOL) tableView: (UITableView *) tableView canEditRowAtIndexPath: (NSIndexPath *) indexPath
{
return YES;
}
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
if( fromIndexPath == toIndexPath ) return;
NSDictionary *department = [_objects objectAtIndex:fromIndexPath.section];
NSArray *employees = department[#"employees"];
NSString *employeeName = [employees objectAtIndex:fromIndexPath.row];
[self.tableView beginUpdates];
[_objects removeObjectAtIndex:fromIndexPath.row];
[_objects insertObject:employeeName atIndex:toIndexPath.row];
[self.tableView endUpdates];
[tableView reloadData];
}
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the item to be re-orderable.
if (indexPath.section == 1 && [_objects count] > 1)
{
return YES;
}
return NO;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
if(editingStyle == UITableViewCellEditingStyleDelete){
[_objects removeObjectAtIndex:indexPath.row];
NSArray *rows = [NSArray arrayWithObject:indexPath];
[self.tableView beginUpdates];
[self.tableView deleteRowsAtIndexPaths:rows withRowAnimation:UITableViewRowAnimationAutomatic];
[self.tableView endUpdates];
}
}
call this method after your array initialised. [self.tableView reloadData]
This will load the table data once again.
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;
}