LongPressReorder adresses a common use case when working with tables on an iOS device: the posibility to reorder table rows using a long press gesture, similar to drag and drop gesture. Lightweight and easy to use, LongPressReorder works with any view controller that manages an UITableView. Autoscroll and tables with one or multiple sections are supported.
This Swift module is based on the well-known article posted on raywenderlich.com:
Cookbook: Moving Table View Cells with a Long Press Gesture
To run the example project, clone the repo, and run pod install
from the Example directory first.
UITableViewController with fixed first cell
UITableViewController with multiple sections
Because of the way Swift handles protocols and extensions, it's extremely hard or next to impossible to add the desired behaviour directly on UIViewController or UITableView. Using the objc_setAssociatedObject hack is not an elegant Swift solution, therefore this module uses a wrapper of UITableView to achieve flexibility and cover all use cases.
First of all, import LongPressReorder into your view controller and declare a new variable
var reorderTableView: LongPressReorderTableView!
Assuming we are working with a UITableViewController, create the object in onViewDidLoad()
override func viewDidLoad() {
super.viewDidLoad()
reorderTableView = LongPressReorderTableView(tableView)
}
In the case of a regular UIViewController with an UITableView inside, use the specific table outlet
reorderTableView = LongPressReorderTableView(yourTableViewOutlet)
The only thing left now is to enable it with
reorderTableView.enableLongPressReorder()
That was all. All the cells inside the UITableView can now be reordered using the long press gesture. To disable reordering of cells, simply call
reorderTableView.disableLongPressReorder()
You may want to also disable the table's Selection on the cell for a better visual effect.
Use the delegate member to enable interaction with the LongPressReorderTableView. onViewDidLoad() usually looks like this
reorderTableView = LongPressReorderTableView(tableView)
reorderTableView.delegate = self
reorderTableView.enableLongPressReorder()
Reordering of cells is now purely visual. If you want to also change the model behind the table, LongPressReorder offers the following optional functions which can be grouped in a view controller extension
extension SpecificViewController {
override func positionChanged(currentIndex: IndexPath, newIndex: IndexPath) {
// currentIndex and newIndex rows are swapped, implement accordingly
}
override func reorderFinished(initialIndex: IndexPath, finalIndex: IndexPath) {
// Gesture is finished and cell is back inside the table at finalIndex position
}
}
The module offers additional functions, which can be overridden in order to specify which cells cannot be moved or cannot lose their position inside the table
extension SpecificViewController {
override func startReorderingRow(atIndex indexPath: IndexPath) -> Bool {
// All table cells except the first one can be reordered
if indexPath.row > 0 {
return true
}
// First cell will not respond to the long press gesture
return false
}
override func allowChangingRow(atIndex indexPath: IndexPath) -> Bool {
// All table cells except the first one can be replaced with the selected cell
if indexPath.row > 0 {
return true
}
// First cell will not lose its position and therefore no other cell can replace it
return false
}
}
When there are more cells in the table that the ones that can be displayed on the device screen at a certain moment, autoscroll can be used when reordering the cells. Autoscroll is turned off by default.
reorderTableView = LongPressReorderTableView(elementsTableView, scrollBehaviour: .early)
After pressing on the desired cell, the cell will pop out of the table and will be ready to be dragged around. This pop out effect can be customized using 4 different scales for the selected cell: none, small, medium and big (default is medium).
reorderTableView = LongPressReorderTableView(elementsTableView, selectedRowScale: SelectedRowScale.small)
- Swift 4.1
- iOS 9.0 +
- XCode 9.4+
LongPressReorder is available through CocoaPods. To install it, simply add the following line to your Podfile:
pod "LongPressReorder"
or
pod 'LongPressReorder', '~> 1.2.1'
Simply copy LongPressReorder.swift to your project and you're ready to go.
Cristian Sava, cristianzsava@gmail.com
LongPressReorder is available under the MIT license. See the LICENSE file for more info.