2016-08-11 56 views
1

我正在使用UIScroll View制作具有分页功能的画廊式UI。基本上是这样的:展开UIScrollView交互区域并区分划动和轻敲

enter image description here

因为我需要分页,所以我设置滚动视图的宽度等于单个页面的宽度,在我的例子,粉红色长方形的宽度。

但我想两个额外的东西:

  1. 轻敲黄色或蓝色区域会带来相应的矩形的中心。
  2. 可以在黄色或蓝色区域(滚动视图之外)滚动/滑动,这意味着整个屏幕宽度都可以滚动。

我跟着this thread并添加了- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event但是通过这样做,我只能达到我的第二个目标。当我设置选择器或代表处理黄色和蓝色的点击反应时,它不起作用。有关它的任何想法?

回答

1

That answer you referenced是我的老收藏之一。它没有考虑你的第一个要求,但我认为它只需添加一个轻敲手势识别器就可以非常整齐地处理它。

你的 “ClipView” 创建它:

UITapGestureRecognizer *tapGR = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap:)]; 
[self.myClipView addGestureRecognizer:tapGR]; 
// myClipView is the view that contains the paging scroll view 

- (void)tap: (UITapGestureRecognizer *)gr { 
    // there are a few challenges here: 
    // 1) get the tap location in the correct coordinate system 
    // 2) convert that to which "page" was tapped 
    // 3) scroll to that page 
} 

挑战1)容易多亏了手势识别器,其回答locationInView:

CGPoint location = [gr locationInView:self.scrollView]; 

对于挑战2),我们需要弄清什么点击滚动视图中的页面。这可以通过给定页面宽度的非常简单的算法来完成。

// assuming you have something like this 
#define kPAGE_WIDTH // some float 

// page is just how many page-width's are represented by location.y 
NSInteger page = floor(location.y/kPAGE_WIDTH); 

现在,挑战3)现在很容易因为它滚动位置直线向前,我们可以改变一个网页...

CGFloat y = page * kPAGE_WIDTH; 
[self.scrollView setContentOffset:CGPointMake(y, 0.0f) animated:YES]; 

或者,所有的代码一个大块......

- (void)tap: (UITapGestureRecognizer *)gr { 
    CGPoint location = [gr locationInView:self.scrollView]; 
    NSInteger page = floor(location.y/kPAGE_WIDTH); 
    CGFloat y = page * kPAGE_WIDTH; 
    [self.scrollView setContentOffset:CGPointMake(y, 0.0f) animated:YES]; 
} 

编辑

您可能还需要排除来自手势识别器的“当前页面”区域。这只是通过在tap方法中验证测试来完成的。

唯一的技巧是让抽头位置相同的坐标系作为滚动视图的框架,也就是夹视图中......

CGPoint locationInClipper = [gr locationInView:gr.view]; 

和SDK提供了一个很好的方法来测试。 ..

BOOL inScrollView = [self.scrollView pointInside:locationInClipper withEvent:nil]; 

所以......

- (void)tap: (UITapGestureRecognizer *)gr { 
    CGPoint locationInClipper = [gr locationInView:gr.view]; 
    BOOL inScrollView = [self.scrollView pointInside:locationInClipper withEvent:nil]; 

    if (!inScrollView) { 
     CGPoint location = [gr locationInView:self.scrollView]; 
     NSInteger page = floor(location.y/kPAGE_WIDTH); 
     CGFloat y = page * kPAGE_WIDTH; 
     [self.scrollView setContentOffset:CGPointMake(y, 0.0f) animated:YES]; 
    } 
} 
+0

太谢谢你了!这完美地解决了我的问题,答案设计得非常好。 – mlin956

+0

有没有办法限制轻拍手势识别器正在观察的区域?就像我只想要黄色和蓝色的区域观察它。我知道有一种方法可以计算第2步中的位置...... – mlin956

+0

当然。请参阅编辑。 :-) – danh