How to block a UITableView Cell from being deleted in iPhone - iphone

I have a UITableView With Two Sections. First section has one row and the section one has variable number of rows which varies according to data entry in database.
I want that user cant delete the cell from first section but he is able to delete the cells from the second section.
I have implemented the commitEditingStyle method for the tableview but the problem is it allows the user to delete the row from first section.
I can put some flag to check it in commitEditingStyle but what I want to do is just block it to show the editing button. That is user wont be able to see the delete button when he swips his or her finger on the table cell.
I did set the property editing=false but cant set editingStyle since it is readonly property. Setting editing=false doesnt work.
tnx.

Yeah this works.
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
switch (indexPath.section) {
case 0:
return UITableViewCellEditingStyleNone;
break;
case 1:
return UITableViewCellEditingStyleDelete;
break;
default:
return UITableViewCellEditingStyleNone;
break;
}
}

Have you tried setting the tableViewCells editing style to none for the first section cells? I think that should work for you

Related

How to disable UITableViewCell selection one by one?

I am creating a table view based iPhone application, Where i need to disable one by one entire table view cell.
The requirement is like -
Case-1 :-
Initially only first table cell row should be user interaction enable, rest should be disable. We can easily do this to make indexPath.row 0 enable in CellForRowAtIndexPath method.
Case-2 :-
If User will tap on First cell and when again he will come back then First cell will be disable and second cell should enable(rest table cell will be disable at this time after second cell).
Case-3 :-
Again if user will tap on second table cell and come back to this table then apart from Third cell, others should be disable and so on...
It means i need to disable one by one all the table cell in serial order.It is possible by setting index but it won't be the proper way to do this. So, can you please suggest me what condition i need to give for this ? Please suggest me for further proceeding.
Thanks.
Just maintain an instance variable which holds the cell number that should be enabled.e.g. enabledCell.
Initialize enabledCell to 0. In didSelectRow increment enabledCell and reload the tableView. In cell for row at indexPath only enable the cell if the indexPath is same as the enabledCell value.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
// write code to dequeue or create new UITableViewCell here
// then check if index is same as the cell that should be enabled
if(index.Path.row == enabledCell)
cell.userInteractionEnabled = NO;
else
cell.userInteractionEnabled = YES;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
//Assuming you have number of rows stored in variable numberOfRows
enabledCell++;
if(enabledCell == numberOfRows)
enabledCell = 0;
[tableView reloadData];
}
There are many ways to do this (from now on, I'm a assuming a linear table view with n rows and only one section).
For example, you can add a BOOL enabled property to your cell model object. In your controller's didSelectRowAtIndexPath: check that property and do nothing if it's set to NO. If it's set to YES then navigate to the appropriate page and exchange the enabled property with the one at index position i + 1 (or position 0 if it's the last entry and you want to cycle).

Filtering UITableViewCells with animation - iPhone Development

This seems simple enough but as yet I am unable to find a solution.
Basically I have a segmented control with two options. The first is the default (and is automatically displayed on load) and when selected displays all rows in a table view. The second is a filter limiting the rows displayed. This is the exact same set-up as used on the "Recents" tab of the iPhone's Phone app that filters 'All' and 'Missed' calls.
At present I have the data loading from two different arrays. The problem is that when I swap the data there is no animation to denote that the rows have been filtered. Apple have implemented this in their Phone app but I can see no way of acheiving this.
Perhaps each cell will need to be deleted and re-added as the user switches between the two states - or perhaps setting the height of the cells that I wish to hide to 0 would acheive the same effect? Does anyone have any experience of producing this accordian-type animation?
I have looked here for some clues but am having problems rolling some code that works. Has anyone implemented this before? If so, how did you get it to work?
You can accomplish a similar effect by calling deleteRowsAtIndexPaths:withRowAnimation: and insertRowsAtIndexPaths:withRowAnimation: on your table view with a UITableViewRowAnimationFade animation.
Have you looked into reloadSections:withRowAnimation:?
The basic idea is to call reloadSections:withRowAnimation: and in your UITableViewDataSource implementation switch on the segmented control's selectedSegmentIndex.
Assuming your data is flat (only one section) it would look something like this:
- (IBAction)segmentSwitch:(id)sender
{
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
switch (self.segmentedControl.selectedSegmentIndex)
{
default:
case 0:
return [self.allRows count];
case 1:
return [self.onlySomeRows count];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
id data;
switch (self.segmentedControl.selectedSegmentIndex)
{
default:
case 0:
data = [self.allRows objectAtIndex:[indexPath row]];
break;
case 1:
data = [self.onlySomeRows objectAtIndex:[indexPath row]];
break;
}
//TODO: use data to populate and return a UITableViewCell...
}

Properly setting up willSelectRowAtIndexPath and didSelectRowAtIndexPath to send cell selections

Feel like I'm going a bit nutty here. I have a detail view with a few stand-alone UITextFields, a few UITextFields in UITAbleViewCells, and one single UITableViewCell that will be used to hold notes, if there are any. I only want this cell selectable when I am in edit mode. When I am not in edit mode, I do not want to be able to select it. Selecting the cell (while in edit mode) will fire a method that will init a new view. I know this is very easy, but I am missing something somewhere.
Here are the current selection methods I am using:
-(NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (!self.editing) {
NSLog(#"Returning nil, not in edit mode");
return nil;
}
NSLog(#"Cell will be selected, not in edit mode");
if (indexPath.section == 0) {
NSLog(#"Comments cell will be selected");
return indexPath;
}
return nil;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (!self.editing) {
NSLog(#"Not in edit mode. Should not have made it this far.");
return;
}
if (indexPath.section == 0)
[self pushCommentsView];
else
return;
}
My problem is really 2 fold;
1) Even when I'm not in edit mode, and I know I am returning nil (due to the NSLog message), I can still select the row (it flashes blue). From my understanding of the willSelectRowAtIndexPath method, this shouldn't be happening. Maybe I am wrong about this?
2) When I enter edit mode, I can't select anything at all. the willSelectRowAtIndexPath method never fires, and neither does the didSelectRowAtIndexPath. The only thing I am doing in the setEditing method, is hiding the back button while editing, and assigning firstResponder to the top textField to get the keyboard to pop up. I thought maybe the first responder was getting in the way of the click (which would be dumb), but even with that commented out, I cannot perform the cell selection during editing.
Good lord I am an idiot. I never added these lines:
self.tableView.allowsSelection = NO; // Keeps cells from being selectable while not editing. No more blue flash.
self.tableView.allowsSelectionDuringEditing = YES; // Allows cells to be selectable during edit mode.
Sorry for the garbage question.
The documentation notes that tableView:willSelectRowAtIndexPath: isn't called when in editing mode. In addition, the blue flash will happen even if you cancel the selection. From the documentation:
This method is not called until users touch a row and then lift their finger; the row isn't selected until then, although it is highlighted on touch-down. You can use UITableViewCellSelectionStyleNone to disable the appearance of the cell highlight on touch-down. This method isn’t called when the editing property of the table is set to YES (that is, the table view is in editing mode).

Preventing cell reordering for particular cells in iPhone SDK

I have 2 sections in my UITableView. I want the 2nd section to be movable but the 1st section of cells not.
Specifying canEditRowAtIndexPath and canMoveRowAtIndexPath doesn't help - the first section cells although not showing drag controls, they still change places if a cell from the 2nd section is dragged over.
Is there a workaround for this?
Try implementing the targetIndexPathForMoveFromRowAtIndexPath method and forcing the row from the second section back to its original place if user tries to move it to the first section:
- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
if (proposedDestinationIndexPath.section == 0)
{
return sourceIndexPath;
}
else
{
return proposedDestinationIndexPath;
}
}

How to find the row index of a UIButton is a TableCell? (iPhone)

In my app, I have a table displaying a cell in each row.
In Interface Builder, I dragged a button onto the cell, styled it as a Dark Info button, and connected it to a IBAction.
That is working fine.
Only, I want the button to behave differently, depending on the row of the table where the cell of the button is.
How would I get that row index?
I realize that I might display a lack of basic understanding of the object hierarchy, but I hope you guys will forgive me
Thanks
Sjakelien
It's definitely not easy to do if you don't have some data set up first. If you can, have an NSDictionary where the buttons are the keys and the values are the index paths, that you update whenever you return a cell from -tableView:cellForRowAtIndexPath:. Something like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
...
[indexDict setValue:indexPath forKey:theButton];
return cell;
}
- (void) buttonPressed:(UIButton *)button {
NSIndexPath *indexPath = [indexDict valueForKey:button];
...
}
You can maintain tags. When you drag and drop the button, check the interface build and you will see "tag" property for these buttons. Assign different values for each of your button ( I assume you have different buttons for different rows, this solution will not work if you have same cell identifier for different rows ). And when you receive an event check for tag value.
I had similar problem with my work and i was maintaing NSArray for each button tag created.
In your tableView delegate and datasource methods (check the docs!) you have several methods, the best one for this is
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
Drop this method in your implementation and say something like
switch (indexPath.row) {
case 0:
//set variable or do method based on row 0 (first row)
break;
case 1:
//set variable or do method based on row 1 (second row)
break;
case 2:
//set variable or do method based on row 2 (third row)
break;
}//and so on
}
another way is to change the base class of your UIButton in your view,
then using this other class wich basically extends an UIButton with an added NSInteger row #property (remember to #synthesize it).
You'll then set this property during the cell setup, and you can retrieve this property within the message method