When editing a UITableView, I see strange animation.
Here the print screen:
https://dl.dropboxusercontent.com/u/17347115/errorUiTableViewSetEditing.png
When I have a new project with Xcode 4.6.3 (template "Master-Detail Application) and set the UITableView to Style=Grouped and Run on a iOS 7 device, it presents the same problem, if I change to Style=Plain the problem is resolved.
Here the print screen:
https://dl.dropboxusercontent.com/u/17347115/errorTemplateDefault.png
How I can fix this problem for a UITableView with Style=Grouped ?
Thanks,
Hugo
This helped me out with this exact problem:
- (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath {
return NO;
}
You can not set a table to editing and then immediately set it to not editing. You have to wait for the set to editing animation to finish and then you can set it to not editing.
Related
I have an application where the main root is a UIViewController with a similar behavior like the application of facebook or path, that is, swipe and show another view, on the left or right.
However, my problem is that sometimes the main UIViewController has UITableViewcells, which should be eliminated with swipe, yet this does not work correctly, sometimes it detects the gesture sometimes not.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[dataItems removeObjectAtIndex:indexPath.row];
[self.tableView reloadData];
}
}
I am adopting this library
enter link description here
to make the controller of the UIViewController's
Any idea how to solve this?
Thanks in advance.
The problem is the gesture you're using. If both the table cells and view are trying to intercept swipe events you are guaranteed to not get the behavior you're looking for. The way that I usually solve this problem is to make a button that changes the table into editing mode. That way you don't have a conflict.
[tableView setEditing:YES animated:YES];
The problem isn't program design or language capabilities, it's having the EXACT SAME gesture do two DIFFERENT things. This isn't physically possible to implement and always get what you want. iOS devices can't read minds, although I heard about a new API in iOS 7...
You could try using multi-finger gestures.
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 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
{
}
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?
In my application I have a UITextField inside a UITableViewCell. If I click inside the text field and add some text I find that if try to move the insertion point it works the first time but fails on subsequent attempts. I am completely unable to move the selection; no "magnifying glass" appears.
Even more curious, this "setting" seems to be permanent until I restart the application. And it affects all UITextFields on that screen and not just the one that I originally tried to edit.
If you want to see it yourself, try the "UICatalog" sample that comes with the iPhone SDK. Click "text fields" and then "edit" and play around with the text boxes.
I've done a lot of digging on this but it's pretty hard to Google for! The best references I've found are on Apple's support board and MacRumors formum (both reference a solution that apparently used to work on iPhone 2.0 but does work not with contemporary versions -- I did try).
My feeling that is that this is a bug in the OS, but I thought I'd throw this out to the SO crowd for a second opinion and to see if there are any workarounds. Any ideas?
Following benzado's suggestion, I tried building my application using the 2.0, 2.1 and 2.2 SDKs. I got the same behaviour in all versions. (Actually, something related but not the same broke in 2.2 but that's probably another question!)
I spent a lot of time on this but I finally think that I have it nailed.
The trick is that the table needs to be editable (i.e., its editing property needs to be set to YES). The good news is that you are now able to move the insertion point. Sometimes the magnifying glass doesn't appear or follow but your gesture always seems to work.
Does this still qualify as a bug? Perhaps. At the very least Apple's SDK documentation should be updated. I've raised a bug report with Apple to cover this (rdar://6462725).
Thanks to this post, I've been able to successfully get this to work properly in my app.
Something to add, however:
If you set your table to be editable, you'll likely get different behavior than you expect (indenting, editing widgets, no disclosure indicators, etc.). This surprised me but here's how to best deal with it:
In your UITableView delegate, implement:
- (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
return NO;
}
Then, in your UITableViewCell's implementation, set your UITableView to be editable ONLY when you're actually editing:
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
((UITableView *)[self superview]).editing = YES;
...
}
and disable editing when editing is done:
- (void)textFieldDidEndEditing:(UITextField *)textField
{
...
((UITableView *)[self superview]).editing = YES;
}
This will ensure that your table isn't in editing mode when you're not editing the cell, keeping things working smoothly.
Thanks!
Brian M. Criscuolo
Mark/Space Inc.
The answer by Brian M. Criscuolo is the closest, however its still not quite right - in my usage of SDK2.2.1 I find that I have to do the following:
To your UITableViewDelegate (which is often your UITableViewController) add both of the following:
- (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
return NO;
}
and:
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewCellEditingStyleNone;
}
and:
- (void)viewDidLoad {
[super viewDidLoad];
// do any other customisation here
self.uiTableView.editing = true;
}
If you don't put the top two delegate methods, the above will cause the delete icons next to each row, and the indentation of each row.
You shouldn't need to do anything with textfield delegates as Brian indicated (unless you have multiple rows and you want to respond to a didSelectRowAtIndexPath: event - which you don't seem to get while in edit mode - then you will need to also do as he suggests).
By the way - this seems fixed in SDK3.0 (although subject to change I guess)
It does sound like an OS bug. I would try to reproduce it by running the UICatalog sample against the 2.0, 2.1, and 2.2 SDKs to see if anything changes. (There's a bug related to table cell text alignment that occurs if you build for 2.2 but not if you build for 2.1, regardless of what version of the OS is on the device.)
If it turns out to make a difference, https://bugreport.apple.com/
I tried this with my application and it seems to work as expected. I get a magnifying glass every time. I am using the 2.1 SDK.
actually what works best seems to be to set the table "editing" property to true in "viewDidLoad" and adding these to the table delegate
- (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
return NO;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return NO;
}
you don't need to do anything in the text field delegate
In iOS 12 or later you can select table view cell in the storyboard, then enable User Interaction Enabled in the attribute inspector.