Allow interactivity in UIScroolView and prevent interaction with content inside it as it scrolls

2

Is there any way to prevent user interaction with content within a UIScrollView?

I have a the ScrollView contains UIViews inside it.
In these UIviews contains only one object, UIImage.

UIScroolView
 ||
\  /
 \/
----------------------------------------------------------------
          ______    ______
         |      |  |      |
         |      |  |      |   <-- UIview com imagem dentro
         |______|  |______|

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

I want to allow the user to interact with the UIScrollView so that they can scroll from side to side, but while it is rolling, it can not interact with objects inside (the images). Images have a drag'n drop event attached.

The touch and drag effect can only start if the scroll is stopped.

So far, it works as expected, but interactivity with the scroll is disabled for this to happen because I do not know a way to disable only content from within UIScrollView.

I am applying userInteractionEnabled and this disables the interaction completely while it is rolling. When it finishes scrolling, userInteractionEnabled is set to YES .

- (void)scrollInteractionEnabled:(bool)val :(UIScrollView *)sender
{

    /*
    O objeto UIScrollView está setado como objeto.delegate = self
    */

    //  Esse está e uso e funciona bem.
    // O problema é que fica desativado por completo, não permitindo rolar
    sender.userInteractionEnabled = val;

    /*
    Algumas combinações que tentei, sem sucesso
    */
    //sender.multipleTouchEnabled = YES;         //sender.scrollEnabled = YES;
    //sender.canCancelContentTouches = YES;
}


/*
Os métodos abaixo capturam eventos de rolagem, especificamente quando desacelera e quando para.
Isso é necessário para reverter o valor de userInteractionEnabled
*/
- (void)scrollViewDidScroll:(UIScrollView *)sender{
    [self scrollInteractionEnabled:NO:sender];
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    //[super scrollViewDidEndDragging:scrollView willDecelerate:decelerate];
    if(!decelerate) {
        [self scrollInteractionEnabled:YES:scrollView];
    }
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    [self scrollInteractionEnabled:YES:scrollView];
}

- (void)scrollViewDidScrollToTop:(UIScrollView *)scrollView
{
    [self scrollInteractionEnabled:YES:scrollView];
}

- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
{
    [self scrollInteractionEnabled:YES:scrollView];
}

Something that seems closest to solving is [objeto_scroll setCanCancelContentTouches:YES] . Obviously I tested it and it did not work.

I also consider using some library, class, or whatever is functional. The reason for all this is the class I use has a bug that when you touch an object within the scroll while it is rolling, the drag effect is not detected. Only the touch event runs.

[edit]

Solved by @MarioKlein's tip

- (void)scrollInteractionEnabled:(bool)val :(UIScrollView *)sender
{
    /*
    Possuo 2 objetos do tipo UIScrollView, por isso foi necessário identifica o Scroll em contexto (onde contém os objetos)
    */
    if (sender == mScrollView) {

        // Itera os objetos de dentro, habilitando e desabilitando a interatividade de cada um individualmente ao invés de aplicar ao UIScrollView.  
        for (UIView* subview in mScrollView.subviews)
        {
            subview.userInteractionEnabled = val;
        }

    } else if (!mScrollView.isDragging || !mScrollView.isDecelerating) {
        // Se o scroll parar de se mover, é habilitada a interatividade nele mesmo. Essa regra ainda continua.
        mScrollView.userInteractionEnabled = YES;
        mScrollView.scrollEnabled = YES;
    }
}
    
asked by anonymous 09.09.2016 / 04:27

1 answer

3

Daniel,

Try to navigate through the [scrollView subviews] views tree and set them all to userInteractionEnabled = false while scrolling. When done, do the inverse ( userInteractionEnabled = true ).

    
14.09.2016 / 21:41