仅在其父视图内拖动UIImageView

时间:2019-06-07 13:30:10

标签: ios swift

让我说:

  • 名为UIImageView的{​​{1}}
  • 名为fox的父ImageView
  • 默认情况下嵌入fence中的主UIView

现在换句话说,我希望ViewControllers仅在其fox内移动

在我的fence中:

viewDidLoad()

现在这部分工作正常,我想通过对override func viewDidLoad() { super.viewDidLoad() view.addSubview(fence) fence.addSubview(fox) } 进行子类化并进行一些修改来移动fox

UIImageView

现在,我可以将class DraggableImageView: UIImageView { var dragStartPositionRelativeToCenter : CGPoint? override init(image: UIImage!) { super.init(image: image) self.isUserInteractionEnabled = true addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(handlePan(nizer:)))) layer.shadowColor = UIColor.black.cgColor layer.shadowOffset = CGSize(width: 0, height: 3) layer.shadowOpacity = 0.5 layer.shadowRadius = 2 } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } @objc func handlePan(nizer: UIPanGestureRecognizer!) { if nizer.state == UIGestureRecognizer.State.began { let locationInView = nizer.location(in: superview) dragStartPositionRelativeToCenter = CGPoint(x: locationInView.x - center.x, y: locationInView.y - center.y) layer.shadowOffset = CGSize(width: 0, height: 20) layer.shadowOpacity = 0.3 layer.shadowRadius = 6 return } if nizer.state == UIGestureRecognizer.State.ended { dragStartPositionRelativeToCenter = nil layer.shadowOffset = CGSize(width: 0, height: 3) layer.shadowOpacity = 0.5 layer.shadowRadius = 2 return } let locationInView = nizer.location(in: superview) UIView.animate(withDuration: 0.1) { self.center = CGPoint(x: locationInView.x - self.dragStartPositionRelativeToCenter!.x, y: locationInView.y - self.dragStartPositionRelativeToCenter!.y) } }} 对象拖到我喜欢的任何位置,但是;如果我只想在fox对象内移动fox,该怎么办?由于它是子视图,所以我认为是可能的。

1 个答案:

答案 0 :(得分:2)

为了将图像视图保留在其父视图中,我在更新视图中心之前添加了一项检查,以确保视图框架位于父框架中。仅当更新将视图保持在其父框架之内时,中心才会更新。

我还更新了平移处理程序以使用翻译(类似于平移手势documentation中的示例),而不是locationInView。 这样可以使拖动效果更好。

我已经对此进行了测试,并且我相信它会按照您期望的方式运行。希望这会有所帮助:

    @objc func handlePan(nizer: UIPanGestureRecognizer!) {
        if nizer.state == UIGestureRecognizer.State.began {
            dragStartPositionRelativeToCenter = self.center
            layer.shadowOffset = CGSize(width: 0, height: 20)
            layer.shadowOpacity = 0.3
            layer.shadowRadius = 6

            return
        }

        if nizer.state == UIGestureRecognizer.State.ended {
            dragStartPositionRelativeToCenter = nil

            layer.shadowOffset = CGSize(width: 0, height: 3)
            layer.shadowOpacity = 0.5
            layer.shadowRadius = 2

            return
        }

        if let initialCenter = dragStartPositionRelativeToCenter {
            let translation = nizer.translation(in: self.superview)
            let newCenter = CGPoint(x: initialCenter.x + translation.x, y: initialCenter.y + translation.y)
            if frameContainsFrameFromCenter(containingFrame: superview!.frame, containedFrame: self.frame, center: newCenter) {
                UIView.animate(withDuration: 0.1) {
                    self.center = newCenter
                }
            }

        }
    }

    func frameContainsFrameFromCenter(containingFrame: CGRect, containedFrame: CGRect, center: CGPoint) -> Bool {
        let leftMargin = containedFrame.width / 2
        let topMargin = containedFrame.height / 2
        let testFrame = CGRect(
            x: leftMargin,
            y: topMargin,
            width: containingFrame.width - (2*leftMargin),
            height: containingFrame.height - (2*topMargin)
        )
        return testFrame.contains(center)
    }