首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在UIScrollView上平移对象

在UIScrollView上平移对象
EN

Stack Overflow用户
提问于 2014-02-03 05:38:19
回答 4查看 4.2K关注 0票数 5

我正在开发一个应用程序,其中有几个UIView对象,它们是UIScrollView对象的子视图。我以编程方式创建子视图,并根据关联对象的属性将它们放在滚动视图中。允许用户在滚动视图上移动这些子视图。通常情况下,这是可行的,但有时滚动视图抓住潘手势。

如果触摸位置在子视图中,我想要做的是禁止滚动视图手势识别器。

通过查看滚动视图的手势识别器数组并查找UIScrollViewPanGestureRecognizer对象,我可以找到滚动视图手势识别器。我想只有一个。

我的一个想法是让我的视图控制器成为这个手势识别器的委托,如果触摸在子视图的范围内,那么委托就会抑制它。

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

我做过类似的事情,在我对我自己的问题的回答中描述了这一点。How to get stepper and longpress to coexist?

嗯。看起来,它将比我预期的更难识别滚动视图的UIScrollViewPanGestureRecognizer。任何关于这样做的提示都将不胜感激。

我的主意行不通。为了编码我的想法,我不得不让我的VC代表滚动视图的pan手势识别器。但是,当我这样做时,我会得到以下错误:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'UIScrollView's built-in pan gesture recognizer must have its scroll view as its delegate.'

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

代码语言:javascript
运行
复制
self.scrollViewPanGestureRecognizer = [self.scrollView panGestureRecognizer];
self.scrollViewPanGestureRecognizer.delegate = self;

然后,我实现了这个委托方法:

代码语言:javascript
运行
复制
-(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;
}

这似乎是个好主意,但看来我不能让我的风投成为代表。

刚在滚动视图上尝试将scrollEnabled设置为NO。它成功地禁用了滚动,但没有解决问题。视图仍然偶尔不会对手势做出反应。考虑到可能是某些bug导致手势识别器从对象中掉下来,我要求调试器为有问题的视图显示手势识别器。他们还在那里。我很困惑。

更新:新信息。我终于意识到,没有响应的子视图是屏幕右侧的子视图。经过仔细的测试,这似乎只发生在景观方向,只有当手指位置是在右边的边缘描绘,即320点。显然,当旋转到景观时,某些东西没有被处理。每件事看起来都很正常,但是手势没有被识别出来。

只是为了保持笑容,我决定在方法viewDidLayoutSubviews中显示框架、边界和内容区域。我得到的是:

代码语言:javascript
运行
复制
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}

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

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-02-04 03:51:13

我找到了解决办法。我忘记了子视图不是直接放置在滚动视图中的。有一个视图最初占据了放置子视图的滚动视图的范围。层次结构如下:

代码语言:javascript
运行
复制
self.view
    scroll view
        UIView (fills whole scroll view)
            subview1
            subview2
            subviewn

在处理旋转的代码中,我没有调整放置子视图的UIView的大小。纠正这个问题解决了这个问题。

我最初尝试在它们和滚动视图之间放置没有UIView超级视图的子视图,但是由于某些原因,它没有工作。增加这个额外的层解决了这个问题,但我忘记了旋转时的调整。

因此,我猜手势识别器没有响应,因为虽然它们是可见的,但它们超出了其superview的范围。

票数 1
EN

Stack Overflow用户

发布于 2014-02-03 06:09:11

使用requireGestureRecognizerToFail:方法。

当其中一个手势发生在其(scrollViewGesture)上时,您希望滚动视图pan手势subView失败。

因此,当您将pan手势添加到您的(subViewGesture),中时,在属性下面设置为

代码语言:javascript
运行
复制
scrollViewGesture.requireGestureRecognizerToFail =subViewGesture;
票数 4
EN

Stack Overflow用户

发布于 2014-02-03 15:03:27

我给出了一个社区wiki的答案,因为我还没有完全想出这个解决方案。主要是从文档中利用这一点:

子类可以覆盖touchesShouldBegin:withEvent:inContentView:pagingEnabledtouchesShouldCancelInContentView:方法(滚动视图调用这些方法),以影响滚动视图处理滚动手势的方式。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21520437

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档