I have two UITableView in my iPad application.
I want to drag a cell from one tableview and drop onto another tableview.
Please suggest me any idea how can I Implement drag & drop between two tables in iPad ?
Thanks in advance
I've implemented a solution to this before.
Approach
The main component of the solution is class that listens for drag / drop events and broadcasts them to a delegate; I called this component the gesture coordinator. It handles the events emitted from a UIGestureRecognizer to calculate the 'drag and drop' state and notify the delegate.
For example, a view controller acting as its delegate would receive messages about when items have been exchanged between collections and then update its collection views and data sources.
The gesture coordinator is essentially just a drag-and-drop decorator for a UIGestureRecognizer.
Gesture Coordinator Logic
Here are the propositions that I considered when implementing the gesture coordinator:
A collection is a view that contains and array of child items.
A drag arena consists of a superview and an ordered set of collections that exist as subviews within that superview.
The order of the collections in the drag arena determines their drag / drop priority. That is, if a collection sits at the beginning of the drag arena's ordered set of collections, then drags and drops occurring on that collection will be recognized in place of any of the later collections in the set.
A drag starts if and only if a gesture is started within the bounds of a draggable item of a collection in the drag arena.
Dragging occurs if and only if, immediately after a drag has been started, the location of the gesture changes within the drag arena.
A drag stops if and only if immediately after dragging the gesture stops, is cancelled or finishes.
A deletion occurs if and only if the drag stops at a point which is specified as being deletable. For example, the user may designate certain bounds within the drag arena to be 'delete on drop' areas.
A rearrange occurs if and only if the drag stops within the bounds of the collection that it started in, on a different item in that collection which is specified as being rearrangeable, and on a point in the drag arena that is not specified as being deletable.
A drop occurs if and only if the drag stops within the bounds of another collection in the drag arena, on a specific item or point that is specified as droppable within that collection, and on a point in the drag arena which is not specified as being deletable.
References
Documentation
Use Case examples
Once you touch upon a row in one table.. You must create a image of the row you want to drag
This could be done by editing didSelectRowAtIndexPath function from where you can actually determine which row was selected.
then move that image along with your drag (by custom implementation of touches:Moved)
CGPoint gesturepoint = [touch locationInView:self.view];
imageview.centre = gesturepoint;
Now you can do this help with dragDelegate and dropDelegate of UITableView from iOS11
Several steps:
Add long press gesture recoginzer, when it's detected, get UIImage from cell you press.
Remove the cell from the tableview (deleteRowsAtIndexPaths:withRowAnimation:). Created a UIImageView by the UIImage you get from step 1. Move the UIImageView while you move the finger.
When the end of gesture, decide the tableview to drop and the location to insert. Then add the selected data to the data source (insertRowsAtIndexPaths:withRowAnimation:).
Related
I have a collectionView with each cell showing an image. I want to implement a drag and drop. This will solve two purpose.
Rearrange cells.
When a image is dragged into other, it forms a collection (think of it as a group containing two or more images).
This behavior is inline with the home screen folder where app icon can be grouped into folders.
Please suggest how I can implement this.
This isn't trivial but it is not impossible either.
Reordering is simpler, and you can take advantage of UICollectionView's methods:
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UICollectionView_class/#//apple_ref/doc/uid/TP40012177-CH1-SW67
Reordering Items Interactively
Collection views allow you to move
items around based on user interactions. Normally, the order of items
in a collection view is defined by your data source. If you support
the ability for users to reorder items, you can configure a gesture
recognizer to track the user’s interactions with a collection view
item and update that item’s position.
To begin the interactive repositioning of an item, call the
beginInteractiveMovementForItemAtIndexPath: method of the collection
view. While your gesture recognizer is tracking touch events, call the
updateInteractiveMovementTargetPosition: method to report changes in
the touch location. When you are done tracking the gesture, call the
endInteractiveMovement or cancelInteractiveMovement method to conclude
the interactions and update the collection view.
During user interactions, the collection view invalidates its layout
dynamically to reflect the current position of the item. If you do
nothing, the default layout behavior repositions the items for you,
but you can customize the layout animations if you want. When
interactions finish, updates its data source object with the new
location of the item.
The UICollectionViewController class provides a default gesture
recognizer that you can use to rearrange items in its managed
collection view. To install this gesture recognizer, set the
installsStandardGestureForInteractiveMovement property of the
collection view controller to YES.
To implement the "grouping" behavior, you need to define your cell in such a way that it can determine whether it is a single item and should just display itself, or if it consists of multiple items, in which case it should be able to pop up a view to act as a tray, possibly its own view controller to handle taps independently. This part is going to be hard as you'll need to implement reordering again, and dragging out, etc.
You might want to search Github and others to see if anyone has implemented a "Springboard" type of app that can get you started.
I have implemented a scrollview that has dynamic content: multiple sub-views displaying photos of players with player names under. The flow is:
1. On the main window, a player is selected.
2. User launches another view to add a new player.
3. When the user goes back to the main menu, the scroll view is refreshed completely so that the new player photo and name is also displayed.
At this time, the scroll-view should still have the previously selected player in focus but instead it is showing it from the beginning.
So the question is: is there a method to automatically scroll to a specific position in the scrollview so the screen still has the selected player in focus?
Yes, there are two:
(1) scrollRectToVisible:animated:
(2) setContentOffset:animated:
You can read about both methods at UIScrollView Class Reference. Either way, you can use an instance variable to store the content offset or the visible rect when the user scrolls, and then use one of the methods I listed above to restore the scroll view position when the player data is updated.
Depending on what you are doing, you may find UITableView easier to implement because it is very customizable "out-of-the-box" and it has plenty of methods to help manage a list (including the ones I mentioned above, and more). If you're interested, have a look at UITableView Class Reference.
Simple, create a CGPoint and a BOOL that you can retain after the view change and set them when you initially navigate away from that page. Then in viewDidAppear you can check if the BOOL is YES and use:
[myScrollView setContentOffset:myCGPoint animated:YES];
Or, if you want the scroll view to appear already scrolled to the correct position, do the same thing except in viewWillAppear with the animated flag set to NO.
I want do drag a lot of selected cells and recorder them in my app.But I don't know how to do it.It seems apple just let u to drag one that what I have done it.
idea?
If it is ok to require that the selected cells are contiguous, then you can cheat by replacing them with a single tall cell.
EDIT:
For noncontiguous, the lazy solution would be to let the user select any cells, then after they drag and drop one of them, just move all the other selected cells right below it.
You could experiment with UITableView and see if it will let you animate out the other selected cells (with deleteRowsAtIndexPaths:withRowAnimation:) as soon as dragging is detected (possibly with UITableViewDelegate's tableView:targetIndexPathForMoveFromRowAtIndexPath:toProposedIndexPath:). You could also see if it will let you redraw/resize the cell when it begins dragging - then you could make it look like a z-layered stack or totem pole them into a tall cell while dragging.
Of course I'm assuming all the selected cells will share the same destination position. I can't wrap my head around noncontiguous sources to noncontiguous destinations in one drag-n-drop. If the user drags down 3 slots, does that mean you add 3 to the positions of all the selected cells? What if that takes a cell out of bounds? Even if you decided on some rules for odd cases like those and actually implemented this monstrosity, it could never be user friendly.
There is no easy way out. You need to handle the animation and movement by yourself.
Maybe you can take a copy of the cells you want to move and show an animation of moving to the destination.
When animation stops change the datasource.
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.
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.