UITableViewCell swiped but delete button doesn't appear - objective-c

This is odd. I'm right swiping a UITableViewCell in the iPad simulator. Even though the event below fires and the swipedCell is not nil, the Delete button doesn't appear. Actually, it appears-but only sometimes. I never get a bad access or a sigbart.
Here's the code:
- (void)handleSwipeFrom:(UISwipeGestureRecognizer *)recognizer
{
if (userListSwipeRightRecognizer.state == UIGestureRecognizerStateEnded) {
CGPoint swipeLocation = [userListSwipeRightRecognizer locationInView:self.outletView];
NSIndexPath *swipedIndexPath = [self.outletView indexPathForRowAtPoint:swipeLocation];
UITableViewCell* swipedCell = [self.outletView cellForRowAtIndexPath:swipedIndexPath];
[swipedCell setEditing:YES];
}
}
Is this just a simulator issue or am I doing something wrong?

If you simply want to enable swipe-to-delete on your table, there is a much easier way to do it. Implement tableView:commitEditingStyle:forRowAtIndexPath: in your data source and the table view will automatically show the delete button when a cell is swiped.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}

If you defined your UITableView in your header, then try:
swipedCell = [self.outletView cellForRowAtIndexPath:swipedIndexPath];

If you use a custom cell and override setEditing, you must call the super method or your delete controls will not be drawn.
- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
[super setEditing:editing animated:animated];
}

Related

Make 'edit' button trigger edit-mode on UITableView

This might be a very stupid question, but I have very little knowledge about Xcode, Objective-C and iOS development in general.
What I have is a UITableViewController, with a number of cells. I've gotten the 'add' and delete (swipe to delete) functions to work, but I cannot figure out how to connect the 'edit' button to a function that will trigger the editing mode of that TableView, so I can rearrange the order of the elements.
I have un-commented these functions:
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the item to be re-orderable.
return YES;
}
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
XYZToDoItem *itemToMove = [self.toDoItems objectAtIndex:fromIndexPath.row];
[self.toDoItems removeObjectAtIndex:fromIndexPath.row];
[self.toDoItems insertObject:itemToMove atIndex:toIndexPath.row];
[self.tableView reloadData];
}
As you can see I have also made a few additions to the moveRowAtIndexPath method following the documentation.
In addition there are these functions;
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[self.toDoItems removeObjectAtIndex:indexPath.row];
[self.tableView reloadData];
}
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
As previously stated the "swipe to delete" function works, I don't know how, but I simply just uncommented these last two methods and edited one a bit to fit my code.
To be more specific, what I'm asking is how can I link the 'edit' button I have in my Navigation Controller to trigger the edit mode for the TableView, thereby showing the three lines (?) known from the TableViews editing mode (and letting me drag the elements to an order I want).
Thanks in advance for all your help! :)
If this is a UITableViewController you have two options. Either use the built-in edit button, which will give you the automatic Edit/Done button change. Use self.editButtonItem in your navigation bar:
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
Or you could use setEditing:animated to change editing state of the tableViewController:
// self is a UITableViewController
[self setEditing:YES animated:YES];
If your viewController is not a subclass of UITableViewController you can set the editing mode of the tableView:
[self.tableView setEditing:YES animated:YES];
If you have a UITableViewController you should use the first way because it is most convenient.

Cell text overlaps the editingAccessory when try to delete a row in iOS7

When I compile my app in the new iOS7, I found a problem when entering in the edit mode of an UITableView.
When I press in the red minus button to delete a row of the table, this row indent to the left to let appear the 'Delete' button. However, when this button appears, the text of the cell overlaps the editingAccesory (this happens only when the text is longer than the length of the cell).
How can I remove the overlapping?
Edit: Images in the comments
Edit 2: Tis is the code of the creation of the table
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [_tweetList count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"SessionDetailCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
Tweet *tweet = [_tweetList objectAtIndex:indexPath.row];
cell.textLabel.text = tweet.text;
return cell;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
[tableView beginUpdates];
Tweet *deletedTweet = [_tweetList objectAtIndex:indexPath.row];
[_selectedSession removeTweetsObject:deletedTweet];
[deletedTweet deleteEntity];
_tweetList = [Tweet findAllSortedBy:#"index" ascending:YES withPredicate:[NSPredicate predicateWithFormat:#"session == %#",_selectedSession]];
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
}
[[NSManagedObjectContext defaultContext]saveToPersistentStoreWithCompletion:nil];
}
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{
selectedPath = indexPath;
[self performSegueWithIdentifier:#"EditTweet" sender:self];
}
Solution:
Finally, I put the accessoryButton in the default state, and I use the edit state only to delete the rows. It's the only solution I've found :(
Perhaps, the method "willTransitionToState" can help people to solve similar problems.
You can hide or remove editingAccesory in editing mode , so there is no overlapping there,
set this,
Screenshot:
I came across this question, because in iOS 8.3 I faced the same problem, that it seems not possible to correctly display the editing accessory AND the delete confirmation without the cell content and the accessory item to overlap. Solving this issue without breaking the transition-animations was quite a challenge. ;)
So here is my solution (assuming that you are using autolayout constraints in IB):
Create a UITableViewCell subclass and link it to your table view cell in IB.
Add an outlet from the autolayout constraint specifying the horizontal spacing bewteen the right-most view and the cell's content view (trailing to margin).
Override willTransitionToState and layoutSubviews as shown below.
Table cell subclass:
#IBOutlet weak var horizontalSpaceConstraint: NSLayoutConstraint!
override func willTransitionToState(state: UITableViewCellStateMask) {
if (state & UITableViewCellStateMask.ShowingDeleteConfirmationMask == UITableViewCellStateMask.ShowingDeleteConfirmationMask) {
self.horizontalSpaceConstraint.constant = 49.0; // ugly, delete-confirmation width
}
super.willTransitionToState(state)
}
override func layoutSubviews() {
if (!self.showingDeleteConfirmation) {
self.horizontalSpaceConstraint.constant = 0.0;
}
super.layoutSubviews()
}
The reason why I cannot use didTransitionToState() (and use layoutSubviewsinstead) to reset the layout constraint is, that this function is simply not invoked (as of iOS 8.3) after transitioning from the delete-confirmation-state. It seems Apple did only handle the case, that the user actually deletes the row, but not the case that the delete-confirmation is closed without deleting the row. :(

UITable view selection stay highlighted

I am using XCode4.2 to develop a storyboard application
I am switching views based on a click in a UITableView after clicking the row is highlighted in blue and the new view is loaded .
when I come back to the original view the row is still highlighted in blue ... how can I disable that ?
I do this in
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath];
}
That way I have the index path that was selected every time.
use deselectRowAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated function to deselect rows in uitableview
call it in your viewWillAppear function
[yourTableView deselectRowAtIndexPath:selectedIndexPath animated:NO];
if you are not sure which is index you select last time you can run a loop on all the index path in your table.
-(void) viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
for(int i = 0; i <= [yourArr count]; i++)
{
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0];
[yourTableView deselectRowAtIndexPath:indexPath animated:NO];
}
}
Note: As I don't know your exact code....you need to modify above code to your needs.
A UITableViewController does this automatically. Otherwise, in your viewDidAppear for the owning controller, you need to call - (void)deselectRowAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated on the table view.

Objective C: How to add "plus" button in cell

Can anyone advise me on how I can add a "plus" button in a UITableView Cell like what you see in the screen shot below?
You can also put the table view into editing mode, implement editingStyleForRowAtIndexPath: and return UITableViewCellEditingStyleInsert (which puts a green circle with a plus sign).
For example...
- (IBAction)editButtonPressed
{
//toggle editing on/off...
[tableView setEditing:(!tableView.editing) animated:YES];
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView
editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 0)
return UITableViewCellEditingStyleInsert;
//gives green circle with +
else
return UITableViewCellEditingStyleDelete;
//or UITableViewCellEditingStyleNone
}
When the green button is pressed, the table view will call tableView:commitEditingStyle:forRowAtIndexPath::
- (void)tableView:(UITableView *)tableView
commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleInsert)
{
//handle insert...
}
else
{
//handle delete...
}
}
The simple way: get an image of the plus, set it for the cell.imageView.image.
You can customize your cell by getting the contentView property of your UITableViewCell and adding the UIImage of the plus button as a subview.
That's not a built-in control. It's probably a custom-style UIButton with that image in its .image property.

How to unselect a UITableViewCell after you have done some action using didSelectRowAtIndexPath?

Currently I do some work inside the didSelectRowAtIndexPath delegate and noticed that my row is still "selected" after I come back to the view controller later.
How can I unselect this row inside the delegate itself?
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
//do logic and ... it remains selected in the view?
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
Typically, you want to deselect the row when the view controller appears again:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
}
That's what UITableViewController does implicitly, and animating the deselection process after the view controller appears again is a helpful hint to the user as to which cell they selected previously.