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

时间:2017-11-04 03:48:10

标签: ios uiscrollview uiimageview swift4 uipangesturerecognizer

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

我已经panGesture正常工作,但UIImageView仅在包含UIScrollView时显示在拖动内部,如果超出包含UIScrollView的范围,则会隐藏,如截图图片。

我尝试了someScrollView.sendSubview(toBack: self.view)之类的设置图层顺序以及imageView.layer.zIndex = ..,但在我的情况下似乎不起作用。

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

enter image description here

@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 个答案:

答案 0 :(得分:0)

首先,优先考虑手势识别器是一种很好的做法 - 告诉滚动视图的平移手势,由于您的平移手势而无法接收触摸(您的手势首先出现)。 / p>

someScrollView.panGestureRecognizer.require(toFail: yourGestureRecognizer)

将滚动视图的子视图解开到其边界 - 当拖动到scrollView的边界外时,它的子视图将会可见。

scrollView.clipsToBounds = false

您可以将拖动视图的帧转换为scrollView和newParentView祖先的coord'系统,像这样(假设self.view是scrollView& newParentView' s ancestor)。

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

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

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

}

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

平移已结束 AND pannedView位于newParentView的范围内

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

另一种解决方案是在GR状态为pannedView时从scrollView移除.began,并将其添加到scrollViewnewParentView的常见内容祖先。其余部分与我之前提到的相同。