I\'m new in objective-c. I create UIScrollView
object and add in my view with this code:
height = self.view.frame.size.height;
width = self.view.fra
If i understood you right, you want to disable scrolling in the direction that has been dragged less by the user. If so, UIScrollView already offers an option to do so:
scrollView.directionalLockEnabled = YES;
When this option is set to true UIScrollView will handle the correct direction lock by itself.
For more information look at the documentation: link
You can achieve the result you want adding some code to your delegate. This is my ViewController.m
file. -viewDidLoad
, #import
statements and the other methods are omitted.
@interface ViewController () {
CGPoint initialOffset;
NSInteger direction; // 0 undefined, 1 horizontal, 2 vertical
}
@end
@implementation ViewController
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
// retrieve current offset
CGPoint currentOffset = scrollView.contentOffset;
// do we know which is the predominant direction?
if (direction == 0) {
// no.
CGFloat dx = currentOffset.x - initialOffset.x;
CGFloat dy = currentOffset.y - initialOffset.y;
// we need to decide in which direction we are moving
if (fabs(dx) >= fabs(dy)) {
direction = 1; // horizontal
} else if (fabs(dy) > fabs(dx)) {
direction = 2;
}
}
// ok now we have the direction. update the offset if necessary
if (direction == 1 && currentOffset.y != initialOffset.y) {
// remove y offset
currentOffset.y = initialOffset.y;
// update
[scrollView setContentOffset:currentOffset];
} else if (direction == 2 && currentOffset.x != initialOffset.x) {
currentOffset.x = initialOffset.x;
[scrollView setContentOffset:currentOffset];
}
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
// store the current offset
initialOffset = scrollView.contentOffset;
// reset flag
direction = 0; // AKA undefined
}
@end
When you start dragging, the delegate will reset the flag direction
to "unknown" state, and store the current content offset. After every dragging move, your -scrollViewDidScroll:
will be called. There, you decide which is the predominant direction (if this hasn't been done yet) and correct the current scrolling offset accordingly, by removing the x (or y) offset.
I tested this with the same settings you provided, only I used a UIImageView
inside UIScrollView
and I set up everything via InterfaceBuilder, but it should work fine. Theoretically, with this method you could replace directionLock
, but remember that -scrollViewDidScroll
is called many times during an action, and every time it rewrites the content offset (if the scrolling is happening in both directions). So if you leave directionLock
enabled, you save many of the calls to setContentOffset:
that the delegate performs.