美文网首页
Xamarin - UITableView 长按拖动Cell

Xamarin - UITableView 长按拖动Cell

作者: 十一胡言兮 | 来源:发表于2017-06-05 17:20 被阅读0次
    1. UITableView 添加长按事件
      LongPress = new UILongPressGestureRecognizer(new Action(() => { Cell_OnMove(); }));
      tableView.AddGestureRecognizer(LongPress);
      其中Cell_OnMove中代码如下:
      switch (LongPress.State)
      {
      case UIGestureRecognizerState.Began:
      GestureBegan();
      break;
      case UIGestureRecognizerState.Changed:
      //ProcessScroll();
      break;
      case UIGestureRecognizerState.Ended:
      GestureEnded();
      break;
      }

    2. 各个长按状态的响应事件
      2.1 长按手势开始
      /// <summary>
      /// 长按手势开始
      /// </summary>
      void GestureBegan()
      {
      // 得到当前长按的点相对于长按手势载体的位置
      CGPoint location = LongPress.LocationInView(LongPress.View);
      // 根据位置得到IndexPath
      NSIndexPath indexPath = TableView.IndexPathForRowAtPoint(location);
      // 根据IndexPath得到Cell
      var cell = TableView.CellAt(indexPath) as OptionEditCell;
      // 记录长按开始的位置
      sourceIndex = NSIndexPath.FromRowSection(indexPath.Row, 0);
      // 得到cell的移动截图
      snapShotView = GetMoveCellImage(cell);
      // 开启边缘滑动
      StartScroll();
      CGPoint center = cell.Center;
      snapShotView.Center = center;
      snapShotView.Alpha = 0;
      TableView.AddSubview(snapShotView);
      UIView.Animate(0.1, new Action(() =>
      {
      center.Y = location.Y;
      snapShotView.Center = center;
      snapShotView.Transform = CGAffineTransform.MakeScale(1f, 1f);
      snapShotView.Alpha = 1f;
      cell.Alpha = 0;
      }));
      }
      2.2 长按手势变化
      /// <summary>
      /// 长按手势变化
      /// </summary>
      void GestureChanged()
      {
      // 得到当前长按的点相对于长按手势载体的位置
      CGPoint location = LongPress.LocationInView(LongPress.View);

           // 移动位置超出上边界则等于上边界
           if (location.Y <= 0) location.Y = 0;
           // 移动位置超出下边界则等于下边界
           if (location.Y >= TableView.ContentSize.Height - 1) location.Y = TableView.ContentSize.Height - 1;
      
           NSIndexPath indexPath = TableView.IndexPathForRowAtPoint(location);
           var cell = TableView.CellAt(indexPath) as OptionEditCell;
           if (cell == null) return;
           CGPoint cen = snapShotView.Center;
           cen.Y = location.Y;
           snapShotView.Center = cen;
           cell.Alpha = 0;
           if (indexPath != null && !indexPath.Equals(sourceIndex))
           {
               // 移动行,是界面有滑动填充的效果
               Source_OnItemMoved(sourceIndex.Row, indexPath.Row);
               // 记录cell的新位置
               sourceIndex = indexPath;
           }
       }
      

    2.3 长按手势结束
    /// <summary>
    /// 长按手势结束
    /// </summary>
    void GestureEnded()
    {
    UIView.Animate(0.15, new Action(() =>
    {
    // 此处使用sourceIndex,也就是Changed中变化后的位置,如果重新取值有可能取到下一个cell,导致移动的cell没有恢复alpha值
    var sourceCell = TableView.CellAt(sourceIndex) as OptionEditCell;
    sourceCell.Alpha = 1;
    snapShotView.Center = sourceCell.Center;
    snapShotView.Transform = CGAffineTransform.MakeIdentity();
    snapShotView.Alpha = 0;

                // 停止scrollTimer
                scrollTimer.RemoveFromRunLoop(NSRunLoop.Main, NSRunLoopMode.Common);
            }), new Action(() =>
            {
                // 移除snapShotView
                snapShotView.RemoveFromSuperview();
                snapShotView = null;
            }));
        }
    
    1. 开启滚动事件
      void StartScroll()
      {
      scrollTimer = CADisplayLink.Create(ProcessScroll);
      scrollTimer.AddToRunLoop(NSRunLoop.Main, NSRunLoopMode.Common);
      }

    2. 滚动事件
      /// <summary>
      /// 边缘滚动事件
      /// </summary>
      void ProcessScroll()
      {
      // 触发长按变化事件
      GestureChanged();

           // 设置向上移动时,TableView开始滑动的边界
           nfloat minOffsetY = tableView.ContentOffset.Y + edgeScrollRange;
           // 设置向下移动时,TableView开始滑动的边界
           nfloat maxOffsetY = tableView.ContentOffset.Y + tableView.Frame.Height - edgeScrollRange;
           // 得到截图的当前位置
           CGPoint touchPoint = snapShotView.Center;
      
           // 截图位置达到向上的滚动条件,但是没有可以滚动的内容
           if (touchPoint.Y < edgeScrollRange && tableView.ContentOffset.Y <= 0) return;
           // 截图位置满足向下的滚动条件,但是没有可以滚动的内容
           if ((touchPoint.Y > tableView.ContentSize.Height - edgeScrollRange) &&
              (tableView.ContentOffset.Y >= tableView.ContentSize.Height - tableView.Frame.Height)) return;
      
           nfloat maxMoveDistance = 10f;
           if (touchPoint.Y < minOffsetY)
           {
               nfloat moveDistance = (minOffsetY - touchPoint.Y) / edgeScrollRange * maxMoveDistance;
               // 确保停止后,TableView顶部不出现空白
               if (tableView.ContentOffset.Y - moveDistance <= 0)
                   moveDistance = tableView.ContentOffset.Y;
               tableView.SetContentOffset(new CGPoint(tableView.ContentOffset.X, tableView.ContentOffset.Y - moveDistance), false);
               snapShotView.Center = new CGPoint(snapShotView.Center.X, snapShotView.Center.Y - moveDistance);
           }
           else if(touchPoint.Y > maxOffsetY)
           {
               nfloat moveDistance = (touchPoint.Y - maxOffsetY) / edgeScrollRange * maxMoveDistance;
               // 确保停止后,TableView底部不出现空白
               if (tableView.ContentOffset.Y + moveDistance >= tableView.ContentSize.Height - tableView.Frame.Height)
                   moveDistance = tableView.ContentSize.Height - tableView.Frame.Height - tableView.ContentOffset.Y;
               tableView.SetContentOffset(new CGPoint(tableView.ContentOffset.X, tableView.ContentOffset.Y + moveDistance), false);
               snapShotView.Center = new CGPoint(snapShotView.Center.X, snapShotView.Center.Y + moveDistance);
           }
       }
      

    文章根据 http://www.jianshu.com/p/ce382f9bc794 这里的思路来写,整体思路一样,但是实现上有些不一样的地方。

    相关文章

      网友评论

          本文标题:Xamarin - UITableView 长按拖动Cell

          本文链接:https://www.haomeiwen.com/subject/vrxwfxtx.html