拖动到视图顶部时,UILongPressGestureRecognizer 在 tableview 中崩溃 - SWIFT

Posted

技术标签:

【中文标题】拖动到视图顶部时,UILongPressGestureRecognizer 在 tableview 中崩溃 - SWIFT【英文标题】:UILongPressGestureRecognizer crashes in tableview when dragged to top of view - SWIFT 【发布时间】:2015-07-21 19:13:07 【问题描述】:

我正在为具有两个节/节标题的表视图中的每个单元格使用 UILongPressGestureRecognizer。当我在第一部分中长按一个单元格并拖动到表格视图的顶部时,我的应用程序崩溃了。 (我为第二部分禁用了 longPressGestureRecognizer)。我在下一行得到一个异常点,

var indexPath: NSIndexPath? = self.routeTableView.indexPathForRowAtPoint(location)!

我在调试器中收到此错误,

致命错误:在展开可选值时意外发现 nil

我的代码如下,

func longPressGestureRecognized(手势:UILongPressGestureRecognizer)

    var state: UIGestureRecognizerState = gesture.state

    var location:CGPoint = gesture.locationInView(self.routeTableView)
    var indexPath: NSIndexPath? = self.routeTableView.indexPathForRowAtPoint(location)!

    if indexPath == nil 
        return
    

    if indexPath?.section != 1 

            switch(state)
            case UIGestureRecognizerState.Began:
                sourceIndexPath = indexPath

                var cell: UITableViewCell = self.routeTableView .cellForRowAtIndexPath(indexPath!)! as! RouteSelectionCell

                //take a snapshot of the selected row using helper method
                snapshot = customSnapshotFromView(cell)

                //add snapshot as subview, centered at cell's center
                var center: CGPoint = cell.center
                snapshot?.center = center
                snapshot?.alpha  = 0.0
                self.routeTableView.addSubview(snapshot!)
                UIView.animateWithDuration(0.25, animations:  () -> Void in
                    center.y = location.y
                    self.snapshot?.center = center
                    self.snapshot?.transform = CGAffineTransformMakeScale(1.05, 1.05)
                    self.snapshot?.alpha = 0.98
                    cell.alpha = 0.0
                    , completion:  (finished) in
                        cell.hidden = true
                )

            case UIGestureRecognizerState.Changed:
                var center: CGPoint = snapshot!.center
                center.y = location.y
                snapshot?.center = center


                //is destination valid and is it different form source?
                if indexPath != sourceIndexPath
                    //update data source
                    self.messageOptions.exchangeObjectAtIndex(indexPath!.row, withObjectAtIndex: sourceIndexPath!.row)
                    //move the row
                    self.routeTableView.moveRowAtIndexPath(sourceIndexPath!, toIndexPath: indexPath!)
                    //and update source so it is in sync with UI changes
                    sourceIndexPath = indexPath
                

            default:
                //clean up
                let cell: UITableViewCell = routeTableView.cellForRowAtIndexPath(sourceIndexPath!)!
                cell.alpha = 0.0
                cell.hidden = false

                UIView.animateWithDuration(0.25, animations:  () -> Void in

                    self.snapshot?.center = cell.center
                    self.snapshot?.transform = CGAffineTransformIdentity
                    self.snapshot?.alpha = 0.0
                    //undo fade out
                    cell.alpha = 1.0

                    , completion:  (finished) in
                        self.sourceIndexPath = nil
                        self.snapshot?.removeFromSuperview()
                        self.snapshot = nil
                )
                break
            
        
   

有人对如何避免这个问题有任何建议吗?

【问题讨论】:

【参考方案1】:

当您调用 self.routeTableView.indexPathForRowAtPoint(location)! 时,您将强制解开返回的值,在这种情况下,它是 nil。这就是你崩溃的地方。

你的代码应该是这样的:

if let indexPath = self.routeTableView.indexPathForRowAtPoint(location) 
  //do normal code
 else 
  //the point didn't map back to a cell! Maybe it was on the header or footer? 
  //Handle this case differently.

另外,我发现这个答案可能会有所帮助:

indexPathForRowAtPoint returns nil only for first cell in a uitableview

【讨论】:

啊。所以我删除了“!”并且不再崩溃。但是,当我拖动到视图顶部时,我的单元格/快照正在禁用。它似乎悬停在其他单元格上。 在 else 语句中,您必须管理如何处理那些特定的边缘情况。例如,如果它位于屏幕顶部,则可能将其插入到索引 0。如果它位于底部,则将其插入到表格的末尾。 你说的是snapshot.layer.edgeAntialiasingMask吗?对不起。我才开发了一年多一点。

以上是关于拖动到视图顶部时,UILongPressGestureRecognizer 在 tableview 中崩溃 - SWIFT的主要内容,如果未能解决你的问题,请参考以下文章

将图像从滚动视图拖动到视图而不会影响其位置

拖动底部子视图之一时平滑更新顶部子视图(iOS)

将动态视图捕捉到屏幕顶部、底部或中间的统一行为

如何将一个按钮从cardview布局的中心拖动到android中的左,右,顶部和底部

ios - 滚动到结束时滚动视图缩放,如 Fancy

bar button item segue 不在下一个视图顶部添加导航栏