将滑动触摸从 UIView 传递到底层 UIScrollView 以实现正确滚动

发布于 2024-10-20 08:11:33 字数 1131 浏览 4 评论 0原文

我的情况与这两篇文章类似(1907297689684)并最简洁地描述我的情况,我呈现此文本/图形布局(类似于您在IB中看到的,用于强制缩进级别的点)

UIView(MainView:320x460 )
。 .UIScrollView(滚动视图:320x460)
。 .UIView(OverlayView:320x40)
。 。 。 .UIButton(任意按钮1)
。 。 。 .UILabel (ArbitraryLabel1)
。 。 。 .UILabel (ArbitraryLabel2)

这里的目标是让 OverlayView 作为一个统一的、透明的容器来在 ScrollView 顶部定位和显示一些任意按钮/标签。这些按钮/标签应保持静止,而下方 ScrollView 中的内容随着用户滑动而移动。按钮/标签有时可能会统一隐藏/取消隐藏/缩放(使用动画),这使得将它们全部分组在单个 OverlayView 中变得很方便。

问题在于,虽然 OverlayView 上的点击似乎很好地直接传输到底层 ScrollView,但滑动动作却没有效果。我可以通过覆盖 OverlayView 中的方法来检测/拦截滑动

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event

,但是我还没有找到一种方法以使其滚动的方式正确地将这些滑动传递到 ScrollView。显然,touchesMoved 方法不是 UIScrollView 用于检测/解释滑动的方法?

我研究过的所有其他类似帖子要么找到了对我的情况不起作用的不同解决方案,要么只是没有解决。我还看到提到使用touchesShouldBegin/touchesShouldCancel,尽管我不明白这是如何实现的。无论如何,仍然希望社区有一些见解可以让我为此提出一个优雅的解决方案 - 任何示例代码都很棒。

预先感谢,乔尔。

PS - 我还应该提到,我需要使其与 iOS 3.0 兼容,所以我认为尝试使用 UIGestureRecognizers 已经过时了。

I have a situation similar to these two posts (1907297 AND 689684) and to describe my situation most concisely, I present this text/graphical layout (similar to what you'd see in IB, dots used to enforce indent levels)

UIView (MainView: 320x460)
. .UIScrollView (ScrollView: 320x460)
. .UIView (OverlayView: 320x40)
. . . .UIButton (ArbitraryButton1)
. . . .UILabel (ArbitraryLabel1)
. . . .UILabel (ArbitraryLabel2)

The goal here is for the OverlayView to serve as a unified, transparent container to position and display some arbitrary buttons/labels on top of the ScrollView. These buttons/labels should remain stationary while the content in the ScrollView beneath moves with user swipes. The buttons/labels may sometimes be hidden/unhidden/scaled in unison (with animation) which is what makes it handy to have them all grouped in the single OverlayView.

The trouble is that, while taps on the OverlayView seem to transmit right through to the underlying ScrollView just nicely, swiping motions have no effect. I can detect/intercept the swipes by overriding the

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event

method in the OverlayView, however I haven't yet found a way to properly pass those along to the ScrollView in a way that makes it scroll. Evidently the touchesMoved method is not what UIScrollView uses to detect/interpret swipes?

All the other similar posts I've researched have either found a different solution that wouldn't work in my case or have just gone unsolved. I've also seen mention of employing touchesShouldBegin / touchesShouldCancel though I don't grasp how that would be implemented. Anyhow, still hopeful that there's some insight from the community that can allow me to come up with an elegant solution for this - any sample code would be fantastic.

Thanks in advance, Joel.

P.S. - I should also mention that I need to make this compatible with iOS 3.0 so I think trying to use UIGestureRecognizers is out.

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

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

发布评论

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

评论(3

对你的占有欲 2024-10-27 08:11:33

这是一个对我来说效果很好的更简单的解决方案:

在 OverlayView (UIScrollView 顶部的视图)中,将宽度和高度设置为 0 (以便该视图在技术上不再位于滚动视图顶部)并设置 ClipsToBounds = NO (这样 OverlayView 的内容仍然显示在滚动视图的顶部)。它对我来说就像一种魅力。

 self.OverlayView.clipsToBounds = NO;
 CGRect frame = self.OverlayView.frame;
 self.OverlayView.frame = CGRectMake(frame.origin.x, frame.origin.y, 0, 0);

请注意,如果 OverlayView 包含交互式控件(如上面的按钮),那么它们将不再起作用。您需要将其移动到 UIScrollView 上方它自己的视图中。

Here's an easier solutions that worked well for me:

In the OverlayView (the view on top of UIScrollView), make the width and height both 0 (so that the view is no longer technically on top of the scrollview) and set clipsToBounds = NO (so that the contents of the OverlayView still show up on top of the scrollview). It worked like a charm for me.

 self.OverlayView.clipsToBounds = NO;
 CGRect frame = self.OverlayView.frame;
 self.OverlayView.frame = CGRectMake(frame.origin.x, frame.origin.y, 0, 0);

Note that if OverlayView contains interactive controls (like the button above) then they will no longer work. You'll need to move it into it's own view above the UIScrollView.

失去的东西太少 2024-10-27 08:11:33

怎么样,在运行时在 viewDidLoad 中将按钮从容器视图中取出并将它们直接作为子视图放置在视图中(并摆脱容器视图)?然后没有容器视图来拦截滑动,但您仍然可以使用视图对 IB 中的内容进行分组。

另外,您也可以将容器视图作为滚动视图的子视图,并在滚动视图委托中每当用户滚动时不断重新定位视图。这似乎很容易让人紧张,但可能值得一试。

此外,如果包含视图是一个视觉容器并且您需要查看它,则可以使用放置在 CALayer 顶部的超级视图中的 CALayer 来渲染滚动视图,因为 CALayers 与输入无关,并且不会每一次接触。

How about, at runtime in viewDidLoad you take the buttons out of the container view and place them in the view as subviews directly (and get rid of the container view)? Then there's no container view to intercept swipes but you can still use a view to group things in IB.

Also potentially you could put the container view in as a subview of the scroll view instead, and in the scroll view delegate keep re-positioning the view whenever the user scrolls. That would seem to have a high potential for being jittery but may be worth a try.

Also if the containing view is a visual container and you need to see it, you could instead use a CALayer that was placed in the superview on top of the CALayer for rendering the scroll view, since CALayers have nothing to do with input and would not each touches.

我也只是我 2024-10-27 08:11:33

您应该子类化 UIScrollView 并重写 TouchesShouldCancelInContentView: 方法

-(BOOL)touchesShouldCancelInContentView:(UIView *)view
{

    if ([view isKindOfClass:[UIButton class]]) {//or whatever class you want to be able to scroll in
        return YES;
    }

    if ([view isKindOfClass:[UIControl class]]) {
        return NO;
    }

    return YES;
}

You should subclass UIScrollView and override the touchesShouldCancelInContentView: method

-(BOOL)touchesShouldCancelInContentView:(UIView *)view
{

    if ([view isKindOfClass:[UIButton class]]) {//or whatever class you want to be able to scroll in
        return YES;
    }

    if ([view isKindOfClass:[UIControl class]]) {
        return NO;
    }

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