ios 关于如何将项目从 UITableView 拖放到 UITableView 的教程
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3481858/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Tutorial on How to drag and drop item from UITableView to UITableView
提问by mj_
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 :).
我一直在这个问题上敲我的头一段时间,我想通了。我想回馈社区,因为我从这个网站得到了很多帮助:)。
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.
我试图将一个项目从一个 UITableView 复制到另一个 UITableView 并且我在网上看到的关于如何做到这一点的信息充其量只是粗略的。我自己想出来的,所以我会描述我的小架构。
- Master UIView
- UIView with UITableView
- Custom UITableViewCell
- Custom UIView that gets copied (Person object in my case)
- Custom UITableViewCell
- UIView with UITableView
- Custom UITableViewCell
- Custom UIView that gets copied (Person object in my case)
- Custom UITableViewCell
- UIView with UITableView
- 主界面视图
- 带有 UITableView 的 UIView
- 自定义 UITableViewCell
- 被复制的自定义 UIView(在我的例子中是 Person 对象)
- 自定义 UITableViewCell
- 带有 UITableView 的 UIView
- 自定义 UITableViewCell
- 被复制的自定义 UIView(在我的例子中是 Person 对象)
- 自定义 UITableViewCell
- 带有 UITableView 的 UIView
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.
我在 UITableView 中的 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.
从 Person 对象开始,这是一个包含图像的简单对象。我不得不实现自己touchesMoved方法来改变当拖动正在发生的人的中心位置。
-(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;
}
}
}
}
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.
我在初始化时将 Person 对象的 userInteractionEnabled 标志设置为 NO,这样表中的任何点击都不会被 Person 对象捕获。在这种情况下,Person 对象将在表内移动,这违背了目的。
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.
下一个对象是我的自定义 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
}
}
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.
重要的是要注意 userInteractionEnabled 标志在上述方法中被翻转。在触摸之前,Person 对象对人的触摸是“禁止的”。自定义单元格捕捉到移动后,通过将其添加到父视图然后激活 Person 来释放 Person(userInteractionEnabled=YES)。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.
这有一个小故障,即 Person 对象在左上角闪烁,但随后立即落到用户的手指上。
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 需要处理“触摸转换”。当用户触摸桌子并且 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;
}
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.
此代码的工作方式是,当人的表蹦出来,它没有触摸聚焦于它。触摸由从中弹出 Person 的 UITableView “拥有”。hitTest 方法是重新聚焦触摸的关键。系统会定期检查哪个 UIView 是触摸的焦点。系统调用 hitTest 方法来识别该 UIView。当 Person 附加到主视图时,此 hitTest 函数会遍历所有子视图并检测 Person 的存在并将其作为“主要”触摸对象返回。手指的任何移动都会立即报告给 Person 而不是 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!
这是实施的胆量。让 UITableView“捕捉”移动的对象现在很简单,我会留给你尝试!如果您有任何问题,请留言!
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
编辑 #1 删除 Person 对象比我想象的更难:)。我不得不添加一行以防止 UITableView 在父移动时滚动,因为 UITableView 正在吸收所有移动事件。
touchesEnded 函数在自定义 UITableViewCell 类中触发。
米
采纳答案by rano
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:
嗨,我已经设法将 UITableView 中的一行拖放到同一个表的另一行上。我创建了一个代表移动项目的 uiImageView(它没有从表格中删除)并将它附加到最前面的 UIView 以使其可在整个屏幕上拖动。以下是一些关于我所面临的痛苦的帖子:
- UITableView: Drag a row onto another one
- UITableView: scrolling programmatically the content view
- UITableView: custom gestures make it scrolling no more
Hope this can help ^^
希望这可以帮助^^