【问题标题】:Tutorial on How to drag and drop item from UITableView to UITableView [closed]关于如何将项目从 UITableView 拖放到 UITableView 的教程 [关闭]
【发布时间】:2011-03-29 18:04:44
【问题描述】:

我一直在努力解决这个问题,我想通了。我想回馈社区,因为我从这个网站得到了很多帮助:)。

我正在尝试将一个项目从一个 UITableView 复制到另一个 UITableView,而我在网上看到的有关如何执行此操作的信息充其量只是粗略。我自己想出来的,所以我将描述我的小架构。

  • 主 UIView
    • 带有 UITableView 的 UIView
      • 自定义 UITableViewCell
        • 被复制的自定义 UIView(在我的例子中是 Person 对象)
    • 带有 UITableView 的 UIView
      • 自定义 UITableViewCell
        • 被复制的自定义 UIView(在我的例子中是 Person 对象)

我在 UITableView 中拥有的 person 对象是我想要从一个表拖放到另一个表中的对象。我最难弄清楚如何将项目从桌子上弹出并以一个平滑的动作将其拖过来。最长的时候,我需要两次触摸才能执行操作。

从 Person 对象开始,这是一个包含图像的简单对象。当拖动发生时,我必须实现自己的 touchesMoved 方法来更改 Person 的中心位置。

-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
    if( m_moveable == YES ){
        UITouch *touch = [touches anyObject];
        CGPoint location = [touch locationInView:self.superview];

        if( 0 < location.x-50 && location.x+50 < 768 ){ 
            if( 0 < location.y-50 && location.y+150 < 1004 ){
                self.center = location;
            }
        }
    }
}

我在初始化时将 Person 对象的 userInteractionEnabled 标志设置为 NO,这样表中的任何点击都不会被 Person 对象捕获。在这种情况下,Person 对象会在表格中移动,这违背了目的。

下一个对象是我的自定义 UITableViewCell。这个对象负责捕捉用户的第一次触摸。它应该做的是抓住这种触摸并“弹出”Person。 Person 是属于自定义 UITableViewCell 的子视图之一。

 - (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    UIView *parent = self.superview.superview.superview;    

    Person *s = nil;
    for( UIView *child in self.subviews ){
        if( [child isKindOfClass:[Person class]] ){
            s = child;
            s removeFromSuperview];
            break;
        }        
    }

    if( s != nil ){
        self.userInteractionEnabled = NO;
        s.userInteractionEnabled = YES;
        UITableView *subParent = self.superview;   //EDIT #1
        subParent.scrollEnabled = NO;              //EDIT #1

        [parent addSubview:s];
        //[self touchesEnded:touches withEvent:event]; //EDIT #1
    }
}

重要的是要注意 userInteractionEnabled 标志在上述方法中被翻转。在触摸之前,Person 对象对人的触摸是“禁区”。在自定义单元格捕捉到移动后,通过将 Person 添加到父视图然后激活(userInteractionEnabled=YES)来释放 Person。 Person 对象然后“出生”并且可以自己处理移动触摸。

这有一个小故障,即 Person 对象在左上角闪烁,但随后立即下降到用户的手指上。

这个设计的最后一部分是主 UIView 需要处理“触摸转换”。当用户触摸表格并且 Person 对象被弹出时,应用程序需要意识到需要从表格中移除焦点并指向 Person 对象。这样做的方式是主 UIView 中的 hitTest 方法被以下内容重载。

- (UIView*) hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    UIView *rv = nil;
    for(UIView *child in self.subviews){
        if( [child isKindOfClass:[Person class]] ){
            rv = child;
            child.center = point;
            break;
        }
    }
    if( rv == nil ){
        rv = [super hitTest:point withEvent:event];
    }   
    return rv;
}

此代码的工作方式是,当 Person 从表中弹出时,它没有针对它的触摸。触摸由从中弹出 Person 的 UITableView “拥有”。 hitTest 方法是重新聚焦该触摸的关键。系统会定期检查哪个 UIView 是触摸的焦点。系统调用 hitTest 方法来识别该 UIView。当 Person 附加到主视图时,此 hitTest 函数遍历所有子视图并检测 Person 的存在并将其作为“主要”触摸对象返回。您手指的任何移动都会立即报告给 Person,而不是 UITableView。

这是实现的核心。现在让 UITableView “捕捉”移动对象很简单,我会留给你尝试! 如果您有任何问题,请发布!

编辑 #1 事实证明,删除 Person 对象比我想象的要难:)。我必须添加一行以防止 UITableView 在父级移动时滚动,因为 UITableView 正在吸收所有移动事件。
touchesEnded 函数在自定义 UITableViewCell 类中触发。
mj

【问题讨论】:

  • @mj_:干得好,感谢分享!看起来花费了很多时间和精力。为你 +1 投票!
  • 不投赞成票,因为这不是问题,而是标记为收藏,因为它仍然很棒。干得好!
  • StackOverflow 不是你的博客。请坚持仅使用问答,以保持本网站为问答网站。
  • 那么,如果这不是问题怎么办 - 我知道 SO 是经过策划的,但我们通常是在寻找问题还是在寻找答案?这很好。这才是最重要的。
  • 顺便说一句,我之前对拖放所做的是将拖动焦点保持在检测到拖动的视图中——不管它是什么。您始终可以在视图之间转换坐标。切换焦点很麻烦。

标签: ios objective-c uitableview drag-and-drop touches


【解决方案1】:

您好,我已经成功地将 UITableView 中的一行拖放到同一张表的另一行上。我创建了一个代表移动项目的 uiImageView(它没有从表格中删除)并将其附加到最前面的 UIView 以使其在整个屏幕上可拖动。 以下是一些关于我所面临的痛苦的帖子:

  1. UITableView: Drag a row onto another one
  2. UITableView: scrolling programmatically the content view
  3. UITableView: custom gestures make it scrolling no more

希望对你有所帮助^^

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-23
  • 2012-11-08
  • 2012-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多