For my iPhone app, I have an editable (for delete) table view. I'd like to be able to detect that the user has clicked the "Edit" button. See this image: http://grab.by/It0
From the docs, it looked like if I implemented :
- (void)tableView:(UITableView *)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath
then I could detect it (although from the name of the method, I wouldn't think that). This proved not to work.
Any ideas on detecting this? The reason I want to is I want to hook up a "Delete all" button in the upper left hand corner when in delete mode.
thanks
It is probably not working as you expect because willBeginEditingRowAtIndexPath: is called before the editing starts.
If you want to check while in another method you need the editing property:
#property(nonatomic, getter=isEditing) BOOL editing
If you want to do something when the 'Edit' button is pressed you need to implement the setEditing method:
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
Which you'll find in UIViewController. (Well, that's the most likely place; there are others.)
Swift
Use below code accordingly:
open var isEditing: Bool // default is NO. setting is not animated.
open func setEditing(_ editing: Bool, animated: Bool)
When subclassing a tableviewcontroller (what most people are going to be doing most of the time since you have to override it's delegate methods just to put data into it...) you can just override the setEditing:animated: method to grab editing state changes.
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
NSLog(#"Editing %i", editing);
[super setEditing:editing animated:animated];
}
That passes the state change along to the super class, but lets you jump in the middle and detect the change, or alter it if you wanted...
The setEditing:animated: examples didn't work for me (on iOS 6.1) to detect the state changes that occur when you enter and exit delete confirmation mode. It seems that setEditing:animated: is only called once, when the table view goes into edit mode, but not on state changes of the cells. After some debugger fun, I arrived at a method to detect the cell state change.
My use case is different from yours. I just wanted to hide the label when the delete button is showing so that the other cell content doesn't overlap it when the Delete button slides in. (I'm using UITableViewCellStyleValue2, the one with the blue label on the left and black label on the right.)
(In your UITableViewCell subclass)
- (void)willTransitionToState:(UITableViewCellStateMask)state {
[super willTransitionToState:state];
if (state & UITableViewCellStateShowingDeleteConfirmationMask) {
// showing delete button
[self.textLabel setAlpha:0.0f]; // <-- I just wanted to hide the label
}
}
- (void)didTransitionToState:(UITableViewCellStateMask)state {
if (!(state & UITableViewCellStateShowingDeleteConfirmationMask)) {
// not showing delete button
[self.textLabel setAlpha:1.0f]; // <-- show the label
}
}
Kendall 's answer works. I did it in following way.
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the specified item to be editable.
NSLog(#"Can edit %d", tableView.editing);
if (tableView.editing == 1) {
[self.editButtonItem setTitle:EDIT_BUTTON_TITLE];
}else {
[self.editButtonItem setTitle:DONE_BUTTON_TITLE];
}
return YES;
}
That method tells you when a user is editing a Cell, not put the table into editing mode. There is a method called when editing mode is entered, to ask each cell if it can be edited:
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
I don't think overriding setEditing:animated: makes sense, since you would have to subclass UITableView which is extra work and a class you need for no other reason, not to mention it would have to communicate the fact that editing had been turned on back to the controller.
One other option is to simply add the Edit button yourself - it's a built in UIBarButtonSystemItem, you can add it and then have it call your own method in which you do something specific then call setEditing:animated: on the UITableView itself.
The idea behind editing is that when editing is enabled, each cell is told to go to edit mode, and as asked if there are any specific editing controls that should be applied. So in theory there's no need to detect entry into editing mode beyond changing the appearance of cells. What are you trying to do when editing mode is entered?
Related
I added an Edit button to Navigation bar in my app.
I have a UIViewController which implements UITableViewDataSource and UITableViewDelegate.
I added the UITableView using storyboards and made connections to data source and delegate.
I did like this in implementation file of the view controller:
self.navigationItem.rightBarButtonItem = self.editButtonItem;
[self.editButtonItem setAction:#selector(setEditing:animated:)];
and
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
DLog(#"Editing = %d", editing)
NSLog(editing ? #"Yes" : #"No");
[self.recentSearchList setEditing:editing animated:YES];
}
The problem is that whenever I tap on Edit button, the BOOL variable "editing" is always "YES". And for the first it sets the UITableView to editing mode but the Edit button still shows "Edit" label instead of "Done". And the since the parameter is always YES, the table view is never set to normal mode.
I read from an Answer in here: UITableView in edit mode - 'Edit' button doesn't change status
I am assuming the Edit button should change its state itself on tapping. And the parameter in the overridden method should also toggle.
I can write code of my own to set flags in the UIViewController to check the mode and toggle the tableView accordingly but I am assuming that there must be some other way.
From the documentation
Also remove the line [self.editButtonItem setAction:#selector(setEditing:animated:)];
The editButtonItem gets implicitly associated with the method - (void)setEditing:(BOOL)editing animated:(BOOL)animated.
So you just gotta override that method and call super's implementation at the top as the documentation says.
I think if you look more closely you will see that editing is actually a reference to the control itself.
When you call setAction on a UIControl ( your right button in this case ) your target can have one of the following signatures.
- (void)action
- (void)action:(id)sender
- (void)action:(id)sender forEvent:(UIEvent *)
You have to handle edit mode within this method separately.
In the mail app, you can swipe to delete a message. You can also hit edit, and select multiple messages, and delete them.
I want to be able to do the same in my table views.
I already had swipe to delete, by implementing the required delegate method:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
// squish it.
}
}
And then I found about this great new property apple introduced in iOS 5, tableView.allowsMultipleSelectionDuringEditing. So, in my viewDidLoad:
if ([self.tableView respondsToSelector:#selector(setAllowsMultipleSelectionDuringEditing:)]) {
self.tableView.allowsMultipleSelectionDuringEditing = YES;
// set up a little toolbar to commit edits
}
And it worked, and that was fun... until I tried to swipe to delete again.
For some reason, the multi-edit functionality was preventing the standard swipe to delete style edit. I want both. Anyone know how to get both working?
Clearly you can just set allowsMultipleSelectionDuringEditing to YES right before you enable editing mode on the tableview. Do this inside setEditing:animated:
Edit: Ah, it also looks like this has been answered already: How do I get swipe-to-delete working when tableView's allowsMultipleSelectionDuringEditing property is YES?
I know this question has been asked before, but no one has really answered it.
I am trying to make an app with a static table view and a Done/Edit button in the top-right corner. I need to be able to hide a cell when it is in one state, and display that cell when it is in the other state. Also I need to be able to add cells when the user selects something. I all ready have the bool in place to detect the change of the Done / Edit button.
So basically my question would be: how do you go about making the table view display the cell when the user presses the button, and hide it when the user presses it again.
And how to add the static cells through the code.
Thanks!
I haven't really looked at the static table stuff in iOS 5 because I believe that requires storyboards, which I don't use.
This can be easily accomplished with a classical grouped UITableView, however. In your UITableViewDataSource methods merely return different results based on the editing state. If you are using the literal editing mode of the UITableView you could do something like the following (warning: typed in browser):
– (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
if ([tableView isEditing]) {
// Return number of sections when editing
}
else {
// Return number of sections when not editing
}
}
– (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
{
if ([tableView isEditing]) {
// Return number of rows in section when editing
}
else {
// Return number of rows in section when not editing
}
}
// etc.
I don't recall whether the -setEditing: transition handles animation for you, but if it doesn't then you will want to use -insertRowsAtIndexPaths:withRowAnimation: and related methods to notify the table view that the number of rows, sections, etc. has changed and that it should animate to the new layout. Finally, if you are adding/removing multiple rows/sections, as always you probably want to wrap your work in a -beginUpdates/-endUpdates pair so that the animations are all coalesced.
I created an iOS application based on navigation-based application template, the application is backed by Core Data framework.
When clicking on Edit button, I want the rows to be reorder-able and delete-able.
When constructing cells, I added this line:
cell.showsReorderControl = YES;
And tableView:canMoveRowAtIndexPath: method returns YES.
But the reorder control isn't displayed in the row, Am I missing something?
From the UITableViewCell showsReorderControl docs:
For the reordering control to appear, you must not only set this
property but implement the UITableViewDataSource method
tableView:moveRowAtIndexPath:toIndexPath:. In addition, if the data
source implements tableView:canMoveRowAtIndexPath: to return NO, the
reordering control does not appear in that designated row.
The UITableView also has to be in editing mode, which it's not in by default. Usually you use a button or some other control to toggle between editing mode. To put the table view in editing mode (we assume you have a UITableViewController and your tableView property is properly set, if not, adjust for your environment):
// This line somewhere inside the UITableViewController will
// animate in the various editing controls and make sure they
// show up on your table.
[[self tableView] setEditing:YES animated:YES];
try this . . .you have to implement these two methods to get that reorder control in editing mode
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{
}
I search didSelectRowAtIndexPath this key word
And found most problem is how to trigger it
But my question is how to enable it with another conditions
You can check my last question here - How to add a radio button in tableview
how To disable this void when the radio button is not selected ???
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {}
I'm a bit confused by your question, but from what I can tell, you want to prevent a tableView row from being selected under certain conditions? For that you'll want to use tableView:willSelectRowAtIndexPath:. If you return nil from that method the tableView will not select a row. You may find it helpful to read the documentation for UITableViewDelegate.
Well I guess you need to run the code within the method conditionally. If your radiobutton is enabled, just run it, if not, return nil (or the other way round). You cannot prevent the method from being called at all, however.
according to your radio button state set the cell property
cell.userInteractionEnabled = NO;