IOS: gesture recognizer for smooth scrolling and viewing

I am creating an iPad application where I needed to enable resizing of the presentation functions using the separator view between the two views. The separator view is just a 20-fold view of the height between two representations of half-screen content - see the attached images.

When the user scrolls this view of the separator up or down, both views of the content resize accordingly. I extended UIView and implemented this using the touchMoved delegate as the code below in the touchesMoved delegate. It is working fine. The only thing missing in touchMoved is that you cannot directly switch to split mode from the top or bottom. You have to drag to the top or bottom!

To support the click of a view that I tried UIPanGestureRecognizer , but I do not see a smooth drag and drop in it. Setting the parent's split-position resizes both content views, as shown in the code. When I handle the split position change in the UIGestureRecognizerStateChanged state, just touching the separator view, move it up or down. The handling of position changes in UIGestureRecognizerStateEnded does the same, but I don't see the resizing of the content using diverview scroll!

Can someone please tell me how I can achieve both smooth scrolling of a divider view with resizing content views (for example, touchMoved ), and by clicking? Any alternative approach would also be great. Thanks.

 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObject]; if (touch) { CGPoint lastPt = [touch previousLocationInView:self]; CGPoint pt = [touch locationInView:self]; float offset = pt.y - lastPt.y; self.parentViewController.splitPosition = self.parentViewController.splitPosition + offset; } } - (void)handlePan:(UIPanGestureRecognizer*)recognizer { CGPoint translation = [recognizer translationInView:recognizer.view]; CGPoint velocity = [recognizer velocityInView:recognizer.view]; if (recognizer.state == UIGestureRecognizerStateBegan) { } else if (recognizer.state == UIGestureRecognizerStateChanged) { // If I change split position here, I don't see smooth scrolling dividerview...it directly jumps to the top or bottom! self.parentViewController.splitPosition = self.parentViewController.splitPosition + translation.y; } else if (recognizer.state == UIGestureRecognizerStateEnded) { // If I change split position here, the same thing happens at end and I don't see my divider view moving with my scrolling and resizing my views. self.parentViewController.splitPosition = self.parentViewController.splitPosition + translation.y; } } 

Start screen

Initial screen

Increased top view size by scrolling through the divider view at the bottom.

Increased top view size by scrolling divider view

The top view is completely hidden, but I need to scroll through the divider view all the way to the top. I want to click on the separator view so that it jumps directly from any position to the top

Top view is totally hidden here but I have to scroll divider view all the way to top. I want to flick the divider view so that it directly goes from any position to top.

+4
source share
1 answer

If you understand correctly, you have two separate problems.

1st: "nonsmooth" drag and drop when using GestureRecognizer. The problem in your code is that you add a translation every time GR calls a processing method. Since the translation is measured continuously, you add a higher value each time it is called (i.e., the first call adds 10 to the split position, 2nd 20th, 3rd, etc.).

To solve this problem, you should set the translation to zero after updating the split position:

 - (void)handlePan:(UIPanGestureRecognizer*)recognizer { CGPoint translation = [recognizer translationInView:recognizer.view]; if (recognizer.state == UIGestureRecognizerStateChanged) { self.parentViewController.splitPosition = self.parentViewController.splitPosition + translation.y; } [recognizer setTranslation:CGPointZero inView:recognizer.view]; } 

2nd: so that the user can click the split position from the top or bottom, you can check the speed in UIGestureRecognizerStateEnded, and if it returns a certain value, instantly set the splitting to the top or bottom.

But it would be more convenient to use the UISwipeGestureRecognizer.

 - (void)handleSwipe:(UISwipeGestureRecognizer *)gr { if (gr.direction == UISwipeGestureRecognizerDirectionUp){ [self.parentViewController moveSplitViewToTop]; } else if (gr.direction == UISwipeGestureRecognizerDirectionDown){ [self.parentViewController moveSplitViewToBottom]; } } 

In this case, it may be required (not sure, maybe not) to require SwipeGR to fail before the PanGR triggers install:

 [panGestureRecognizer requireGestureRecognizerToFail:swipeGestureRecognizer]; 

Hope this helps.

Edit: Regarding your comment, I assume that by frequency you mean speed. If you use PanGR, you can change the code above to sth. eg:

 - (void)handlePan:(UIPanGestureRecognizer*)recognizer { CGPoint translation = [recognizer translationInView:recognizer.view]; CGPoint velocity = [recognizer velocityInView:recognizer.view]; if (recognizer.state == UIGestureRecognizerStateChanged) { self.parentViewController.splitPosition = self.parentViewController.splitPosition + translation.y; } else if (recognizer.state == UIGestureRecognizerStateEnded){ if (velocity.y > someValue){ [self.parentViewController moveSplitViewToBottom]; } else if (velocity.y < someValue){ [self.parentViewController moveSplitViewToTop]; } } [recognizer setTranslation:CGPointZero inView:recognizer.view]; } 

I am not sure if the speed is signed, if not, you need to check the translation in the if-block.

+7
source

Source: https://habr.com/ru/post/1439328/


All Articles