29

我有一个UIScrollView和另一个UIScrollView里面。它们都水平滚动并具有pagingEnabled = YES. 假设我开始滚动内部滚动视图并到达最右边的边界。如果我继续在其中滚动,则外部 scrollView 开始移动。我需要避免这种情况。内视图应以橡皮筋效果跳跃,外视图应保持原位。

希望它很清楚,但这里有一个草图: 在此处输入图像描述

我试过这样设置outerView.scrollEnabled = NO;

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    outerView.scrollEnabled = NO;
}

,如果只在innerView中滚动,它完全符合我的需要。OuterView 不再滚动。但是scrollEnabled如果我想再次滚动outerView,我必须在某个地方设置回YES。我试过在这里做:

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    outerView.scrollEnabled = YES;
}

,但我遇到了同样的问题:在到达 innerView 的最右边边界后,outerView 滚动而不是 innerView 跳转,并带有橡皮筋效果。

任何建议如何解决问题?

4

4 回答 4

19

更新

此解决方案始终有效:

@implementation InnerScrollViewController <UIScrollViewDelegate, UIGestureRecognizerDelegate>

- (void)viewDidLoad
{
    UISwipeGestureRecognizer*   swipeGesture = [[[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipe:)] autorelease];
    swipeGesture.delegate = self;
    [self.view addGestureRecognizer:swipeGesture];
}

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
    _outerScrollView.scrollEnabled = NO;
    return YES;
}

- (void)handleSwipe:(UIGestureRecognizer*)gestureRecognizer
{

}

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{   
    _outerScrollView.scrollEnabled = NO;
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    if (!decelerate)
    {
        _outerScrollView.scrollEnabled = YES;
    }
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    _outerScrollView.scrollEnabled = YES;
}

@end

-------------------------------------------------- ---------------------

旧答案:并不总是有效

这是我解决问题的方法:

@implementation InnerView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.delaysContentTouches = NO;
    }
    return self;
}

- (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view
{
    return NO;
}

据我了解,self.delaysContentTouches = NO;使所有事件立即传递,并- (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view防止响应者链传递这些事件。

于 2013-03-18T19:25:01.143 回答
2

通过以下方式修改您的方法:

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    if(scrollView == innerView)
        outerView.scrollEnabled = NO;
    else
        outerView.scrollEnabled = YES;
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    if(scrollView == innerView)
    {
         if(innerView.contentOffset.x + innerView.frame.size.width == innerView.contentSize.width)
         {
              outerView.scrollEnabled = NO;
         }
         else
         {
              outerView.scrollEnabled = YES;
         }
    }
}
于 2013-03-15T16:48:02.040 回答
2

我有一个类似的问题。我找到了解决方案,但它仅适用于innerScrollView.bounces = NO.

@interface PageCtrl ()
    @property (weak, nonatomic) IBOutlet UIScrollView *innerScrollView;
    @property(nonatomic) UIPanGestureRecognizer *panLockScroll;
@end

@implementation PageCtrl
- (void)viewDidLoad {
    // ...
    self.innerScrollView.delegate = self;   

    self.innerScrollView.bounces = NO;   // disable bounces!

    self.panLockScroll = [[UIPanGestureRecognizer alloc]initWithTarget:self action:nil];
    self.panLockScroll.delegate = self;
    [self.innerScrollView addGestureRecognizer:self.panLockScroll];
}

- (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer*)otherGestureRecognizer{
    if( gestureRecognizer == self.panLockScroll && 
        otherGestureRecognizer == self.innerScrollView.panGestureRecognizer ){
        return YES;
    }
    return NO;
}

@end
于 2016-07-10T20:36:19.943 回答
1

这对我很有效:

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
  outerScrollView.scrollEnabled = NO;
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
  [NSTimer scheduledTimerWithTimeInterval:0.3
                                     target:[NSBlockOperation blockOperationWithBlock:^{ outerScrollView.scrollEnabled = YES; }]
                                   selector:@selector(main)
                                   userInfo:nil
                                    repeats:NO];
}

请记住在您的类声明中采用 UIScrollViewDelegate 并将 innerScrollView 的委托设置为 self(不要分配 outerScrollView 的委托)

于 2015-03-10T00:26:06.923 回答