当外部视图缩放时,嵌套的 UIScrollView 不会滚动

发布于 2024-10-16 18:08:39 字数 908 浏览 1 评论 0原文

嵌套 UIScrollViews 时我遇到了很大的问题。

我有一个外部分页滚动视图,它使用它的 UIScrollView 子视图进行分页滚动。这些子视图包含一个带有大图像的 CALayer 的子视图。无论何时需要,这个 CALayer 子视图都可以添加小的滚动视图,充当小图片库。这些画廊有自己的视图控制器,称为 SlideViewController。

查看
|
v
主滚动视图
|
v
UIScrollView(页面)
|
v 使用 CALayer 查看
|
v
ScrollView 就像画廊。

一切都像魅力一样,直到 ipad 旋转到横向并且页面滚动视图缩放 33%。

所有子视图都在其位置上。它们的边界是正确的,它们的框架也是正确的。问题是,当我在小画廊上滑动时,它们不再滚动。大页面确实如此。 我尝试将所有涉及的滚动视图的 canCancelContentTouches 设置为 NO。

我还对图库滚动视图进行了子类化,以获取 TouchEnded/began/cancelled 的控制,并尝试从那里禁用超级视图滚动,但没有成功。

当我调用 init 时,我尝试将画廊设置为第一响应者。没有进一步的结果。

现在,只有当我将手指放在画廊上一段时间时,我才能滚动画廊,因此没有手势识别器会窃取它们的滑动,然后轻轻滚动到画廊的下一张图片。

如果我正常滑动,有时大的外部滚动视图会窃取滑动并更改页面,有时小画廊会先捕获它。

只有当包含 CA 层(页面)的滚动视图被缩放时才会发生这种情况,否则效果会非常好,不会出现任何问题。

我搞砸了 UIResponder 链吗?我该如何解决这个问题?

我可以向您粘贴一些代码片段,但这涉及到一些类,我不知道哪些类有用或无用。

提前致谢

I'm having quite a problem here when nesting UIScrollViews.

I have an outter paged scroll view, that does paged scrolling with it's UIScrollView subviews. These subviews contain a subview that have a CALayer with a big image. Whenever is needed this CALayer subviews can be have small scrollview added to them that act as small picture galleries. These galleries have their own viewcontroller called SlideViewController.

view
|
v
mainScrollView
|
v
UIScrollView (page)
|
v
view with CALayer
|
v
ScrollView like gallery.

Everything works like a charm until the ipad is rotated to landscape and the page scroll view is zoomed a 33%.

All of the subviews are in their place. their bounds are correct, so as their frame. The thing is that when I swipe over the little galleries they don't scroll any more. The big page does.
I've tried setting canCancelContentTouches to NO to all of the involved scrollviews.

I also subclassed the gallery scroll view to get a grip on the touchesEnded/began/cancelled and try to disable the super view scrolling from there with no success.

I tried to set the galleries as a first responder when I called init on them. With no further results.

Now I can scroll the galleries only if I put my finger for a while on them, so no gesture recognizer steals the swipe from them, and then scroll gently to the next picture of the gallery.

If I swipe normally, sometimes the big outter scrollview would steal the swipe and change the page, and sometimes the little gallery would catch it first.

this only happens when the scrollview containing the CA layer (the page) is zoomed otherwise works amazingly great with no issues what so ever.

Am I screwing the UIResponder chain? How could I fix this?

I could paste you some code snippets, but this involves a handful of classes, that I don't know which ones could be of use or not.

Thanks in advance

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

温柔嚣张 2024-10-23 18:08:39

我会回答我自己的问题,以防万一有人遇到这个问题。

首先阅读 ---> 这个

其次,发生了什么?现在,外部和内部滚动视图正在努力争取每次触摸屏幕时调度的触摸事件。由于像滑动识别器这样的手势识别器需要一些时间来识别外部视图的滑动子视图,同时可以捕获触摸,这会导致当您在内部视图中进行滚动时,有时可以工作,有时则不行。

我所做的是对响应者链中涉及的视图进行子类化。不是全部。只是最里面和最外面,实际上是第一响应者。

在第一响应者子类(在我的例子中是 UIView)中覆盖命中测试。我从这个问题中得到了代码片段和想法: 如何从 UIScrollView 窃取触摸?< /a>

- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    UIView* result = [super hitTest:point withEvent:event];

    if ([result.superview isKindOfClass:[SlideView class]])
    {
        self.scrollEnabled = NO;
    }
    else 
    {
        self.scrollEnabled = YES;    
    }
    return result;
}

为什么?因为您想禁用外部视图的滚动。这就是它的滑动识别器将被禁用的方式,并且将让您的内部滚动视图保持独立,并在需要时自由地抓住触摸。这也有助于使用户的滚动更加准确。

出色地。祝你好运。我要承诺这一点。 ;-)

I'll answer my own question just in case someone comes across this.

Firstly READ ---> this

Secondly what's going on right now is that the outter and inner scrollviews are struggling for the touch events being dispatched everytime you touch the screen. Since gesture recognizers like swipe recognizers take some time to recognize a swipe subviews of the outter view can catch the touches in the meantime, that causes that when you do the scrolling in the inner views some times it works and some times doesn't.

What I did was to subclass the views involved in the responder chain. Not all of them. just the inner-most and the outter-most which is actually the first responder.

In the first responder subclass (in my case is an UIView) override hit test. I got the code snippet and the idea from this question: How to steal touches from UIScrollView?

- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    UIView* result = [super hitTest:point withEvent:event];

    if ([result.superview isKindOfClass:[SlideView class]])
    {
        self.scrollEnabled = NO;
    }
    else 
    {
        self.scrollEnabled = YES;    
    }
    return result;
}

WHY? Because you want to disable scrolling from the outter views. That's the way it's swipe recognizers will be disabled and will leave your inner scrollview alone and free to grab the touches whenever it feels like it. This also contributes making scrolling more accurate for the user.

Well. Good luck. I'm going to commit this. ;-)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文