GithubHelp home page GithubHelp logo

adamshin / swiftreorder Goto Github PK

View Code? Open in Web Editor NEW
398.0 8.0 75.0 415 KB

Easy UITableView drag-and-drop cell reordering

License: MIT License

Swift 98.37% Ruby 0.73% Objective-C 0.90%
ios uikit uitableview swift swift-3 swift-library ui-components

swiftreorder's People

Contributors

adamshin avatar anton-plebanovich avatar ashok28 avatar colinhumber avatar josephduffy avatar larrylegend avatar laxmorek avatar markborazio avatar matuella avatar twodollarsesq avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

swiftreorder's Issues

Question: Pinch detection

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 :)

Unable to dynamically redraw the dragged cell as it moves up and down the table

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.

Section header bug

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.

Swiping row from one section to other section that is collapsed

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 ???

Multi-Section TableView reordering

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

Carthage install error

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

Cells that are adjusted based on datasource values are bumped down due to spacerCell

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:

Dragging a cell to the top makes the tableview shake

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?

Sample.zip

Use of undeclared type 'TableViewReorderDelegate'

Thanks for sharing a nice library.
I built a custom UITableView and tried to use your library.

  • Environments
  1. MacOSX
  2. XCode 9.2 (9C40b)
  3. Swift 4.0
  • Installation
pod 'SwiftReorder', '~> 4.0'
  • Code snippets
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!

Picking up a cell breaks all other cells

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.

Feature Request: Vibration when dragging cell moves (like current apple feature)

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.

Swapping with fixed Array sizes

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.

Tinted buttons in cells changing colors

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.

Conflict with iOS 13 UIContextMenu functionality

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 :)

Carthage support

Hi!
Could you please add Carthage support?
I got: "Dependency "SwiftReorder" has no shared framework schemes" when I run carthage update command
Tanks!

Application crashed when moving cell to other section

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.

Feature: Implement tableViewWillBeginReordering

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.

Reordering of Lower Rows in Long Table View

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:

  1. Create table views with 30ish rows, containing simple text.
  2. Scroll to bottom of table view.
  3. Try to select bottom row to reorder.
  4. Nothing will happen

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.

A way to disable/enable reordering on a tableviewCell.

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.

SwiftReorder blocks other UIGestureRecognizers in tableview cells

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?

First touch to after reordering is being ignored

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?

Does SwiftReorder support targetIndexPathForMoveFromRowAt?

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?

App is crashing when dragging custom cell to a new section

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

is there a way to disable reordering 0->2

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.

Reordering to top is broken on iOS 13.3, Xcode 11.3.1

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.

1

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.

iOS 11 issues

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.

proposedNewDestinationRow()

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)

Feature Request: Drop cell into another cell

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.
}

Feature request: A way to disable/enable reordering on a tableview.

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
    }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.