拖放功能正常 - 自动滚动无法使用

5
我有一个拖放功能的表格(以下是代码),它工作得很好。但是,我无法将单元格拖到屏幕/视图中未显示的位置。
换句话说,我还没有想出如何使其自动滚动。
有人能否查看我的代码并知道在哪里添加代码以在用户将单元格向视图顶部或底部拖动时启用自动滚动?
func animateCellDrag (gestureRecognizer: UIGestureRecognizer, tableView: UITableView, whichList: String) {

    let longPress = gestureRecognizer as! UILongPressGestureRecognizer
    let state = longPress.state
    var locationInView = longPress.locationInView(tableView)
    var indexPath = tableView.indexPathForRowAtPoint(locationInView)
    var count = 0

    struct My {
        static var cellSnapshot : UIView? = nil
    }
    struct Path {
        static var initialIndexPath : NSIndexPath? = nil
    }

    if indexPath != nil {
        //Steps to take a cell snapshot. Function to be called in switch statement
        func snapshotOfCell(inputView: UIView) -> UIView {
            UIGraphicsBeginImageContextWithOptions(inputView.bounds.size, false, 0.0)
            inputView.layer.renderInContext(UIGraphicsGetCurrentContext()!)
            let image = UIGraphicsGetImageFromCurrentImageContext() as UIImage
            UIGraphicsEndImageContext()
            let cellSnapshot : UIView = UIImageView(image: image)
            cellSnapshot.layer.masksToBounds = false
            cellSnapshot.layer.cornerRadius = 0.0
            cellSnapshot.layer.shadowOffset = CGSizeMake(-5.0, 0.0)
            cellSnapshot.layer.shadowRadius = 5.0
            cellSnapshot.layer.shadowOpacity = 0.4
            return cellSnapshot
        }

        switch state {
        case UIGestureRecognizerState.Began:
            //Calls above function to take snapshot of held cell, animate pop out
            //Run when a long-press gesture begins on a cell
            if indexPath != nil {
                Path.initialIndexPath = indexPath
                let cell = tableView.cellForRowAtIndexPath(indexPath!) as UITableViewCell!
                My.cellSnapshot  = snapshotOfCell(cell)
                var center = cell.center

                My.cellSnapshot!.center = center
                My.cellSnapshot!.alpha = 0.0

                tableView.addSubview(My.cellSnapshot!)

                UIView.animateWithDuration(0.25, animations: { () -> Void in
                    center.y = locationInView.y

                    My.cellSnapshot!.center = center
                    My.cellSnapshot!.transform = CGAffineTransformMakeScale(1.05, 1.05)
                    My.cellSnapshot!.alpha = 0.98

                    cell.alpha = 0.0

                    }, completion: { (finished) -> Void in

                        if finished {
                            cell.hidden = true
                        }
                })
            }
        case UIGestureRecognizerState.Changed:

            if My.cellSnapshot != nil || indexPath != nil {
                //Runs when the user "lets go" of the cell
                //Sets CG Y-Coordinate of snapshot cell to center of current location in table (snaps into place)
                var center = My.cellSnapshot!.center
                center.y = locationInView.y
                My.cellSnapshot!.center = center

                let appDel: AppDelegate = (UIApplication.sharedApplication().delegate as! AppDelegate)
                let context: NSManagedObjectContext = appDel.managedObjectContext!
                let fetchRequest = NSFetchRequest(entityName: whichList)
                let sortDescriptor = NSSortDescriptor(key: "displayOrder", ascending: true )
                fetchRequest.sortDescriptors = [ sortDescriptor ]

                //If the indexPath is not 0 AND is not the same as it began (didn't move): Update array and table row order
                if ((indexPath != nil) && (indexPath != Path.initialIndexPath) && (indexPath?.row < taskList_Cntxt.count)) {

                    switch whichList {
                        case "TodayTask", "TomTask", "TBDTask", "FinTask":
                            swap(&taskList_Cntxt[indexPath!.row], &taskList_Cntxt[Path.initialIndexPath!.row])
                            tableView.moveRowAtIndexPath(Path.initialIndexPath!, toIndexPath: indexPath!)
                            toolBox.updateDisplayOrder()
                        default:
                            swap(&curLifeList_Context[indexPath!.row], &curLifeList_Context[Path.initialIndexPath!.row])
                            tableView.moveRowAtIndexPath(Path.initialIndexPath!, toIndexPath: indexPath!)
                            toolBox.llvc_updateDisplayOrder()
                    }

                    do {
                        try context.save()
                    } catch _ { print("Drag and drop error. State: Changed")}

                    Path.initialIndexPath = indexPath
                }
            }
        default:
            if My.cellSnapshot != nil || indexPath != nil {
                //Runs continuously while a long press is recognized / Animates cell movement
                let cell = tableView.cellForRowAtIndexPath(Path.initialIndexPath!) as UITableViewCell!

                cell.hidden = false
                cell.alpha = 0.0
                UIView.animateWithDuration(0.25, animations: { () -> Void in
                    My.cellSnapshot!.center = cell.center
                    My.cellSnapshot!.transform = CGAffineTransformIdentity
                    My.cellSnapshot!.alpha = 0.0
                    cell.alpha = 1.0
                    }, completion: { (finished) -> Void in
                        if finished {
                            //Completion block removes snapshot of cell, cleans everything up
                            Path.initialIndexPath = nil
                            My.cellSnapshot!.removeFromSuperview()
                            My.cellSnapshot = nil
                        }
                })//End of competion block & end of animation
            }//End of 'if nil'
        }//End of switch
    }//End of longPress if-nil
}//End of longPressGestureRecognized
1个回答

3
我使用以下代码解决了这个问题:
if locationOnScreen.y < 200 && indexPath!.row > 1 {
    let indexPath = NSIndexPath(forRow: indexPath!.row-1, inSection: 0)
    tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: UITableViewScrollPosition.Top, animated: false)
} else if locationOnScreen.y > 550 && indexPath!.row < listCount {
    let indexPath = NSIndexPath(forRow: indexPath!.row+1, inSection: 0)
    tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: UITableViewScrollPosition.Bottom, animated: false)
}

在哪里:

var locationOnScreen = longPress.locationInView(tableView.superview)
listCount = listArrayOrContext.count

插入在switch case中:

case UIGestureRecognizerState.Changed:

我将animate设为false,因为如果不这样做,滚动会非常卡顿和混乱。如果有人知道如何获得缓慢、逐渐的滚动效果,请发布一下。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接