2
votes

I am developing an app in which I have to drag UIImageview from UIScrollview. At the bottom part of my main UIView, I've an UIScrollView with UIImageViews inside. I have created custom UIScrollview using following code snippet:

@interface CustomScroll : UIScrollView {

}@end


@implementation CustomScroll


- (id)initWithFrame:(CGRect)frame {
return [super initWithFrame:frame];

}

- (void) touchesMoved: (NSSet *) touches withEvent: (UIEvent *) event { 
// If not dragging, send event to next responder
if (!self.dragging) {
    self.scrollEnabled=NO;
    [self.nextResponder touchesMoved:touches withEvent:event]; 

}
else{
    [super touchesMoved: touches withEvent: event];
}

}

- (void) touchesEnded: (NSSet *) touches withEvent: (UIEvent *) event { 
// If not dragging, send event to next responder
if (!self.dragging)
    [self.nextResponder touchesEnded: touches withEvent:event]; 
else
    [super touchesEnded: touches withEvent: event];
}
@end

From here I have included a CustomScroll object in my PuzzleViewController and connect it to the scrollview of Interface builder:

@interface PuzzleViewController : UIViewController <UIScrollViewDelegate> {
    IBOutlet CustomScroll *segmentScrollview;

}

I've added all UIImageviews programmatically.

This code is working as expected. UIImageview detecting touch and I can drag UIImageview from UIScrollview to UIView.

But problem occurs when I drag UIImageview diagonally.

In my app when I drag UIImageview vertically from scrollview I'm able to move my UIImageView from the UIScrollView to the UIView. But when I drag UIImageview diagonally from scrollview I can not move UIImageview. Diagonal swipe scrolls UIScrollview [UIImageview remains untouched] which is unexpected. I want UIImageview should be drag diagonally from UIScrollview.

Any help would be greatly appreciated.

Thanks in advance for any help.

3

3 Answers

1
votes

This is just a thought...so try it out and tell me how it goes. If doesn't work then I'll try and help you out further. Try setting directionalLockEnabled to NO. If it is set to YES then your movement will be restricted to horizontal/vertical only. If it is set to NO then you should be able to move diagonally. Try it out and let me know how it goes.

UIScrollView directionLockEnabled Docs

If this property is NO, scrolling is permitted in both horizontal and vertical directions. If this property is YES and the user begins dragging in one general direction (horizontally or vertically), the scroll view disables scrolling in the other direction. If the drag direction is diagonal, then scrolling will not be locked and the user can drag in any direction until the drag completes. The default value is NO

0
votes

i am thinking that what you are after is not [super touchesMoved:...], but rather [self.superview touchesMoved:...] ... assuming you have the superview containing both the CustomScroll and the other view that you are attempting to drag into set up to deal with this.

0
votes

I know this is an older question, but I just ran into this problem as well. Basically I wanted a paging enabled scrollview which would go either up, down, left, or right. Using the pagingEnabled and directionalLockEnabled variables made it basically work, except for the diagonal drag. My solution is below.

    - (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    if (self.scrollView.contentOffset.x >= self.previousScrollOffset.x &&
        self.scrollView.contentOffset.y == self.scrollView.contentSize.height / 3){

        self.currentScrollDirection = SW_DIRECTION_LEFT;

    } else if (self.scrollView.contentOffset.x < self.previousScrollOffset.x &&
               self.scrollView.contentOffset.y == self.scrollView.contentSize.height / 3){

        self.currentScrollDirection = SW_DIRECTION_RIGHT;

    } else if (self.scrollView.contentOffset.x == self.scrollView.contentSize.width / 3 &&
         self.scrollView.contentOffset.y >= self.previousScrollOffset.y){

        self.currentScrollDirection = SW_DIRECTION_UP;

    } else if (self.scrollView.contentOffset.x == self.scrollView.contentSize.width / 3 &&
         self.scrollView.contentOffset.y <= self.previousScrollOffset.y){

        self.currentScrollDirection = SW_DIRECTION_DOWN;

    } else {

        self.currentScrollDirection = SW_DIRECTION_NONE;

    }

    //lock to either horizontal or vertical if we are dragging (prevent the diagonal drag)
    if (self.scrollView.isTracking && self.currentScrollDirection == SW_DIRECTION_NONE){
        self.scrollView.contentOffset = CGPointMake(self.scrollView.contentOffset.x, self.scrollView.contentSize.height / 3);
    }

    self.previousScrollOffset = scrollView.contentOffset;
}

This forces any diagonal swipes to lock the scrolling on the horizontal plane, which worked well for me because horizontal dragging was a priority, so The only way to scroll up or down would be to swipe exactly up or down.

For this to work you will need to declare

@property (readwrite, nonatomic) SW_SCROLL_DIRECTION currentScrollDirection;
@property (readwrite, nonatomic) CGPoint previousScrollOffset;

and

typedef enum {
SW_DIRECTION_NONE,
SW_DIRECTION_LEFT,
SW_DIRECTION_RIGHT,
SW_DIRECTION_UP,
SW_DIRECTION_DOWN

} SW_SCROLL_DIRECTION;

Note. This probably wont work out of the box, as you see I hardcode a value of 3 pages. This is because I have content always centred, so you can either scroll one page in any direction, then it will animate back to the centre. It shouldn't be to hard to modify to work with multiple pages.