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;
}

、しかし、私は同じ問題を抱えています。

問題を解決する方法について何か提案はありますか?

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 のデリゲートを自分自身に設定することを忘れないでください (outerScrollView のデリゲートを割り当てないでください)。

于 2015-03-10T00:26:06.923 に答える