将特定的触摸事件通过UIScrollView传递到底层视图

11
我有一个视图,其中包含两个子视图:
  1. Subview A, 一个 UIView(包含其他视图,其中包括带有手势识别器的 UIButtons 和 views...)
  2. Subview B, 一个 UIScrollView(包含一些视图,但有透明区域)。
滚动视图位于 Subview A 的上方,宽度/高度与设备相同。我希望用户能够通过滚动视图下方的透明区域与所有按钮和手势识别器进行交互,同时仍然能够滚动(所以传递hittest是不行的)。
看起来很简单,但我无法让它工作。滚动视图总是阻止所有触摸事件。
你有任何想法如何实现这一点吗?谢谢!

为什么滚动视图首先会覆盖其他视图? - GuybrushThreepwood
滚动视图中的视图需要重叠在下面的视图上方。 - René
3个回答

16
你应该创建UIScrollView的子类并重写下面的方法:
-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event

如果这个方法返回NO,那么滚动视图将对触摸事件“透明”。

如果你希望滚动视图仅在触摸处于滚动视图的透明区域时才“透明”,那么你的实现应该如下所示:

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
     return ![self isPointInsideATransparentRegion:point]; //you need to implement isPointInsideATransparentRegion to check whether the point touched is in a transparent region or not
}

3
如果用户只在实心区域上滚动,则此方法可行。但是,在透明区域进行平移手势时,仍应使ScrollView滚动。 - René

2

我现在已经有点解决这个问题了,我将原本应该在滚动视图下方的视图添加到滚动视图中作为第一个子视图,并在scrollViewDidScroll:方法中调整它的位置。

-(void)scrollViewDidScroll:(UIScrollView *)scrollView {
    [self updateBottomViewPosition];
}

- (void)updateBottomViewPosition {
    CGPoint contentOffset = _mainScrollView.contentOffset;

    CGFloat y = MAX(contentOffset.y, 0);

    CGRect frame = _bottomPage.frame;
    if (y != frame.origin.y) {
        frame.origin.y = y;
        _leadPage.frame = frame;
    }
}

这个方法可以运行,但可能不够优雅。


正是我正在寻找的解决方案。遗憾的是IOS没有提供更简单的方法。不过,这比实现轻拍手势更加清晰。 - htafoya

0

基于René的答案,如果背景视图固定(例如在视图顶部),并且底部滚动具有反弹效果,则此方法有效。

#pragma mark - Scroll delegate

-(void)scrollViewDidScroll:(UIScrollView *)scrollView {
    [self updateBottomViewPosition];
}

- (void)updateBottomViewPosition {
    CGPoint contentOffset = self.scrollView.contentOffset;

    CGFloat y = MAX(contentOffset.y, 0);


    CGRect frame = self.fixedView.frame;
    if (y > 0) {
        frame.origin.y = y;
    } else {
        frame.origin.y = 0;
    }
    self.fixedView.frame = frame;
}

你可以使用这个来创建一个漂亮的视差效果,如果你不想它固定,你应该将y值改为你想要的过渡运动。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接