【问题标题】:How to limit the area in which an object can be moved to the boundaries of another view with pan gestures?如何通过平移手势限制对象可以移动到另一个视图边界的区域?
【发布时间】:2018-04-03 15:56:00
【问题描述】:

我想限制 UITextView 只能移动到另一个视图的框架的区域。我尝试使用以下代码来完成此操作,但是,它不会正确限制用户可以拖动 UITextView 的位置:

@IBOutlet weak var canvas: UIView! 

@IBAction func handleDragOfCaption(_ sender: UIPanGestureRecognizer) {

    if sender.state == .began || sender.state == .changed {

        guard let senderView = sender.view else {return}

        let translation = sender.translation(in: sender.view)
        let x = senderView.center.x + translation.x
        let y = senderView.center.y + translation.y
        let point = CGPoint(x: x, y: y)

        if canvas.frame.contains(point) {
            senderView.center = point
            sender.setTranslation(CGPoint.zero, in: senderView)
        }

    }

}

请参阅下图,了解我正在尝试完成的工作。我只希望用户能够在 UIView 的边界内拖动 UITextView(这是 UITextView 下方的白色方块)。任何帮助将不胜感激。

【问题讨论】:

  • 尝试搜索一下 - 这个问题已经回答了很多次了。这里只是一个例子:stackoverflow.com/questions/47413817/…
  • @DonMag,我实际上遵循了人们在这里所说的但没有运气:stackoverflow.com/questions/12048525/…
  • 您还要做的是跟踪sender.state == .ended || sender.state == .cancelled 的时间,如果textView 超出范围,则对 x、y(或两者)进行编程翻译,直到它完全在界限。
  • @itsfaraaz - 你的文本视图是固定大小的吗?还是只是固定宽度?并且您希望能够在白色矩形内拖动它,而不是在图像顶部?

标签: ios swift


【解决方案1】:

这是另一种方法,使用约束...

给你的“可拖动视图”(你的文本视图,在这种情况下)一个宽度约束并禁用滚动(这将允许它自动调整其高度)。

将“可拖动视图”的所有四个边都约束为零 - 然后将这些约束编辑为 >= 0。这将防止视图被拖到其父视图之外。

另外将“可拖动视图”限制为水平和垂直居中 - 然后将这些限制编辑为具有Priority = 750。通过将中心约束设置为低于边缘约束的优先级,中心仅在边缘完全位于父视图内时才会生效。

将中心约束连接到视图控制器中的IBOutlets,并为中心约束的“当前”常量值添加vars

现在将平移手势识别器添加到“可拖动视图”。

启动平移时,将中心约束常量保存到“当前”变量中。

平移时,获取平移 X 和 Y(从平移起点移动的距离),并根据起点和新值之间的差异更新中心常数。这会将“可拖动视图”移动到新位置。

完成平移后,根据“可拖动视图”的最终位置更新中心常量。

@IBAction func handleDragOfCaption(_ sender: UIPanGestureRecognizer) {

    guard let senderView = sender.view else { return }
    guard let parentView = senderView.superview else { return }

    // get the current pan movement - relative to the view (the text view, in this case)
    let translation = sender.translation(in: canvas)

    switch sender.state {
    case .began:
        // save the current Center X and Y constants
        currentCenterXConstant = textViewCenterXConstraint.constant
        currentCenterYConstant = textViewCenterYConstraint.constant
        break

    case .changed:
        // update the Center X and Y constants
        textViewCenterXConstraint.constant = currentCenterXConstant + translation.x
        textViewCenterYConstraint.constant = currentCenterYConstant + translation.y
        break

    case .ended, .cancelled:
        // update the Center X and Y constants based on the final position of the dragged view
        textViewCenterXConstraint.constant = senderView.center.x - parentView.frame.size.width / 2.0
        textViewCenterYConstraint.constant = senderView.center.y - parentView.frame.size.height / 2.0
        break

    default:
        break

    }

}

为了帮助正确设置约束,我在此处发布了一个示例项目:https://github.com/DonMag/LimitDrag

【讨论】:

  • 这种方法比其他方法干净得多。感谢分享。
  • 谢谢!这个答案是我用来制作可拖动视图的答案
猜你喜欢
  • 2012-08-16
  • 1970-01-01
  • 1970-01-01
  • 2023-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-01
相关资源
最近更新 更多