UIScrollView dentro de UIScrollView
Tengo un UIScrollView
con otro UIScrollView
dentro. Ambos se desplazan horizontalmente y tienen pagingEnabled = YES
.
Supongamos que comencé a desplazarme por la vista de desplazamiento interior y alcancé el límite más a la derecha. Y si continúo desplazándome en él, entonces la vista de desplazamiento exterior comienza a moverse. Necesito evitar esto. Vista interior debe saltar con efecto de banda de goma, exterior debe permanecer en su lugar.
Espero que esté claro, pero aquí hay un bosquejo:
He tratado de establecer outerView.scrollEnabled = NO;
así:
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
outerView.scrollEnabled = NO;
}
, y funciona exactamente como necesito, si para desplazarse solo en innerView. OuterView ya no se desplaza. Pero tengo que configurar scrollEnabled
de nuevo a SÍ en algún lugar para el caso si quisiera volver a desplazarme hacia fuera.
He tratado de hacerlo aquí:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
outerView.scrollEnabled = YES;
}
, pero que estoy recibiendo el mismo problema: después de alcanzar el límite más correcto de Inerview pergaminos outerView en lugar de saltos Inerview con efecto de banda de goma.
Alguna sugerencia de cómo resolver un problema?
4 answers
ACTUALIZACIÓN
Esta solución funciona siempre:
@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
-----------------------------------------------------------------------
VIEJA RESPUESTA: no funciona siempre
Así es como resolví el problema:
@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;
}
Según tengo entendido, self.delaysContentTouches = NO;
hace que todos los eventos se entreguen inmediatamente, y - (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view
previene el paso de estos eventos por la cadena de respuesta.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-29 16:10:11
Modifique sus métodos de la siguiente manera:
- (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;
}
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-03-15 16:48:02
Tengo un problema similar. Encontré la solución, pero solo funciona con 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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-10 20:36:19
Esto funciona bien para mí:
- (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];
}
Recuerde adoptar UIScrollViewDelegate en su declaración de clase y establecer el delegado de innerScrollView en self (no asigne el delegado de outerScrollView)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-10 00:26:06