iOS的scrollView属性directionalLockEnabled的问题修正

感谢公司的QA发现这个问题,感谢stockoverflow的高手提出解决方案,感谢公司的大大实现了具体的代码

这个问题是我负责的,但是我没有能力解决,所以要声明的是,这篇文章是我的原创,但是有很多人的劳动成果在里面,之所以放上来是因为在中文材料中还没有关于这个问题的解决方案,算是填补空白吧——————————顺便吐槽下挑剔到变态的客户 ^_^

~~~~~~~~~~~~~~~~~~~~~惭愧的分割线~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

scrollView中的directionalLockEnabled的功能本来就是用来让用户每次只在一个方向上滚动,竖直或者水平,但是如果初始移动方向处于45°左右的时候,这个锁就失效了。苹果官方发现了这个问题,在官方文档里有如下描述,但是没有解决:

"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"

很操蛋,对吧。

这是stackoverflow上的讨论,http://stackoverflow.com/questions/728014/uiscrollview-paging-horizontally-scrolling-vertically 

我试了几个有的没效果,公司大大实现了其中的一个,很牛逼啊。这样做就完全使scollView在一次运动中只能在一个方向上。

核心代码如下:

@property (nonatomic) CGPoint scrollViewStartPosPoint;
@property (nonatomic) int     scrollDirection;

@synthesize scrollViewStartPosPoint = _scrollViewStartPosPoint;
@synthesize scrollDirection = _scrollDirection;

- (id)initWithFrame:(CGRect)frame
{
     _scrollDirection = 0;
}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView 
{ 
    if (self.scrollDirection == 0){//we need to determine direction
        //use the difference between positions to determine the direction.
        if (abs(self.scrollViewStartPosPoint.x-scrollView.contentOffset.x)<
            abs(self.scrollViewStartPosPoint.y-scrollView.contentOffset.y)){
            //Vertical Scrolling
            self.scrollDirection = 1;
        } else {
            //Horitonzal Scrolling
            self.scrollDirection = 2;
        }
    }
    //Update scroll position of the scrollview according to detected direction.
    if (self.scrollDirection == 1) {
        scrollView.contentOffset = CGPointMake(self.scrollViewStartPosPoint.x,scrollView.contentOffset.y);
    } else if (self.scrollDirection == 2){
        scrollView.contentOffset = CGPointMake(scrollView.contentOffset.x,self.scrollViewStartPosPoint.y);
    }
}

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView 
{
    self.scrollViewStartPosPoint = scrollView.contentOffset;
    self.scrollDirection = 0;
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate 
{
    if (decelerate) {
        self.scrollDirection =0;
    }
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView 
{
    self.scrollDirection =0;
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesBegan:touches withEvent:event]; // always forward touchesBegan -- there's no way to forward it later
//    if (_isHorizontalScroll)
//        return; // UIScrollView is in charge now
//    if ([touches count] == [[event touchesForView:self] count]) { // initial touch
//        _originalPoint = [[touches anyObject] locationInView:self];
//        _currentChild = [self honestHitTest:_originalPoint withEvent:event];
//        _isMultitouch = NO;
//    }
//    _isMultitouch |= ([[event touchesForView:self] count] > 1);
//    [_currentChild touchesBegan:touches withEvent:event];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
     [super touchesMoved:touches withEvent:event];
//    if (!_isHorizontalScroll && !_isMultitouch) {
//        CGPoint point = [[touches anyObject] locationInView:self];
//        if (fabsf(_originalPoint.x - point.x) > kThresholdX && fabsf(_originalPoint.y - point.y) < kThresholdY) {
//            _isHorizontalScroll = YES;
//            [_currentChild touchesCancelled:[event touchesForView:self] withEvent:event]
//        }
//    }
//    if (_isHorizontalScroll)
//        [super touchesMoved:touches withEvent:event]; // UIScrollView only kicks in on horizontal scroll
//    else
//        [_currentChild touchesMoved:touches withEvent:event];
}


你可能感兴趣的:(iOS,编程技巧)