Reordering UITableView without reorder control

前端 未结 5 1141
挽巷
挽巷 2020-12-10 03:17

I need the user to be able to reorder a UITableView by this way: he touches a cell for a predetermined period (e.g. 1 second), then he can drag and drop it over the other ce

相关标签:
5条回答
  • 2020-12-10 03:48

    I solved the question of the following steps:

    1. Attach gesture recognizer to UITableView.
    2. Detect which cell was tapped by "long touch". At this moment create a snapshot of selected cell, put it to UIImageView and place it on the UITableView. UIImageView's coordinates should math selected cell relative to UITableView (snapshot of selected cell should overlay selected cell).
    3. Store index of selected cell, delete selected cell and reload UITableView.
    4. Disable scrolling for UITableView. Now you need to change frame of snapshot UIImageView when you will drag cell. You can do it in touchesMoved method.
    5. Create new cell and reload UITableView (you already have stored index) when the user finger leaves screen.
    6. Remove the snapshot UIImageView.

    But it was not easy to do it.

    0 讨论(0)
  • 2020-12-10 03:54

    This is an old question, but here's a solution that's tested and working with iOS 8 through 11.

    In your UITableViewCell subclass try this:

    class MyTableViewCell: UITableViewCell {
        weak var reorderControl: UIView?
    
        override func layoutSubviews() {
            super.layoutSubviews()
    
            // Make the cell's `contentView` as big as the entire cell.
            contentView.frame = bounds
    
            // Make the reorder control as big as the entire cell 
            // so you can drag from everywhere inside the cell.
            reorderControl?.frame = bounds
        }
    
        override func setEditing(_ editing: Bool, animated: Bool) {
            super.setEditing(editing, animated: false)
            if !editing || reorderControl != nil {
                return
            }
    
            // Find the reorder control in the cell's subviews.
            for view in subviews {
                let className = String(describing: type(of:view))
                if className == "UITableViewCellReorderControl" {
    
                    // Remove its subviews so that they don't mess up
                    // your own content's appearance.
                    for subview in view.subviews {
                        subview.removeFromSuperview()
                    }
    
                    // Keep a weak reference to it for `layoutSubviews()`.
                    reorderControl = view
    
                    break
                }
            }
        }
    }
    

    It's close to Senseful's first suggestion but the article he references no longer seems to work.

    What you do, is make the reorder control and the cell's content view as big as the whole cell when it's being edited. That way you can drag from anywhere within the cell and your content takes up the entire space, as if the cell was not being edited at all.

    The most important downside to this, is that you are altering the system's cell view-structure and referencing a private class (UITableViewCellReorderControl). It seems to be working properly for all latest iOS versions, but you have to make sure it's still valid every time a new OS comes out.

    0 讨论(0)
  • 2020-12-10 03:57

    For future reference... I had the same problem, I found another question(Swift - Drag And Drop TableViewCell with Long Gesture Recognizer) about it and someone suggested this tutorial: https://www.freshconsulting.com/create-drag-and-drop-uitableview-swift/ worked just perfectly for me

    0 讨论(0)
  • 2020-12-10 03:58

    I know this is a question about UITableView. But I ended with a solution of using UICollectionView rather than UITableView to implement longtap reorder. Its easy and simple.

    0 讨论(0)
  • 2020-12-10 04:08

    The article Reordering a UITableViewCell from any touch point discusses this exact scenario.

    Essentially you do the following:

    1. Find the UITableViewCellReorderControl (a private class).
    2. Expand it so it spans the entire cell.
    3. Hide it.
    4. 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:

    1. Add a long press gesture recognizer on the table view.
    2. Create a snapshot of the cell when the cell is dragged.
    3. As the cell is dragged, move the snapshot around, and call the -[UITableView moveRowAtIndexPath:toIndexPath:].
    4. When the gesture ends, hide the cell snapshot.
    0 讨论(0)
提交回复
热议问题