UITableView tap and hold + drag and drop - ios

I wanted to find out how to do the following:
I have a UItableView, which enters edit mode when the user taps and holds one of the rows
Once it enters edit mode I need the cell to remain selected and give the effect of popping out, under the users finger.
The user should be able to drag the popped out cell and reposition it to another row, without lifting the finger.
What I already have in place:
I have a long tap gesture recognizer and I set the table into editing in the long tap gesture recognizer selector.
However in order to drag the cell I currently require to raise the finger and re tap to drag the cell , which is not what I want.
Any help would be appreciated.

At current moment there is a workaround (not easy enough): https://stackoverflow.com/a/7501076/326017 .
And I have found code snippet here: https://github.com/FlorianMielke/FMMoveTableView
"FMMoveTable is an UITableView subclass that provides moving rows by simply tap and hold an appropriate row without switching the table to it's edit mode" - from description

The article Reordering a UITableViewCell from any touch point discusses this exact scenario.
Essentially you do the following:
Find the UITableViewCellReorderControl (a private class).
Expand it so it spans the entire cell.
Hide it.
The user will now be able to drag the cell from anywhere.
Another solution, Cookbook: Moving Table View Cells with a Long Press Gesture, achieves the same effect by doing the following:
Add a long press gesture recognizer on the table view.
Create a snapshot of the cell when the cell is dragged.
As the cell is dragged, move the snapshot around, and call the -[UITableView moveRowAtIndexPath:toIndexPath:].
When the gesture ends, hide the cell snapshot.

Related

Handling gestures for UICollectionView that is embedded in a UIPageView

This question has satisfying answers for the bigger part of this question but there's a small case that I can't get rid of.
After using the method from the accepted answer
Only one of the pages inside the PageView has a CollectionView. When you swipe into that one page and swipe again the collection view handles the gestures because the pageView no longer has a datasource.
If I keep swiping and get to the last cell of the collectionView my next swipe goes to the PageView because I set the datasource (when i was on the last cell). And all is well.
The Problem
Problems start if I change my mind.
On the last cell, if I move my finger slightly towards the next page and then (without removing my finger) swipe towards the previous cell it jumps to the previous page (not the previous cell). Supposedly because the datasource has been set, and the gesture that was supposed to set it to nil was not recognised.
Has anyone had this issue? How do I handle gesture that started in one direction and then went in the other?

How to edit tableview cell on TAP instead of swipe - Swift

I have a UITableViewController and at the moment, the user can swipe left on the cell to reveal an 'add to favourites' button. I would now like to add an icon to the cell that the user can tap to reveal the this button (does the same thing as swiping to the left). This will just act as a visual aid for the users who do not know swiping left will do the same thing.
For my TableView, I use the following code to 'close the cell' when the user has pressed the button:
itemsTableView.setEditing(false, animated: true)
From this I assumed that to manually open the cell I would simply call:
//Get cell
let cell:TableViewCell = itemsTableView.cellForRowAtIndexPath(NSIndexPath(forRow:
sender.tag, inSection: 0)) as! TableViewCell
//Open cell to reveal button
cell.setEditing(true, animated: true)
Unfortunately this does not work. So I would like to know what is the function that is called when a user swipes to the left of a cell and how can I replicate it when a user taps on the icon?
I don't think you're going to be able to do it, sorry. This feature relies on the UITableView's pan gesture recognizer. When the user pans sideways, the table view checks the editActions... delegate method and, if we have edit actions, inserts a private confirmation view behind the cell and allows the cell to be moved to reveal it. You can't trigger that behavior programmatically as far as I can tell.
This would be a reason — one of many very good reasons — for sticking with a third-party scrollable cell class. In this way, the cell is a horizontal scroll view and you just scroll it in code.

Call to didHighlightItemAtIndexPath without a call to didSelectItemAtIndexPath for UICollectionView

I have a UICollectionView where I overrode hitTest:withEvent: in my UICollectionViewCells in order to allow for taps just outside of the cells to register as taps on the cells.
When I do this and I tap just outside the cells that now register as hits, I get calls to didHighlightItemAtIndexPath and didUnhighlightItemAtIndexPath, but I don't get a call to didSelectItemAtIndexPath. If I tap inside the cell I get all of the expected highlight and select item calls as I did before.
I don't have any custom gesture recognizers set up and I don't override touchesBegan or anything like that.
So does anyone know under what conditions you get a call for didHighlightItemAtIndexPath without a call to didSelectItemAtIndexPath? Is there any way to get my didSelectItemAtIndexPath called? Thanks.
EDIT
I forgot to mention that my UICollectionView is within a Today Widget, so it is contained within the Notification Center scroll view. If I move my select code into the didUnhighlightItemAtIndexPath, then it is called when you tap outside the cell, but the result is that you can't actually scroll the Notification Center without selecting one of the cells.
So perhaps the difference between the highlighting and selecting that I'm experiencing here has something to do with the scroll view responder canceling the selection outside of the cell?
OK, I figured out what was going on.
I added a new UITapGestureRecognizer to my UICollectionView. Implementing it like this led me the the solution:
- (void)cellSingleTap:(UITapGestureRecognizer *)sender
{
CGPoint point = [sender locationInView:collectionView_];
NSIndexPath *indexPath = [collectionView_ indexPathForItemAtPoint:point];
[ .... ]
}
When I checked the points returned when I got highlighting but no selection, it became apparent that it happened when the point tapped on was within the section insets of the collection view layout. And when the taps were on the section insets, the indexPathForItemAtPoint calls returned nil.
So basically the collection view will highlight, but not select, taps that are outside cells but are within its section insets. As long as the taps are outside the cells and not within the insets, those taps will result in calls to didSelectItemAtIndexPath.
Since I would like taps within the insets to count as taps on cells, I was able to workaround this issue by adjusting the tap points before my call to indexPathForItemAtPoint.

How do I prevent the user from moving a UITableViewCell to a specific location?

In my TableView, the bottom cell has an "Add Cell" button that is used to..well, add cells. However, the app crashes if the user reorders the tableivew by moving a normal informational cell to the last position, making the "Add Cell": cell next to last.
I was able to prevent moving the "Add Cell" cell using tableView:canEditRowAtIndexPath:. I need something like tableView:canMoveRowAtIndexPath, but I only want to stop movement if they try to move it to the last position. Ideally, I'd need a hypothetical message like tableView:canMoveRowAtIndexPath:toIndexPath.
Any ideas?
I think you can do this by implementing tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath: in your table view's delegate. Make the method return an index path that has a lower row number than your “Add Cell” row.

How move/reorder cells from TableView1 to TableView2

I have several UITableViews, with different datasources in a iPad screen.
I need to copy/move a cell from the first tableView to the second, similar how is done with ListBox in other languages.
Now, I can reorder the cells, but the movement is restricted to the tableView. I want to drag the cell in tableView1 & drop in tableView2.
P.D. I'm open to use any other control to archive this. I take a look at AQGridView & DTGridView, however the layout is based in columns with different #items. If I can emulate columns with this controls or other then I can accept the workaround.
UPDATE:
I hope this links could help:
Observing pinch multi-touch gestures in a UITableView
This is the most close answer:
Drag and drop between two tables in ipad
I know how get a image from a view, I can detect the drag with a Gesture Recognizers, so I have all the setup in place but have not expertise in graphic development, so don't know how put this in motion...
This is definitely a very interesting question, and I wish I had the time to put together some test code to see if the idea I'm about to outline would actually work. My hope is that this will at least point you in the right direction.
UITableViewCell is a subclass of UIView, so I would create a subclass of UITableViewCell called something like DraggableTableViewCell so we can handle the touch events and then perform the following steps:
Create an instance of DraggableTableViewCell and configure it to appear like the selected cell.
Add the new cell as a subview of a view that is a common superview to both tables at the same location as the original cell.
Update the data source for the source table view and remove the original cell from the table view using deleteRowsAtIndexPaths:withRowAnimation:
Move the cell on the display by responding to touchesMoved:withEvent:
When touchesEnded:withEvent: is received, verify the cell is somewhat close to the other table view and determine the index path where to insert the new cell
Update the data source for the destination table view and call insertRowsAtIndexPaths:withRowAnimation:
Remove your draggable cell from its superview with a nice animation.
This entire process will need to be orchestrated by the view controller that controls the various table views on the screen.

Resources