I've tried with following code. It works fine. But I can not figured out how to achieve few things.
How to add insertion control when I clicked "Delete" button instead of deletion control on the same row?
If I moved "section 3" in between "Section 1" and "Section 2", how to update all the three sections with deletion control in them?
So far I've got following output using below code.
-(void)tableView:(UITableView *)aTableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
//Handle things when deletion control clicked!
//[sectionArray removeObjectAtIndex:indexPath.row];
//[self.tableView reloadData];
} else if (editingStyle == UITableViewCellEditingStyleInsert) {
//Handle things when insertion control clicked!
}
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)aTableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
// No editing style if not editing or the index path is nil.
if (isEditMode == NO || !indexPath) return UITableViewCellEditingStyleNone;
if (indexPath.row == 1){
return UITableViewCellEditingStyleDelete;
}else if (indexPath.row == 2){
return UITableViewCellEditingStyleInsert;
}else if (indexPath.row == 3){
return UITableViewCellEditingStyleInsert;
}else {
return UITableViewCellEditingStyleDelete;
}
return UITableViewCellEditingStyleNone;
}
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath
toIndexPath:(NSIndexPath *)toIndexPath {
NSString *item = [sectionArray objectAtIndex:fromIndexPath.row];
[sectionArray removeObject:item];
[sectionArray insertObject:item atIndex:toIndexPath.row];
NSLog(#"%#", sectionArray);
}
Solution for your second question is that you need to refresh your table view once you performed your action such as deletion and insertion
I hope this links also helpful for you.
http://code4app.net/ios/UITableView-actions/50bf05986803fa8e5c000001
http://www.appcoda.com/model-view-controller-delete-table-row-from-uitableview/
For any time of UI problem you also got demo applications from this side.
http://code4app.net
I followed Simon Lee's tutorial on animating uitableview height change, and it's working amazing! The only problem I seem to be facing is that I can tap several cells, and they all will remain expanded regardless if another is already expanded. I only want one expanded at any given time, and if another is already expanded, for it to be closed before a new one expands.
Simon mentioned that we should "store a single NSIndexPath as the current selected item instead on an array of indexes." I'm not exactly sure how to do this. If anyone could help out that would be awesome!
what you have to do is just add the code below in the tableView delegate method tableView:didSelectRowAtIndexPath: below the line
[selectedIndexes setObject:selectedIndex forKey:indexPath];
code to add
NSArray *key = selectedIndexes.allKeys;
for (int i = 0; i < [key count]; i++) {
if (![[key objectAtIndex:i] isEqual:indexPath]) {
[selectedIndexes setObject:[NSNumber numberWithBool:NO] forKey:[key objectAtIndex:i]];
}
}
Happy Coding :)
Enjoy the Day!!
Yes you can colapse the cells using the delegate methods of UITableView -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath and - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath :-
First declare the variable to get theindexPath
NSIndexPath *selectedCellIndexPath;
then get the cell's indexPath in didSelectRowAtIndexPath :-
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
selectedCellIndexPath=indexPath;
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationBottom];
}
Then do the collapsing and extending and set the lower and upper height:-
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(selectedCellIndexPath != nil
&& [selectedCellIndexPath compare:indexPath] == NSOrderedSame)
return yourCellsExtendedHeightInInteger;
return yourCellsCollapsedHeightInInteger;
}
or use
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(selectedCellIndexPath && indexPath.row == selectedCellIndexPath .row)
{
return 100;
}
return 44;
}
You can see this tutorial also:-
I have a UITableView put in edited mode.
self.tableView.editing = YES;
In this table view, I have some lines displayed in a custom cell, and I'd like to add one at the end that would allow the user to add an item (using another view).
So I wrote some lines :
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return "number of lines" + 1;
}
- (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
if(indexPath.row+1 != [tableView numberOfRowsInSection:0]) {
return UITableViewCellEditingStyleDelete;
}
else {
return UITableViewCellEditingStyleInsert;
}
}
- (void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row + 1 == [tableView numberOfRowsInSection:0]) {
cell.textLabel.text = #"Add a line...";
}
else {
do the stuff in the custom cell
}
}
Doing this way, the UITableView allows to rearrange any line. I can move the first line after the "add line", and move the "add line" in first position.
How may I remove the arrange button on the "add line" cell and prevent other lines to go under this one ?
Or is there a better way to code this ?
Implement
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
return ([indexPath row] != INDEX_OF_SPECIAL_ROW)
}
and
- (NSIndexPath *)tableView:(UITableView *)tableView
targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath
toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
if ([proposedDestinationIndexPath row] < NUMBER_OF_ROWS)
{
return proposedDestinationIndexPath;
}
NSIndexPath *otherPath = [NSIndexPath indexPathForRow:NUMBER_OF_ROWS-1 inSection:0];
return otherPath;
}
The much easier way would be to set a tableFooterView. You can place any UIView in there, so not only are you allowed to add a UITableViewCell but also a completely custom subclass. Doing it this way you will avoid all the unnecessary checks.
return UITableViewCellEditingStyleNone
For that row in - (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
And check out – tableView:moveRowAtIndexPath:toIndexPath:
-(BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
NSUInteger row = [indexPath row];
if(row == 0)
return NO;
return YES;
}
My problem is: although i specified NO for row 0. If I attempt to drag row 1 to replace row 0, the animation lets this happen anyways. The problem is that the above method only decides whether or not there is a move icon on the right of the row. Any ideas on how to stop row 0 from ever getting replaced?
Use
- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
from the UITableViewDelegate.
You can do something like this:
if ([proposedDestinationIndexPath row] > 0) {
return proposedDestinationIndexPath;
}
NSIndexPath *betterIndexPath = [NSIndexPath indexPathForRow:1 inSection:0];
return betterIndexPath;
(From "iPhone Programming" by Joe Conway & Aaron Hillegass)
For the iPhone, is it possible to configure a UITableView such that it will allow multiple-selection?
I've tried overriding -setSelected:animated: for each UITableViewCell, but trying to fudge the required behavior is tricky as it's difficult to separate the real unselections from the ones where the UITableView thinks I've unselected due to selection of another cell!
Hope someone can help!
Thanks,
Nick.
Following property should work fine if you are developing app for iOS5.0+
self.tableView.allowsMultipleSelection = YES;
The best way to do this would be to a checkmark per selected row.
You can do that by setting the accessoryType on the selected UITableViewCell instances to UITableViewCelAccessoryCheckmark.
To deselect the row, set it back to UITableViewCellAccessoryNone.
To enumerate which cells/rows were selected (say, upon clicking a button), simply iterate over the cells of the table looking for UITableViewCellAccessoryCheckmark. Or, manage some NSSet or the like in your table view delegate in the "did select" delegate methods.
Use the following code to set up the cell accesory types:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *thisCell = [tableView cellForRowAtIndexPath:indexPath];
if (thisCell.accessoryType == UITableViewCellAccessoryNone) {
thisCell.accessoryType = UITableViewCellAccessoryCheckmark;
}else{
thisCell.accessoryType = UITableViewCellAccessoryNone;
}
}
- (UITableViewCellAccessoryType)tableView:(UITableView *)tableView accessoryTypeForRowWithIndexPath:(NSIndexPath *)indexPath {
//add your own code to set the cell accesory type.
return UITableViewCellAccessoryNone;
}
Jeff Lamarche has a tutorial on how to do this here:
http://iphonedevelopment.blogspot.com/2008/10/table-view-multi-row-edit-mode.html
I've not tried the code but it's been on the back of my mind for a while, knowing the day will come when I need it.
I backported allowsMultipleSelectionDuringEditing and allowsMultipleSelection from iOS5 to older iOS. You can fork it at https://github.com/ud7/UDTableView-allowsMultipleSelection
It's drop in replacement and only thing you need to do is change UITableView to UDTableView (in code or interface builder)
From the HIG:
Table views provide feedback when users select list items. Specifically, when an item can be selected, the
row containing the item highlights briefly when a user selects it to show that the selection has been received.
Then, an immediate action occurs: Either a new view is revealed or the row displays a checkmark to indicate
that the item has been selected. The row never remains highlighted, because table views do not display a
persistent selected state.
You'll need to roll your own multiple selection style, either with something like Mail, or using the checkmark accessory on your cells.
Guys for multiple selection you just need
self.tableView.allowsMultipleSelection = YES;
on viewDidLoad and
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *tableViewCell = [tableView cellForRowAtIndexPath:indexPath];
tableViewCell.accessoryView.hidden = NO;
// if you don't use custom image tableViewCell.accessoryType = UITableViewCellAccessoryCheckmark;
}
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *tableViewCell = [tableView cellForRowAtIndexPath:indexPath];
tableViewCell.accessoryView.hidden = YES;
// if you don't use custom image tableViewCell.accessoryType = UITableViewCellAccessoryNone;
}
I was searching for the same issue and the answer of Bhavin Chitroda sovled it for me but with some addition to keep the check mark as it was while scrolling.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if ( [array indexOfObject:indexPath] == NSNotFound ) {
[array addObject:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
[array removeObject:indexPath];
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
The addition:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
// Your code here
.
.
.
if ( [array indexOfObject:indexPath] == NSNotFound ) {
cell.accessoryType = UITableViewCellAccessoryNone;
} else {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
return cell;
}
If you're trying to do something like Mail's multiple-select (to delete mail, for example), then you're probably going to have to manage all the selection yourself. Multiple row selection isn't something that's standard on the iPhone. Mail solves this by using checkmarks to indicate which rows have been selected.
blue highlighted row as an indicator of whether a row is selected is actually discouraged according to the HIG page 121. Checkmarks will do the trick.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
int selectedRow = indexPath.row;
cout << "selected Row: " << selectedRow << endl;
UITableViewCell *indexPathForCell = [tableView cellForRowAtIndexPath:indexPath];
if (indexPathForCell.accessoryType == UITableViewCellAccessoryNone) {
indexPathForCell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
indexPathForCell.accessoryType = UITableViewCellAccessoryNone;
}
}
then add your arraying or how ever you wish to store the data of which were selected.
Note: This does not work in iOS 4+. This is a private, undocumented constant. Do not use it.
If you are not planning to submit your app to the App Store, you can invoke multi-row edit mode by implementing the following method in your UITableViewController delegate:
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
return 3; // Undocumented constant
}
Tested with iOS4.3 - 6.0
-(void)searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller {
if ([controller.searchResultsTableView respondsToSelector:#selector(allowsMultipleSelectionDuringEditing)]) {
controller.searchResultsTableView.allowsMultipleSelectionDuringEditing = YES;
}
else {
controller.searchResultsTableView.allowsSelectionDuringEditing = YES;
}
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewCellAccessoryCheckmark;
}