无法在其父视图之外平移手势较小的 UIView

Posted

技术标签:

【中文标题】无法在其父视图之外平移手势较小的 UIView【英文标题】:Cannot pan gesture smaller UIView outside of its superview 【发布时间】:2019-09-22 06:00:12 【问题描述】:

我有一个UIView,其中包含许多UIView 子视图。当用户尝试平移其中一个子视图时,我希望他们能够将其拖动到屏幕上的其他任何位置。

但是,我只能将这些较小的视图拖到更大的 UIView 中。当用户第一次尝试平移手势较小的视图时,有没有办法以编程方式在顶部创建第二个 UIView 然后拖动围绕第二个 UIView 代替?第二个 UIView 将与第一次触摸的较小视图相比是全新的。

这是我目前掌握的处理函数,仅供参考。不过,我不知道我会在哪里以编程方式创建第二个 UIView。任何帮助将不胜感激:

 @objc func handlePanGesture(sender: UIPanGestureRecognizer) 
    // get translation
    var translation = sender.translation(in: view)
    sender.setTranslation(CGPoint.zero, in: view)

    // drag around current UIView
    var newView = sender.view as! UIView
    newView.center = CGPoint(x: newView.center.x+translation.x, y: newView.center.y+translation.y)
    newView.isMultipleTouchEnabled = true
    newView.isUserInteractionEnabled = true

    if sender.state == UIGestureRecognizer.State.began 
        // add something you want to happen when the Label Panning has started
    

    if sender.state == UIGestureRecognizer.State.ended 
        // add something you want to happen when the Label Panning has ended
    

    if sender.state == UIGestureRecognizer.State.changed 
        // add something you want to happen when the Label Panning has been change ( during the moving/panning )
     else 
        // or something when it's not moving
    

【问题讨论】:

图片或视频可能会帮助其他人了解您想要做什么。如果要将视图移到其父视图之外,则必须关闭 clpsToBounds 或将视图移至不同的父视图。 @shim 添加了图片解释问题。我将如何以编程方式更改 UIView 的父视图? removeFromSuperview, addSubview @shim 当用户第一次尝试平移手势较小的视图时,有没有办法以编程方式创建第二个 UIView,然后在第二个 UIView 周围拖动?第二个 UIView 将与第一次触摸的原始较小视图相比是全新的...... 您可以制作一个看起来相同的视图并将其放在相同的初始位置并隐藏原始位置 【参考方案1】:

有什么方法可以将较小的视图拖动到任何地方,同时保持我现在的布局

由于触摸的工作方式,默认情况下,当视图到达其父视图的边界时,它是不可能被触摸的。但是您可以通过在超级视图中覆盖 hitTest 来克服该限制。

【讨论】:

有没有办法以编程方式在所有内容之上创建第二个 UIView,然后在第二个 UIView 周围拖动?第二个 UIView 将与第一次触摸的原始较小视图完全分开【参考方案2】:

一种非常常见的模式可以在其父视图之外拖动视图,即在手势开始后立即创建原始视图的快照或克隆,您当然可以隐藏原始视图,以便用户感觉正在拖动相同的 UI 元素。这是 Apple 在此处拖放示例代码中使用的模式

https://developer.apple.com/documentation/uikit/drag_and_drop/adopting_drag_and_drop_in_a_custom_view

查看 ViewController+Dra​​g.swift 中的第 36 行的相关代码。

【讨论】:

是否可以使用 UIPanGesture 创建原始视图的克隆?对于这个项目,我必须使用还没有 UIDragInteraction 的较低 ios 部署目标 是的,它根本不依赖 DragAndDrop API 我需要在 iOS 10.0 上进行部署,但是当我在该链接上下载示例项目时,我收到错误消息“'UIDragInteraction' 仅适用于 iOS 11.0 或更高版本”。我可以在平移手势处理程序的哪个位置复制我试图拖动的视图? 手势开始,然后在更改时您还应该更新翻译,您需要更新克隆视图上的框架。 您需要转换翻译,以便根据新视图和超级视图进行说明。看看 UIView 的转换函数。也好想个头,拖到最后你会怎么做?这个手势是否会成为转换到另一个视图的一部分?

以上是关于无法在其父视图之外平移手势较小的 UIView的主要内容,如果未能解决你的问题,请参考以下文章

如何使集合视图响应其自身视图之外的平移手势

斯威夫特:如何设置最大/最小平移手势?

与平移手势闪烁视图相关的问题

仅从 1 个子视图平移 UIView

是否可以在按钮上启动滚动视图平移手势

平移手势后将视图返回到原始位置,快速