简体   繁体   English

通过UIScrollView将某些触摸传递给基础视图

[英]Pass certain touches through UIScrollView to underlying views

I've got a view that has two subviews: 我有一个有两个子视图的视图:

  1. Subview A, a UIView (contains other views, which contain UIButtons, views with gesturerecognizer ...) 子视图A,UIView(包含其他视图,包含UIButtons,带有手势识别器的视图......)
  2. Subview B, a UIScrollView (contains some views, but has transparent regions). 子视图B,UIScrollView(包含一些视图,但具有透明区域)。

The scrollview is on top of Subview A and has the full device width/height. 滚动视图位于子视图A的顶部,并具有完整的设备宽度/高度。 I want the user to be able to interact - through the transparent regions - with all those buttons and gesture reconizers below the scrollview, while still being able to scroll (so passing on the hittest is out). 我希望用户能够通过透明区域与滚动视图下方的所有按钮和手势重新配置器进行交互,同时仍然能够滚动(因此传递最小的测试结果)。

Seems like an easy enough task, but I can't get it to work. 看起来像一个足够简单的任务,但我无法让它工作。 The scrollview is always blocking all touches. 滚动视图始终阻止所有触摸。

Any idea how I would accomplish that? 知道如何实现这一目标吗? Thanks! 谢谢!

You should subclass the UIScrollView and overwrite the following method: 您应该继承UIScrollView并覆盖以下方法:

-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event

If this method returns NO the scrollview will be "transparent" for touch events. 如果此方法返回NO,则对于触摸事件,scrollview将是“透明的”。

As you want the scrollview to be "transparent" for touch events only if the touch is in a transparent area of your scrollview, your implementation should look like: 如果您希望滚动视图对于触摸事件是“透明的”,仅当触摸位于滚动视图的透明区域时,您的实现应如下所示:

- (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
}

I've somewhat solved this now by adding the view that's supposed to be below the scrollview to the scrollview as the first subview, and shifting its position in scrollViewDidScroll: 我现在已经解决了这个问题,方法是将滚动视图下方的视图添加到scrollview作为第一个子视图,并在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;
    }
}

This works, but it's probably not as elegant as possible. 这有效,但它可能不尽如人意。

Based in René's answer, this works if the background view is fixed (fe at the top of the view) and the bottom scroll has bounce. 根据René的答案,如果背景视图固定(视图顶部为fe)并且底部滚动有弹跳,则此方法有效。

#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;
}

You can use this to create also a nice paralax effect, if you don't want it to be fixed you should change the y value to your wanted transition movement. 您可以使用它来创建一个漂亮的paralax效果,如果您不希望它被修复,您应该将y值更改为您想要的过渡运动。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM