需要 UIResponder 链解释

发布于 2024-11-15 05:48:56 字数 1014 浏览 4 评论 0原文

在这种情况下,我无法让 UIButtonsUIScrollViews 等正常工作:

我有基本的 UIViewController,它是UIWindow。 在该层之上,我添加了一些其他 UIView,我将其称为“中间层视图”。在顶部,我为覆盖对象添加了另一个 UIView。

中间层视图定期更改为不同的视图。它使用的 UIView 来自 UIViewController,由 NIB 文件创建。这是一个例子

if ( mode == eModeShowView1 )
    UIViewController* nextController = [[UIViewController alloc] initWithNibName:@"View1"...
else if ( mode == eModeShowView2 )
    UIViewController* nextController = [[UIViewController alloc] initWithNibName:@"View2"...

[UIView insertSubview:nextController.view below:m_overlayView];

现在,当我触摸屏幕时,第一个响应者显然是 OverlayView 或已触摸的 OverlayView 上的任何 UIResponder。 触摸输入的 UIEvent 沿着视图链向上,但似乎完全跳过了中间层视图和该 UIView 上的 UIResponders。它直接跳转到根UIViewController

有谁知道这是怎么回事?

可以通过创建两个 UIEvents 来解决吗?一种用于叠加视图,另一种用于中间层视图?这可能吗?如果是这样,怎么办?

任何帮助将不胜感激。 谢谢, 富有的

I'm having trouble getting my UIButtons, UIScrollViews etc working in this situation:

I have the base UIViewController, which is the root controller of the UIWindow.
Above that layer I have some other UIViews added, which I will call the "Middle Layer View". And on the top I have another UIView added for overlay objects.

The Middle Layer View is changed for different views regularly. The UIView it uses is from a UIViewController, made by a NIB file. Here's an example

if ( mode == eModeShowView1 )
    UIViewController* nextController = [[UIViewController alloc] initWithNibName:@"View1"...
else if ( mode == eModeShowView2 )
    UIViewController* nextController = [[UIViewController alloc] initWithNibName:@"View2"...

[UIView insertSubview:nextController.view below:m_overlayView];

Now, when I touch on screen, the first responder is obviously the OverlayView or any UIResponder on the OverlayView that has been touched.
The UIEvent of the touch input goes up the view chain but seems to skip the Middle Layer View and the UIResponders on that UIView altogether. It jumps straight to the root UIViewController.

Does anyone know what's going on here?

Could it be solved by somehow creating two UIEvents? One for the Overlay View and one for the Middle Layer View? Is that possible? If so, how?

Any help would be most appreciated.
Thanks,
Rich

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

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

发布评论

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

评论(1

月亮邮递员 2024-11-22 05:48:56

edit1 start:

您可以将 UITapGestureRecognizer 放入 m_overlayView 和 initWithTarget:your-middleview action:some-method-in-middleview

现在,在您的 middleview 中,您可以将 recognizer.state 识别为 UIGestureRecognizerStateBegan、Ended 等,然后执行您想做的操作。

edit1 end:

可以调试了。只需在所有控制器中使用 touchesbegan 中的日志即可。通过日志可以清楚地了解触摸响应的顺序。

好吧..所以文档中的方法描述可能会回答你。您的 m_overlayViewnextController.view 将彼此视为兄弟而不是超级视图。因此,您对其中任何一个的触摸都不会报告给另一个,而是报告给基本的超级视图,这是兄弟姐妹共同的超级视图。

因此你会发现中间层被绕过了。实际上,您的中间层是兄弟视图,不再是超级视图。希望这至少能给您带来一些帮助;)

insertSubview:belowSubview:

在视图层次结构中的另一个视图下方插入一个视图。

(void)insertSubview:(UIView *)view belowSubview:(UIView *)siblingSubview

参数

view

要插入到另一个视图下方的视图。如果它不是siblingSubview 的同级,则会从其superview 中删除。

siblingSubview

将位于插入视图上方的同级视图。

讨论

此方法保留视图并将其下一个响应者设置为接收者,即其新的超级视图

视图只能有一个超级视图。如果视图已经有一个 superview 并且该视图不是接收者,则此方法会在使接收者成为新的 superview 之前删除先前的 superview

edit1 start:

you can put a UITapGestureRecognizer to the m_overlayView and initWithTarget:your-middleview action:some-method-in-middleview

Now, in your middleview you can identify recognizer.state as UIGestureRecognizerStateBegan, Ended etc and do what you want to do.

edit1 end:

You can debug it. Just use the logs in touchesbegan in all your controllers. It will be clear by logs the sequence of touch responses.

Ok.. so this description of method from documentation might answer you. Your m_overlayView and nextController.view are regarding each other as siblings and not superview. So your touch on either of them will not be reported to the other but instead to the base superview which is a common superview to both the siblings.

Hence you are getting that the middle layer is being bypassed. Actually your middle-layer is a sibling and no more a superview. Hope that at least gives you some way ahead ;)

insertSubview:belowSubview:

Inserts a view below another view in the view hierarchy.

(void)insertSubview:(UIView *)view belowSubview:(UIView *)siblingSubview

Parameters:

view

The view to insert below another view. It’s removed from its superview if it’s not a sibling of siblingSubview.

siblingSubview:

The sibling view that will be above the inserted view.

Discussion:

This method retains view and sets its next responder to the receiver, which is its new superview.

Views can have only one superview. If view already has a superview and that view is not the receiver, this method removes the previous superview before making the receiver its new superview.

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