UIScrollView внутри UIScrollView
У меня есть UIScrollView
с другим UIScrollView
внутри. Оба они прокручиваются по горизонтали и имеют pagingEnabled = YES
.
Предположим, что я начал прокручивать внутренний вид прокрутки и достиг самой правой границы. И если я продолжу прокрутку в нем, тогда внешний scrollView начнет двигаться. Мне нужно избегать этого. Внутренний вид должен прыгать с резиновым эффектом, внешний должен оставаться на нем.
Надеюсь, что это понятно, но вот эскиз:
![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 во внешнем виде вместо переходов innerView с эффектом резинкой.
Любые предложения по решению проблемы?
Ответы
Ответ 1
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 ANSWER: не работает всегда
Вот как я решил проблему:
@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
предотвращает передачу этих событий по цепочке ответчиков.
Ответ 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;
}
}
}
Ответ 3
Это хорошо работает для меня:
- (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 для себя (НЕ назначайте делегат внешнегоScrollView)
Ответ 4
У меня подобная проблема. Я нашел решение, но оно работает только с 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