adamshin / swiftreorder Goto Github PK
View Code? Open in Web Editor NEWEasy UITableView drag-and-drop cell reordering
License: MIT License
Easy UITableView drag-and-drop cell reordering
License: MIT License
Hey there!
Sorry to take your issue tracker hostage but I couldn't really find an answer to my question.
I am currently trying to replicate Procreate's "pinch to merge layers" ListView that you can see in this short YouTube video.
I thought I found a solution with your library but after taking a closer look I think it's actually not possible as of now.
I am really new to iOS app creation and was wondering if you could give me some hints on how to implement the above. I think your code is a good starting point. I know for a fact that it is possible to drag and drop multiple ListItems as I found that on the Apple API page somewhere. Maybe it has been done that way, where the pinch triggers somehow the drag and drop action and while you still hold the pinched items your code would somehow kick it, allowing reordering.
I am actually only interested in the pinching part as the ListView that I have in my project does not need reordering.
Sorry for bothering you and any inconveniences I cause :)
Edit: I am coming from Android and apparently ListView is called UITableView over here :)
Great library, perfect drop in functionality for what I need. This is more of a feature request. I have some dynamic content - the cell number - that I'd like to have update as the cell is dragged around. Other use-cases could be imagined (background colour in an alternately-striped table etc). I'd like a method I could call from the delegate as the cell moves. I'm already reloading data in the delegate's reorderRowAt...
method but this doesn't regenerate the UIImage snapshot used in dragging. A naive fix for this is to make createSnapshotViewForCell()
public and call that, but I suspect that there are situations where something this simple will break. Happy to look at contributing a PR if you can suggest your preferred extension point for this. Thanks.
Didn't really know how to title it, but you can watch this happen here: https://streamable.com/rjcd
You should be able to see it when I showcase it in the second half of the video.
I haven't looked too deep into the source code, but I'm guessing this might have something to do with the spacer?
@adamshin I have used reorder framework in multi section table view. Now i want to stop reorder to one section to one another section is this possible?
More of a question than an issue.. But what do you recommend to keep the revised cell order?
Thanks
I have a custom section header cell using override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
. Some of the sections have no cells in them. When I attempt to drag a cell to an empty section the section header will be a white blank rectangle.
This happens when hovering over an empty section while dragging and persists after a cell is dropped into the empty section. Sometimes it will fix itself after I touch and hold the cell that dropped into the empty section so I can drag it and then drop it immediately without moving it anywhere.
EDIT:
I managed to work around this bug by creating the section header programatically instead of with the storyboard editor.
I have created the expand collapse version of UITableView. now I want to implement your framework on it. The reordering performs very well if UITableView is in expanded form (means Multiple rows in sections),
But when the sections are collapsed (Means that no rows are being showed inside the section), if I drop row in such section crashes the app, where as if this section is also expanded the row gets drop and reorder.
How can we implement this ???
It would be very helpful if Swift Package Manager was supported by including a Package.swift file.
I have a tableview with multiple sections and each section has 1 row.
When I try reordering it crashes saying that
attempt to insert row 1 into section 1, but there are only 1 rows in section 1 after the update
I guess it's because the tableView tries to add tile to the destination section but I return 1 on numberOfRowsInSection.
Is there any solution to solve this issue?
Thanks in advance
Hi there,
I have an issue when I have a long list of items and I want to reorder the list. I take my last item and I want to put it on top but the scroll seems infinite.
Checkout this video : http://sendvid.com/rnqf5s1k
Do you have any idea of what happening ?
Thank you
Seeing the following error when I try to run Carthage update:
*** Checking out SwiftReorder at "5.0.0"
*** xcodebuild output can be found in /var/folders/k3/x99j9z1x0k98rf_1y0j94k_40000gp/T/carthage-xcodebuild.VnAuSo.log
*** Skipped building SwiftReorder due to the error:
Dependency "SwiftReorder" has no shared framework schemes
Is it possible to make the user move the cell only if the user touches the right side of the cell?
Looking at the way the spacer cell behaves, a new cell is inserted into the table view, and is causing the cell properties to become out of alignment with the datasource. This isn't immediately obvious on cells with a static appearance, but on cells where the appearance is driven by the datasource, you can see the changed cells jump by one index each time the long press is activated.
Removing this spacer cell call in cellForRow:atIndexPath
fixes the problem, but of course, then we don't get the spacer cell:
if let spacer = tableView.reorder.spacerCell(for: indexPath) {
return spacer
}
Here's a gif that illustrates what I'm seeing:
I have implemented the SwiftReorder and it's really cool. I'm facing an issue when I drag a cell from the bottom to up, but when the cell gets to the top, the whole tableview starts to shake as you can see in the video attached. is there a way to fix it?
Thanks for sharing a nice library.
I built a custom UITableView and tried to use your library.
pod 'SwiftReorder', '~> 4.0'
customTableView.reorder.delegate = self
...
extension CustomViewController: TableViewReorderDelegate {
func tableView(_ tableView: UITableView, reorderRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
// Update data model
}
}
But I am getting the following errors.
Value of type 'CustomTableView' has no member 'reorder'
Use of undeclared type 'TableViewReorderDelegate'
Am I missing something? Appreciate any help!
I have cells with custom properties, but when I pick up any cell, the rest of them seem to reset and behave unexpectedly. Here is an example of my issue:
https://gfycat.com/bleakconcernedarmadillo
This seems to be a bug unique to this pod, as other ones I have tried do not replicate this issue. Let me know if there's anything you want me to provide to figure this out.
There seems to be some UI glitches occurring when I try
Hey there!
I also allow drag and drop via apple's functionality in edit mode, and am trying to make it match.
One big thing that is different that I think is really cool is that with apple's edit functionality, you feel a slight vibration when your drag moves over a tableviewcell.
Also - awesome library, clean code. If you want to give me a pointer on where the code detects the cell moving over another cell & re-adjusting I might give this a shot. I'd have to do some research on how to programmatically give that vibration.
Hey Adamshin great job on this lib but I got a little issue,
I have 2 sections attached to 2 arrays (1 section per array) where the first section has an array with a fixed size of 1.
Whenever I drag a cell from the second section to the first section I want the current cell in the first section to move to the second section if I drop the cell that is being dragged on the first section. Is that possible?
I tried many things such as: calling func tableView(_ tableView: UITableView, reorderRowAt s: IndexPath, to d: IndexPath)
in the func tableViewDidFinishReordering(_ tableView: UITableView)
but I constantly get an assertion failed error unfortunately.
I tried to reorder it after it was dropped, ofcourse I changed my first section array to 2 for this scenario. But again, I get an assertion failed.
The library is not compiling in Xcode 10 and Swift 4.2
Hello, great library! I have an issue for buttons with images that I tint to change their color inside a cell. When I start the dragging the cell the tint color that I set is re-setted to the buttons image original colors. For example I've set the tint color for those buttons to be green and when dragging starts the buttons became black, witch is the image original color. Thanks again for this very useful library, best.
This occurs when the content size is larger than the table view bounds. Probably an issue with cell height calculations.
Hey there,
I opened a PR for an example of this issue. Check it out - if you add UIContextMenu interactions to your cells via the new iOS 13 APIs, the reordering doesn't work very well. This is a gesture recognizer conflict. I'm not sure how to fix it. Suggestions are encouraged :)
i am going to display an image, for example a black color of star image, when i trying to reordering the cell, the star will change to yellow color. After finish the reordering, the yellow star will change to black star.
Cool Repo. Please make it into a Pod. That will be more helpful.
Hi!
Could you please add Carthage support?
I got: "Dependency "SwiftReorder" has no shared framework schemes" when I run carthage update command
Tanks!
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (7) must be equal to the number of rows contained in that section before the update (7), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'
Crash occur, when I cross Section header with cell that I want to get order.
I need to change row before is moved.
Now I'm trying at tableViewDidBeginReordering level, but the row is magnified and receives the changes when I finish the drag movement.
Thanks. Great library.
I encountered a bug where when long pressing a row that appeared towards the bottom of a longer table view (after scrolling to reach the row) would have no effect. I took some steps to diagnose.
Steps to Reproduce:
Setting breakpoints shows the gesture recognizer is triggered. The reordering process stops on line 33 of ReorderController.swift: guard let cell = tableView.cellForRow(at: indexPath) else { return }
The cell is nil, even though the cell is clearly visible on the screen. Further diagnosis shows that calling: tableView.indexPathsForVisibleRows
reveals that the index path for the selected row does not appear in the list, even though the cell is visible (leading me to suspect this is a UIKit bug, which occurs for a short time after tableView.reloadData()
is called.
Removing the tableView.reloadData()
from line 31 of ReorderController.swift seems to resolve the issue, but am unsure what side effects this may cause.
Can you please guide me how can i disable scrolling for specific table view cell. I want to enable/disable specific cells in tableview. Please let me know, is there any way to do that? I will be very thankful to you.
I have a UITableView with custom cells. In each cell I have a thumbnail image and each thumbnail has a UIGestureRecognizer which responds to long presses and triggers a full screen overlay with a zoomed version of the thumbnail.
After implementing SwiftReorder, my cells are no longer responding to the long press on thumbnail images. Is there a way to have SwiftReorder ignore gestures if they happen on a thumbnail image and send those gestures to my pre-exiting UIGestureRecognizer instead?
After reordering a cell, my first touch to select a cell is completely ignored, and didSelectRowAt does not fire. Only once I touch the cell again for a second time does didSelectRowAt gets called.
I did a dirty workaround by grabbing the gesture recognizer and setting cancelsTouchesInView
to false
, like so:
let gestureRecognizer = tableView.gestureRecognizers?.last gestureRecognizer?.cancelsTouchesInView = false
I should add that my table view is within a UIView within a container view. Whether or not that makes a difference, I am not sure.
Should I submit a pull request that automatically sets this value in ReorderController?
In my table view I have certain rows at the top or bottom that should not be movable and should always stay at the top (or bottom). But other rows can be moved around freely. To implement this behaviour, I have been using the following method:
override func tableView(_ tableView: UITableView, targetIndexPathForMoveFromRowAt sourceIndexPath: IndexPath, toProposedIndexPath proposedDestinationIndexPath: IndexPath) -> IndexPath {}
However, it doesn't seem to have any effect once I introduce SwiftReorder. Is there a way to tell SwiftReorder that I want to allow my users to reorder everything below row 0, or everything above row 14 but keep everything else static?
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to delete row 2 from section 0 which only contains 2 rows before the update'
Getting this error while dragging 3rd row from 0th section to 1st row of 1st section
I have weird results when reordering in tableview. The sourceIndexPath and destinationIndexPath in
func tableView(_ tableView: UITableView, reorderRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath)
are 0 and 2 in one call, followed by 0-1, 1-0.
The log is:
7-6
6-5
5-4
4-3
3-2
2-0
0-1
1-0
this actually puts top (0) element on third (2) position, changing the initial order of the array. Is there any way to disable this 0-2 gaps? Spent a lot of time debugging.
So spend half a day today trying to figure out and maybe fix a bug with cell reordering when you try to reorder a cell to the top with a scrolling involved. Basically all you need to do is to scroll at least a little bit down and then try to reorder cell to the very top. There'll be an animation glitch on the last cell reordering. It especially obvious for grouped table views. I used iPhone SE for tests.
I tried to force layout first and contentOffset
restore after to prevent jumps but while I almost fixed a jump glitch cells content and sizes started to glitch so no idea how to fix this one.
On iOS 11, if you drag a cell near the top or bottom of the screen, there are visual jumps and glitches.
Also, automatic cell sizing is enabled by default in iOS 11. This needs to be disabled manually by the library user (see #6). A note should probably be added in the 'usage' section of the readme.
need to reorder cells automatically without a touch.
Hi, I dont know why need to + 5pixel in here
`let visibleCells = tableView.visibleCells.filter {
// Workaround for an iOS 11 bug.
// When adding a row using UITableView.insertRows(...), if the new
// row's frame will be partially or fully outside the table view's
// bounds, and the new row is not the first row in the table view,
// it's inserted without animation.
let cellOverlapsTopBounds = $0.frame.minY < tableView.bounds.minY **+ 5**
let cellIsFirstCell = tableView.indexPath(for: $0) == IndexPath(row: 0, section: 0)
return !cellOverlapsTopBounds || cellIsFirstCell
}`
It creates a crash when I have 2 section, section 0 is empty, section 1 have 2 rows and visibleCells only have a cell at Index(1, 2)
Is it possible to implement this framework for re-ordering sections by getting indexPath from a selected point. I can manage to do it on my own but I am having difficulties with the scrolling so I was wondering if I could use this instead.
tableView(_:moveRowAt:to:) method is calling multiple time if going to reorder a cell position with far away cell.
I got this issue https://www.youtube.com/watch?v=5vmFZPdEqO0 . Since this issue has not fixed yet. I was just wondering if there are any options to disable Automatic edge scrolling?
Hello again! At some point I'll be putting folders into my table - any suggestions for dragging a cell onto another cell with existing functionality, or places to start to make this possible in your library would be helpful.
I figure additional delegate methods (or a separate delegate) might look something like:
func canDragHoverOverIndexPath(_ indexPath : IndexPath) {
// return true if folder / hoverable element, false otherwise to reorder. Defaults to false if the user doesn't extend/override it.
}
func didDropDragItemIntoIndexPath(_ indexPath: IndexPath, fromSourceIndex sourceIndexPath : IndexPath) {
// delete the source index path and update data. Default to false if the user doesn't extend/override it.
}
I want to add haptic feedback the moment you pick up the cell, but I do not see an option to do so. I tried adding an external function to do so, but I believe this pod takes priority over it.
I have 3 section in my tableview. I dont want to reorder the cells from one section to other section. How to avoid dragging one cell from one section to other section.
This library is very easy-to-use. In some of my projects which build with objective-c also want to use this. Does this library support for the project of objective-c?
It would be nice if there was a way to enable/disable the reordering functionality on a UITableView
.
This could be achieved with a method that removes/adds the UILongPressGestureRecognizer
as necessary.
For reference, here is the hacky code I'm using to achieve this:
(note this outside of the SwiftReorder module, and is inside my UIViewController
with the UITableView
I want the reordering functionality on some of the time.)
private var reorderingLongPressGestureRecognizer: UILongPressGestureRecognizer?
private func setReorderingEnabled(_ enabled: Bool) {
if enabled {
guard let reorderingLongPressGestureRecognizer = reorderingLongPressGestureRecognizer else { return }
tableView.addGestureRecognizer(reorderingLongPressGestureRecognizer)
self.reorderingLongPressGestureRecognizer = nil
} else {
if let longPressGestureRecognizer = removeLongPressGestureRecognizerFromTableViewGestureRecognizers() {
// Only setting it if it exists, as this method may have already been called with enabled == false, in which case we don't want to overwrite the `reorderingLongPressGestureRecognizer`.
reorderingLongPressGestureRecognizer = longPressGestureRecognizer
}
}
}
private func removeLongPressGestureRecognizerFromTableViewGestureRecognizers() -> UILongPressGestureRecognizer? {
guard let tableViewGestureRecognizers = tableView.gestureRecognizers else {
return nil
}
let longPressGestureRecognizer = tableViewGestureRecognizers.first { $0 is UILongPressGestureRecognizer } as? UILongPressGestureRecognizer
if let longPressGestureRecognizer = longPressGestureRecognizer {
tableView.removeGestureRecognizer(longPressGestureRecognizer)
}
return longPressGestureRecognizer
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.