在SceneKit场景中将UIView作为SCNMaterialProperty时,该视图能否加入响应链?
在SceneKit中使用UIView作为SCNMaterialProperty时的响应链问题
很遗憾,当你把UIView作为SCNMaterialProperty的contents使用时,这个UIView不会成为App响应链的一部分,没法处理任何触摸、点击这类交互事件。
为什么会这样呢?其实SceneKit在这里只是把你传入的UIView当成一个「纹理数据源」——它会先对这个视图做快照,把内容转换成纹理贴图贴在3D几何体上,之后这个UIView本身并没有被加入到App的视图层级里,自然就接收不到系统分发的触摸事件了。哪怕你后续修改这个UIView的内容,也需要手动触发刷新才能同步到3D物体上,更别说交互了。
比如你提供的这段代码:
let omg_you_can_use_an_actual_uiview_now = UIView(frame: CGRect(x: 0, y: 0, width: 500, height: 500)) material_plane.diffuse.contents = omg_you_can_use_an_actual_uiview_now let geom_plane = SCNPlane(width: 1, height: 1) geom_plane.materials = [material_plane]
这段代码里的omg_you_can_use_an_actual_uiview_now视图,只是被用来生成纹理,完全不参与响应链。
如果想要实现类似「点击3D物体上的UI内容」的效果,给你两个可行思路:
- 模拟交互逻辑:监听SceneKit视图的触摸事件,用
hitTest(_:options:)方法检测点击的是不是目标3D平面。如果是,把触摸点坐标转换到原UIView的坐标系里,手动触发对应的交互(比如判断点击了UIView里的某个子控件,调用它的点击方法)。 - 分层视觉对齐:如果你的UI交互比较复杂,干脆把UIView直接放在SceneKit视图的上层,通过坐标计算让它和3D平面在视觉上完全对齐。这样UIView本身就在正常的视图层级里,能完全参与响应链,处理各种原生交互。
内容的提问来源于stack exchange,提问作者Geoff H
相关产品推荐
相关产品推荐

