关于如何将项目从 UITableView 拖放到 UITableView 的教程 [英] Tutorial on How to drag and drop item from UITableView to UITableView

查看:18
本文介绍了关于如何将项目从 UITableView 拖放到 UITableView 的教程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在用这个问题敲打我的头一段时间,我想通了.我想回馈社区,因为我从这个网站得到了很多帮助:)

I've been banging my head on this one for a while and I figured it out. I want to give back to the community since I've gotten a lot of help from this website :).

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

I'm trying to copy an item from one UITableView to another UITableView and information I've seen on the web regarding how to do this has been sketchy at best. I figured it out on my own and so I'll describe my little architecture.

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

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

          The person object that I have in the UITableView is the object that I want to drag and drop out of one table and into another. I had the most difficult figuring out how to pop the item out of the table and drag it over in a single smooth motion. For the longest time, it would take me two touches in order to perform the operation.

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

          Starting with the Person object, this is a simple object that contains an image. I had to implement my own touchesMoved method to change the center position of the Person when a drag is taking place.

          -(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 对象将在表格内移动,这违背了目的.

          I set the Person object's userInteractionEnabled flag to NO on initialization so that any clicks in the table would not get caught by the Person object. The Person object in that case would move within the table which defeats the purpose.

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

          The next object is my custom UITableViewCell. This object is responsible to catch the user's first touch. What it's supposed to do is catch this touch and "pop" the Person out. The Person is one of the subviews belonging to the custom 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 来释放 Person(userInteractionEnabled=YES).Person 对象然后诞生"并且可以处理它自己的移动触摸.

          It's important to note the userInteractionEnabled flag getting flipped in the above method. Before the touch, the Person object is "off limits" to a person's touch. After the custom cell catches a move, the Person is released by adding it to the parent's view and then activated (userInteractionEnabled=YES). The Person object is then "born" and can handle move touches on it's own.

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

          This has one minor glitch in that the Person object blinks in the upper left corner but then drops down immediately to the user's finger.

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

          The final part of this design is that the master UIView needs to handle a "touch transition." When the user is touching the table and the Person object gets popped out, the app needs to realize that focus needs to be removed from the table and directed towards the Person object. The way that this was done is that the hitTest method in the master UIView was overloaded with the following.

          - (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.

          The way that this code works, is that when the Person is popped out of the table, it doesn't have a touch focused at it. The touch is "owned" by the UITableView from which the Person was popped out of. The hitTest method is the key to refocusing that touch. Regularly, the system checks to see which UIView is the focus of a touch. The hitTest method is called by the system to identify that UIView. When the Person is attached to the master view, this hitTest function iterates through all subviews and detects the presence of the Person and returns it as the "dominant" touched object. Any movement of your finger will immediately be reported to the Person and not to the UITableView.

          这是实现的胆量.现在让 UITableView捕捉"移动的对象很简单,我会留给你尝试!如果您有任何问题,请留言!

          This is guts of the implementation. To have a UITableView "catch" the moving object is simple now and I'll leave it for you to try! If you have any questions, please post them!

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

          EDIT #1 Dropping the Person object is proving harder than I thought :). I had to add a line to prevent the UITableView from scrolling when the parent is being moved around because the UITableView is sucking in all the movement events.
          The touchesEnded function fires in the custom UITableViewCell class.
          mj

          推荐答案

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

          Hi I've managed to create drag&drop of a row in a UITableView onto another row of the same table. I created a uiImageView representing the moving item (which was not removed from the table) and attached it to the frontmost UIView to made it draggable on the whole screen. Here are some post about the pains I faced:

          1. UITableView:将一行拖到另一行上
          2. UITableView:以编程方式滚动内容视图
          3. UITableView:自定义手势让它不再滚动

          希望能帮到你^^

          这篇关于关于如何将项目从 UITableView 拖放到 UITableView 的教程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆