iPhone / iOS的:如何实现拖放滚动视图的子视图?

我在UIViewController有一个水平滚动视图,其中我有很多小图像的图像。 我保持滚动视图的图像,因为图像更多,所以用户可以水平滚动,select图像。 但是,问题是,我不得不select一个图像,并拖放到该UIViewController视图。 但是,由于图像处于滚动视图,将图像拖放到UIViewcontroller的视图不起作用,也没有检测到触摸事件。 请注意 :如果我没有滚动视图,但只保留图像也进入UIViewcontroller的视图本身,拖放图像在同一屏幕上,工作得很好。

如何解决这个问题,当我需要有滚动视图和拖放图像,任何build议/帮助吗?

嗨,Getsy,

我不会直接提供你的代码,但是要知道如何pipe理这个。

你可以用这种方式来pipe理,当时你在scrollView上碰到你的对象,或者当你通过拖动来移动这个对象时, myScroll.scrollEnabled = NO;

然后当在endTouch上,您可以启用Scroll by myScroll.scrollEnabled = YES; 所以通过这个你可以pipe理你的对象滚动希望你有逻辑。

这里是演示代码: 使用ScrollView拖放 。 它具有与touchesMoved:上的Disabling滚动视图相同的逻辑touchesMoved:以及在touchesEnded:Enabling滚动视图。

我之前没有任何子类实现了这种行为。

我使用了canCancelContentTouches = NO UIScrollView canCancelContentTouches = NO ,以确保子视图处理在那里触及它们自己。 如果一个子视图(在你的情况下是一个图像)被触摸,我把视图移出了滚动视图到超级视图,并开始跟踪它的拖动。 (你必须在新的超级视图中计算正确的坐标,所以它保持原位)。

拖完后,我检查是否达到了目标区域,否则我将它移回到滚动视图。 如果这不够详细,我可以发布一些代码。

那么这里是我的示例代码: Github:JDDroppableView

Getsy,

尝试拖放对象的代码:

 -(void)dragAndDropWithGesture { UILongPressGestureRecognizer *downwardGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(dragGestureChanged:)]; [scrollViewAlfabeto addGestureRecognizer:downwardGesture]; for (UIGestureRecognizer *gestureRecognizer in myscrollView.gestureRecognizers) { [gestureRecognizer requireGestureRecognizerToFail:downwardGesture]; } } - (void) dragGestureChanged:(UIPanGestureRecognizer*)gesture { CGPoint point = [gesture locationInView:scrollViewAlfabeto]; if (gesture.state == UIGestureRecognizerStateBegan) { [imageViewToMove removeFromSuperview]; [self.view addSubview:imageViewToMove]; UIView *draggedView = [myscrollView hitTest:point withEvent:nil]; if ([draggedView isKindOfClass:[UIImageView class]]) { imageViewToMove = (UIImageView*)draggedView; } } else if (gesture.state == UIGestureRecognizerStateChanged) { imageToMove.center = point; } else if (gesture.state == UIGestureRecognizerStateEnded || gesture.state == UIGestureRecognizerStateCancelled || gesture.state == UIGestureRecognizerStateFailed) { // Determine if dragged view is in an OK drop zone // If so, then do the drop action, if not, return it to original location NSLog(@"point.x final:%f", point.x); NSLog(@"point.y final:%f", point.y); if (CGRectContainsPoint(goal.frame, point)){ imageToMove.frame = CGRectMake(167, 159, 100, 100); } else{ [imageToMove removeFromSuperview]; [myscrollView addSubview:imageToMove]; [imageToMove setFrame:CGRectMake(12, 38, 100, 100)]; imageToMove = nil; } } } 

可能这个代码会帮助你。

对于类似的问题,我做了如下的UIScrollView子类:当它确定被拖动时,PoliteScrollView将触摸消息传递给它的子视图。

 @interface PoliteScrollView : UIScrollView // number of pixels perpendicular to the scroll views orientation to make a drag start counting as a subview drag // defaults to 1/10 of the scroll view's width or height, whichever is smaller @property(nonatomic,assign) CGFloat subviewDraggingThreshold; // yes when a subview is being dragged @property(nonatomic,assign) BOOL isDraggingSubview; // the subview being dragged @property(nonatomic,strong) UIView *draggingSubview; @end @protocol PoliteScrollViewDelegate <NSObject> @optional - (void)scrollView:(PoliteScrollView *)scrollView subviewTouchesBegan:(NSSet *)touches; - (void)scrollView:(PoliteScrollView *)scrollView subviewTouchesMoved:(NSSet *)touches; - (void)scrollView:(PoliteScrollView *)scrollView subviewTouchesEnded:(NSSet *)touches; @end 

关键的devise思想是拖动滚动视图是不明确的。 用户是滚动还是拖动子视图? PoliteScroll视图通过提供两件事来处理这个事情:(1)定向的概念(如果它的宽度大于其宽度则为水平,否则为垂直);以及(2)在与其方向垂直的方向上构成阻力的阈值距离。 (默认为宽度或高度的1/10)。

我粘贴这个和其他几个文件在一个粘贴bin ,包含以下内容:

  • PoliteScrollView .h和.m
  • DraggableImageView.h和.m – 改变它的位置,当它得到触摸消息。
  • ViewController.m – 演示了两个组合。

要将这些文件合并到一个项目中,请将paste bin粘贴到具有相应名称的文件中,添加一个带有PoliteScrollView的Storyboard(确保将其设置为委托),添加一些图像(ViewController尝试将puppy0.jpeg添加到puppy4.jpeg。

我创build了一个演示如何在两个或多个视图之间拖放的示例: http : //www.ancientprogramming.com/2012/04/05/drag-and-drop-between-multiple-uiviews-in-ios/

我发现将手势识别器注册到与正在拖动的实际视图不同的视图是一个好主意。 这将确保即使拖动的视图改变其“父”视图,手势仍然继续。

也许它可以给一些启发