2013-03-15 2 views
23

У меня есть UIScrollView с другим UIScrollView внутри. Оба они прокручиваются по горизонтали и имеют pagingEnabled = YES. Предположим, что я начал прокручивать внутренний вид прокрутки и достиг самой правой границы. И если я продолжу прокрутку в нем, тогда внешний scrollView начнет двигаться. Мне нужно избегать этого. Внутренний вид должен прыгать с эффектом резиновой ленты, внешний должен оставаться на своем месте.UIScrollView внутри UIScrollView

Надеется, что это понятно, но вот эскиз: enter image description here

Я попытался установить outerView.scrollEnabled = NO; так:

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

, и она работает точно так, как мне нужно, если прокручивать только в innerView. OuterView больше не прокручивается. Но я должен установить scrollEnabled обратно в YES где-нибудь в этом случае, если я захочу снова прокрутить внешний вид. Я пытался сделать это здесь:

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

, но чем я получаю ту же проблему: после достижения наиболее правой границы innerView outerView свиток вместо innerView перескакивает с резиновыми зонным эффектом.

Любые предложения по решению проблемы?

+0

в ваших методах делегата scrollview не похоже, что вы проверяете, какой scrollviewViewBeginDragging и какой scrollViewDidEndDecelerating. Я не совсем понимаю ваши потребности, но это не так. – mkral

+0

попробуйте установить тег на каждом прокрутке, затем установите флажок 'if (scrollview.tag == 1) ' – mkral

+0

@mkral: у меня есть разные делегаты для этих просмотров, поэтому мне не нужно проверять параметр. – Anastasia

ответ

17

UPDATE

Это решение работает всегда:

@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 

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

OLD ОТВЕТ: не работает всегда

Вот как я решил эту проблему:

@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 предотвращает прохождение этих событий, цепочку ответчиков.

+0

У меня такая же проблема. Я попробовал ваше решение, но при этом блокирует внешний вид InnerView от любых событий касания. У меня есть несколько кнопок внутри внутреннего scrollview как subviews. Прокрутка работает отлично, но кнопки больше не поддаются обработке. У вас есть другое решение? –

+0

@AlexeyGolikov: Да, это решение очень сложно, и я не уверен, что он работает для каждого случая. Я думаю, сессия WWDC 2013 «Изучение прокрутки на iOS 7» (developer.apple.com/wwdc/videos/index.php?id=217) поможет, а именно демонстрацию, которая начнется в 11:00. К сожалению, я видел это видео намного позже, затем задал этот вопрос и не пытался его реализовать. – Anastasia

+1

Спасибо, @anastasia. К сожалению, видео не помогло мне. Все еще ищет решение. –

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

Спасибо, но проблема в том, что scrollView имеет scrollEnabled == NO; чем - (void) scrollViewWillBeginDragging: (UIScrollView *) scrollView больше не вызвал его. Поэтому я не могу установить scrollEnabled обратно в YES в этом методе. – Anastasia

2

Это хорошо работает для меня:

- (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)

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 
Смежные вопросы