我正在构建一个iOS棋盘游戏(类似于拼字游戏或单词),涉及移动屏幕上的小瓷砖,我发现用户有时很难触摸和移动瓷砖,因为它们也是小。由于游戏的设计,我不能增加瓷砖的大小,所以我不得不实施一些小技巧,使用户更容易触摸和移动瓷砖,并且它们运行良好。剩下的唯一问题是用户有时只在瓷砖外触摸,当用户试图移动它时,瓷砖会保持原样。
我有两个想法可以解决这个问题......
我更倾向于实施解决方案#2,因为解决方案#1有太多问题,更不用说解决方案#2是更真实的体验。也就是说,当用户将手指拖过它并发送触摸事件以将其移动到手指所在的位置时,如何“捕捉”瓷砖?
目前,我的tile是作为UIView的子类实现的,它们直接处理触摸事件(touchesBegain,touchesMoved和touchesEnded)。因此,如果用户仅在视图外触摸并将其手指拖到视图上,则它不会接收任何触摸事件,因为它没有收到初始touchesBegan事件。
提前感谢您的所有智慧!
答案 0 :(得分:4)
也许你应该让“board”视图处理所有的拖动。当触摸开始并且该点处有一个图块时,则开始拖动它。否则,无论何时移动触摸都会检查,一旦找到图块,就开始拖动它。
您可以在棋盘视图中覆盖hitTest:withEvent:
,这样它仍然可以检测到触摸何时触及平铺,但始终返回自身,以便触摸事件进入棋盘视图(例如,记录被击中的子视图)一个单独的成员变量,以便您知道在触摸事件开始进入时稍后开始拖动的内容。)
更多详情
处理触摸时,UIView将使用hitTest查找应接收触摸事件的视图。默认实现检查每个子视图,以便层次结构中的“最深”子视图获得触摸。为了使电路板视图能够接收触摸,您必须在所有磁贴视图上禁用userInteraction。但这意味着你无法使用hitTest来查找被触摸的磁贴,因为它会忽略禁用了userInteraction的视图。
所以我要说的是在触摸视图上启用userInteraction。但是在电路板视图上覆盖hitTest,以便它首先调用超级实现以便找到一个磁贴(如果结果是self
,则电路板本身被命中)。无需实现自己的磁贴搜索。像这样:
- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event
{
UIView *hitView = [super hitTest:point withEvent:event];
if ( hitView != self )
self.draggingTile = hitView;
return self;
}
现在您知道要在touchesMoved
中移动哪个磁贴。但是,我不认为触摸被移动时会调用hitTest,因此如果尚未拾取任何图块,您可能需要手动调用它(您可以从中获取point
和event
触摸传递给touchesMoved
。
答案 1 :(得分:1)
你有没有看过UIGestureRecognizer API?我认为你最好的选择是在你的棋盘视图中添加一个UIPanGestureRecognizer识别器,然后将选择器反射到你的UIViewController。
在ViewDidLoad中设置:
UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc]
initWithTarget:self action:@selector(handlePan:)];
[[self view] addGestureRecognizer:panGestureRecognizer];
然后实现了选择器:
- (void)handlePan:(UIPanGestureRecognizer *)gestureRecognizer{
CGPoint currentPoint = [gesture locationInView:[self view]];
}
当您设置手势识别器时,您可以设置参数来限制回调(仅识别1个手指的平底锅等等。在回调中,您可以检查手势属性以查看平移是否继续或是否来到您也可以抓住当前点并确定它是否在图块中或附近。