iOS的scrollView属性directionalLockEnabled的问题修正
2014-01-09 00:13
344 查看
感谢公司的QA发现这个问题,感谢stockoverflow的高手提出解决方案,感谢公司的大大实现了具体的代码
这个问题是我负责的,但是我没有能力解决,所以要声明的是,这篇文章是我的原创,但是有很多人的劳动成果在里面,之所以放上来是因为在中文材料中还没有关于这个问题的解决方案,算是填补空白吧——————————顺便吐槽下挑剔到变态的客户 ^_^
~~~~~~~~~~~~~~~~~~~~~惭愧的分割线~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
scrollView中的directionalLockEnabled的功能本来就是用来让用户每次只在一个方向上滚动,竖直或者水平,但是如果初始移动方向处于45°左右的时候,这个锁就失效了。苹果官方发现了这个问题,在官方文档里有如下描述,但是没有解决:
"If this property is
scrolling is permitted in both horizontal and vertical directions. If this property is
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
很操蛋,对吧。
这是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];
}
这个问题是我负责的,但是我没有能力解决,所以要声明的是,这篇文章是我的原创,但是有很多人的劳动成果在里面,之所以放上来是因为在中文材料中还没有关于这个问题的解决方案,算是填补空白吧——————————顺便吐槽下挑剔到变态的客户 ^_^
~~~~~~~~~~~~~~~~~~~~~惭愧的分割线~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
scrollView中的directionalLockEnabled的功能本来就是用来让用户每次只在一个方向上滚动,竖直或者水平,但是如果初始移动方向处于45°左右的时候,这个锁就失效了。苹果官方发现了这个问题,在官方文档里有如下描述,但是没有解决:
"If this property is
NO,
scrolling is permitted in both horizontal and vertical directions. If this property is
YESand
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开发系列】scrollView中的directionalLockEnabled
- iOS: UIScrollView的属性directionalLockEnabled
- iOS: ARC和非ARC下使用Block属性的问题
- iOS中ScrollView的属性和方法详解
- ios开发中button控件的属性及常见问题
- springboot+maven打jar包运行java -jar,报错没有主清单属性;pom文件添加build修正问题
- iOS: ARC和非ARC下使用Block属性的问题
- 修正android cocos2dx项目当点击属性时提示错误的问题
- 【iOS开发-55】图片轮播案例:scrollView的分页、滚动条、利用代理控制定时器和Page Control以及多线程问题
- IOS-1-Objective-C-@property属性的使用及注意问题:@property(assign)int name;
- ScrollView 嵌套 ListView or ExpandableListView显示问题(一行属性搞定)
- 20160917iOS音频开发之资源(AVAsset)与元数据,解决获取资源属性问题(二)
- iOS CocoaPods iOS 'The sandbox is not sync with the Podfile.lock'问题解决
- iOS ScrollView属性介绍
- iOS:UIWebView scrollView 的分页滑动问题
- iOS:UIWebView scrollView 的分页滑动问题
- 关于使用iOS scrollView进行图片浏览的坐标问题
- 使用ScrollView属性fillViewport解决android布局不能撑满全屏的问题
- 使用ScrollView属性fillViewport解决android布局不能撑满全屏的问题
- 关于iOS11下关于UIViewController属性弃用导致含有ScrollView功能的控件出现问题的解决方案