很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,访问帮助中心 /help/reopen-questions 。
我已经在这个问题上摸索了一段时间了,我终于弄清楚了。我想回馈社区,因为我从这个网站得到了很多帮助:)。
我正在尝试将一个项目从一个 UITableView 复制到另一个 UITableView,而我在网上看到的有关如何执行此操作的信息充其量只是粗略的。我自己想出来了,所以我将描述我的小架构。
Master UIView
UIView with UITableView
Custom UITableViewCell
被复制的自定义 UIView (在我的例子中是 Person 对象)
UIView with UITableView
Custom 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 是属于自定义 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 对象就“诞生”了,并且可以自己处理移动触摸。
这有一个小问题,即 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 正在吸收所有移动事件。 TouchsEnded 函数在自定义 UITableViewCell 类中触发。 米杰