将图像从 UIScrollView 移动到 UIView - Swift 4 PanGesture

Posted

技术标签:

【中文标题】将图像从 UIScrollView 移动到 UIView - Swift 4 PanGesture【英文标题】:Move image from UIScrollView to UIView - Swift 4 PanGesture 【发布时间】:2017-11-04 03:48:10 【问题描述】:

我希望能够将UIImageView 的实例从UIScrollView 移动到包含UIScrollView 之外的UIView

我已经让panGesture 工作,但UIImageView 在被拖动时仅显示在包含UIScrollView 内,如果超出包含UIScrollView 则隐藏,如屏幕截图所示。

我尝试过类似someScrollView.sendSubview(toBack: self.view) 的方法来设置图层顺序以及imageView.layer.zIndex = ..,但它似乎不适用于我的情况。

如何实现屏幕截图中显示的内容,以便可以将其拖动到包含视图之外的目标UIView? 如果可能的话,如何在 panGesture 开始时创建 UIImageView 的新实例,以便保留原始图像。

@IBOutlet weak var someScrollView: UIScrollView!
var letters: [String] = ["g","n","d"]

override func viewDidLoad() 
    super.viewDidLoad()
    someScrollView.addSubview(createLetters(letters))
    someScrollView.sendSubview(toBack: self.view)


func createLetters(_ named: String]) -> [UIImageView] 
    return named.map  name in
        let letterImage = UIImageView()
        letterImage.image = UIImage(named: "\(name)")
        addPanGesture(image: letterImage)
        return letterImage
    


func addPanGesture(image: UIImageView) 
    let pan = UIPanGestureRecognizer(target: self, action: #selector(ViewController.handlePan(sender:)))
    image.addGestureRecognizer(pan)


@objc func handlePan(sender: UIPanGestureRecognizer) 
    let translation = sender.translation(in: view)
    if let imageView = sender.view 
        imageView.center = CGPoint(x:imageView.center.x + translation.x,
                              y:imageView.center.y + translation.y)
    
    sender.setTranslation(CGPoint.zero, in: self.view)

    switch sender.state 
    case .began:
    ...
    

【问题讨论】:

【参考方案1】:

首先,优先考虑手势识别器是一种很好的做法 - 告诉滚动视图的平移手势,由于您的平移手势,它不会收到触摸(您的优先)。

someScrollView.panGestureRecognizer.require(toFail: yourGestureRecognizer)

将滚动视图的子视图取消剪辑到它的边界 - 当拖动到滚动视图的边界之外时,它的子视图将可见。

scrollView.clipsToBounds = false

您可以将拖动视图的框架转换为 scrollView 和 newParentView 祖先的坐标系统,如下所示(假设 self.view 是 scrollView 和 newParentView 的祖先)。

let pannedViewFrame = someScrollView.convert(pannedView, to: self.view)

然后,在您的手势识别器的选择器中,您可以测试 pannedViewFrame 和 newParentView.frame 的帧交集,如下所示:

// You have an frame intersection 
if pannedViewFrame.intersects(newParentView.frame) 


现在,如果您在手势识别器的状态为.cancelled.ended.failed 时测试帧的交集,那么:

平移已结束 并且 pannedView 在 newParentView 的范围内

最后一步,只需使用相同的技巧将pannedViewFrame 转换为newParentView.frame 的坐标,并将pannedView 作为子视图添加到newParentView

另一种解决方案是当 GR 状态为 .began 时从 scrollView 中删除 pannedView 并将其添加到 scrollViewnewParentView 的共同祖先。其余的和我之前提到的一样。

【讨论】:

以上是关于将图像从 UIScrollView 移动到 UIView - Swift 4 PanGesture的主要内容,如果未能解决你的问题,请参考以下文章

1-3 UIScrollView

是否可以将 UIScrollView 指示器从右侧移动到左侧?

在 iPhone SDK 中将 UIButton 从 UIScrollView 移动到 UIView

UIScrollView 在导航和状态栏下方移动

将图像视图加载到 UIScrollView 和性能

双击将图像移动到其他视图