Kokodelo Kokodelo - 6 months ago 30
iOS Question

How to dismiss programmatically the clipsToBounds property when a GestureRecognizer begin?

I have a

UIScrollView
which is able to contains many view. To allow a good scrolling (without the content going outside the view while scrolling), on my
Main.sotryboard
, I've clicked on my
UIScrollView
and then in the attribute inspector I have allowed the
Clip Subviews
property:

The 3rd property is: Clip Subviews

My problem: all the views which are in my
UIScrollViews
are draggable (because they all have a
UIPanGestureRecognizer
.
So, when I try to drag them OUTSIDE my
UIScrollView
, they just disappear.
In fact they're just going behind every other view

To give you an exemple, I have others components which allow the drop of a view form the precedent
UIScrollView
. So when I begin the drag'n'drop from it, it disappear, and then reappear in the second component on which I have dropped the view.

What I have tried: I have a special
UIPanGestureRecognizer
for te drag'n'drop of a view coming from this
UIScrollView
. So, I actually have this (which, obviously, doesn't work, otherwise I would not be here):

//Here recognizer is the `UIPanGestureRecognizer`
//selectpostit is the name of the view I want to drag
if(recognizer.state == UIGestureRecognizerStateBegan){
selectpostit.clipsToBounds = NO;
}


Any Ideas on how I can improve that?
Thanks in advance.

Answer

You could try to reset scrollView.clipsToBounds to NO every time gesture starts, but that would lead to side effect when other content outside scroll view would become visible when dragging is in the progress.

I would recommend to take snapshot of the the draggable view when panning starts, place it on the scrollview's parent, and move it. Such approach should solve your problem.

Here is the code:

- (void)onPanGesture:(UIPanGestureRecognizer*)panRecognizer
{
    if(panRecognizer.state == UIGestureRecognizerStateBegan)
    {
        //when gesture recognizer starts, making snapshot of the draggableView and hiding it
        //will move shapshot that's placed on the parent of the scroll view
        //that helps to prevent cutting by the scroll view bounds
        self.draggableViewSnapshot = [self.draggableView snapshotViewAfterScreenUpdates: NO];
        self.draggableView.hidden = YES;
        [self.scrollView.superview addSubview: self.draggableViewSnapshot];
    }

    //your code that updates position of the draggable view

    //updating snapshot center, by converting coordinates from draggable view
    CGPoint snapshotCenter = [self.draggableView.superview convertPoint:self.draggableView.center toView: self.scrollView.superview];
    self.draggableViewSnapshot.center = snapshotCenter;

    if(panRecognizer.state == UIGestureRecognizerStateEnded ||
       panRecognizer.state == UIGestureRecognizerStateCancelled ||
       panRecognizer.state == UIGestureRecognizerStateFailed)
    {
        //when gesture is over, cleaning up the snapshot
        //and showing draggable view back
        [self.draggableViewSnapshot removeFromSuperview];
        self.draggableViewSnapshot = nil;
        self.draggableView.hidden = NO;
    }
}
Comments