ios - 在 UIScrollView 上平移对象

标签 ios uiscrollview uigesturerecognizer

我正在开发一个应用程序,其中有多个 UIView 对象,它们是 UIScrollView 对象的 subview 。我以编程方式创建 subview ,并根据关联对象的属性将它们放置在 ScrollView 上。允许用户在 ScrollView 上移动这些 subview 。通常这是可行的,但有时 ScrollView 会捕获平移手势。

如果触摸位置在其中一个 subview 内,我想做的是抑制 ScrollView 手势识别器。

我可以通过查看 ScrollView 的手势识别器数组并查找 UIScrollViewPanGestureRecognizer 对象来找到 ScrollView 手势识别器。我假设只能有一个。

我有一个想法是让我的 View Controller 成为这个手势识别器的委托(delegate),然后如果触摸在其中一个 subview 的范围内,则让委托(delegate)抑制它。

这是处理这种情况的最佳方法,还是有更好的方法?

我已经做了类似的事情,在我对我自己的问题的回答中有所描述。 How to get stepper and longpress to coexist?

嗯。看起来识别 ScrollView 的 UIScrollViewPanGestureRecognizer 比我预期的要困难。任何关于这样做的提示都将不胜感激。

我的想法行不通。为了对我的想法进行编码,我不得不让我的 VC 成为 ScrollView 的平移手势识别器的代表。但是,当我这样做时,出现此错误:

*** 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“UIScrollView 的内置平移手势识别器必须将其 ScrollView 作为其委托(delegate)。”

这是我使用的代码。在 viewDidLoad 中,我调用了一个方法来获取 ScrollView 的平移手势识别器并将 self 设置为委托(delegate)(self.scrollViewPanGestureRecognizer 只是一个存储它的属性):

self.scrollViewPanGestureRecognizer = [self.scrollView panGestureRecognizer];
self.scrollViewPanGestureRecognizer.delegate = self;

然后我实现了这个委托(delegate)方法:

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
   //Disable touch if touch location is in a subview.
   BOOL enableGestureRecognizer = YES;

   if (gestureRecognizer == self.scrollViewPanGestureRecognizer) {
      CGPoint touchLocation = [touch locationInView:self.scrollView];
      for (UIView *s in self.scrollView.subviews) {
         if (CGRectContainsPoint(s.frame, touchLocation)) {
            enableGestureRecognizer = NO;
         }
      }
   }
   return enableGestureRecognizer;
}

看起来是个好主意,但看起来我不能让我的 VC 成为代表。

刚刚尝试在 ScrollView 上将 scrollEnabled 设置为 NO。这成功地禁用了滚动,但并没有解决问题。 View 仍然偶尔不响应手势。考虑到可能是某些错误导致手势识别器从对象上掉下来,我要求调试器为有问题的 View 显示手势识别器。他们还在那里。我很难过。

更新:新信息。我终于意识到没有响应的 subview 是屏幕右侧的 subview 。经过仔细测试,这似乎只发生在横向并且只有当手指位置在纵向右边缘的右侧时,即 320 点。显然,当旋转到横向时,某些东西没有被处理。一切看起来都很正常,但无法识别手势。

为了好玩,我决定在方法 viewDidLayoutSubviews 中显示框架和边界以及内容区域。我得到的是:

self.view.frame             is {{0, 0}, {480, 320}} 
self.view.bounds            is {{0, 0}, {480, 320}} 
self.scrollView.frame       is {{0, 0}, {480, 320}} 
self.scrollView.bounds      is {{0, 0}, {480, 320}}
self.scrollView.contentSize is {480, 320}

我好像漏掉了什么。旋转时还需要设置什么?

最佳答案

使用 requireGestureRecognizerToFail: 方法。

您希望 ScrollView 平移手势 (scrollViewGesture) 在其中一个手势发生在其 subview 上时失败。
因此,当您向 subview (subViewGesture) 添加平移手势时,将以下属性设置为

scrollViewGesture.requireGestureRecognizerToFail =subViewGesture;

关于ios - 在 UIScrollView 上平移对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21520437/

相关文章:

ios - Objective-C 中的字符串比较与 isEqualToString

ios - 如何在滚动时将单元格的内容保留在屏幕上,直到单元格用完可用空间?

ios - 处理固定 UILabel 中的长文本的最佳实践是什么

ios - UIScrollView 根据时间改变位置

iOS ScrollView setContentSize 不工作

ios - 如何检测有人在 UIImageView 之外点击

objective-c - 长按 UI 元素(或如何确定按下的是哪个元素?)

iphone - 我需要释放手势识别器吗?

iphone - 在 ARC 下使用 IBOutlets 属性的有用性?

ios - 使用检索到的核心数据