ios - 带有边界限制和动画的平移手势

标签 ios iphone uitextfield uigesturerecognizer

从这个答案实现此代码时:https://stackoverflow.com/a/31487087

override func viewDidLoad() {
    super.viewDidLoad()


    var gesture = UIPanGestureRecognizer(target: self, action: Selector("userDragged:"))
    bottomTextField.addGestureRecognizer(gesture)
    bottomTextField.userInteractionEnabled = true
}

func userDragged(gesture: UIPanGestureRecognizer){
    var loc = gesture.locationInView(self.view)
    self.bottomTextField.center = loc

}

可以在该区域周围拖动 TextField。但是我还想要两件事。首先,我想为 TextField 可以拖动,所以 TextField 不能在整个 View 中拖动。其次,它应该有一个漂亮的动画。对于用户体验,它不能只是在 TextField 达到他的边界时“停止”。

例子:
假设可以将 TextField 拖动到相对于 Root View 的每个方向大约 10%。手指离 TextField 越近,TextField 就越“自由”。当将文本字段移动到非常接近其原始位置时,文本字段应该比手指远离文本字段原始位置时移动得更多。因此,当手指伸到右上角时,握住 TextField(假设 TextField 位于中间),TextField 仍然会响应,但它的移动很小。当手指释放 TextField 时,它应该弹回原来的位置。

我希望你们能理解我。如果没有,我也许可以提供另一个例子。谢谢你。

编辑:

这就像拉动松紧带。一开始拖动很顺利,但是你拉或拖动到边界的次数越多,TextField 正在移动,但非常慢。我添加了一张图片。也许我让它听起来很难理解,但它确实很简单......Click Here (图 1 显示 TextField 每个方向可以走 10%。)

最佳答案

好的,所以你想使用手势识别器的翻译,而不是位置,否则如果用户没有“捕获”中间的 View ,你会得到一个跳跃:

var startPosition: CGPoint?
func userDragged(gesture: UIPanGestureRecognizer){
    if gesture.state == .began {
        startPosition = bottomTextField.center
    } else if gesture.state == .changed {
        let translation = gesture.translationInView(self.view)
        guard let start = self.startPosition else { return }
        let newCenter = CGPoint(x: start.x + translation.x, y: x.y + translation.y)
        bottomTextField.center = newCenter
    } else {
        startPosition = nil
    }
}

这应该可以解决第一个问题,即在手势开始时 View 会跳转到手指。

然后你会想仔细看看 let newCenter = CGPoint(x: start.x + translation.x, y: x.y + translation.y)对可以拖动 View 的位置应用一些限制。

假设您不希望 View 在任何方向上可拖动超过 50pts(或 super View 大小的 10%),您可以简单地使用:
let newCenter = CGPoint(x: start.x + min(translation.x, 50), y: x.y + min(translation.y, 50))

它只是检查哪个更小,翻译或值 50,并使用两者中较小的一个。 [注意:这给你一个围绕起点的方形限制,而不是径向限制]

然后你想看看让它更复杂一点,让改变的距离成为平移的函数,这样你就可以在接近极限时逐渐减小运动:
let normX = max(min(translation.x / 150, 1), -1)
let deltaX = 50 * sin(normX) // add custom function here
let normY = max(min(translation.y / 150, 1), -1)
let deltaY = 50 * sin(normY) // add custom function here
let newCenter = CGPoint(x: start.x + min(deltaX, 50), y: x.y + min(deltaY, 50))

这不是您想要使用的转换,而是表明您如何实现改变平移的效果,而不仅仅是线性移动 View ,您将希望在您自己的平移函数中子化以根据任何弹性产生增量你想要的曲线...

(提供的函数将在 150pts 的拖动距离上标准化 1 和 -1 之间的转换,然后将其映射到正弦曲线上以逐渐减小用于移动 View 的增量,将最大增量限制为 50pts。)

如果您可以更好地定义您希望这条曲线如何工作,也许我可以提供更多帮助?

关于ios - 带有边界限制和动画的平移手势,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42811570/

相关文章:

iphone - iPhone 上 INSERT 的 SQLite 行为

iphone - 如何使 UITableView 上的单元格不可选?

iphone - iOS 7 动态模糊效果,如控制中心

ios - 是否有内置的方法可以在iOS 6 UITextField中从右向左输入文本?

ios - 保存后 Core Data objectID 为 nil

iphone - 我应该把我的图像放在我的 iPhone 项目中的什么地方?

swift - UITextField 键盘返回按钮标题

ios - 无法在 UITextfield 中输入

ios - Xcode 4.6.3 中的解析问题 - "Expected a type"- 找不到错误

ios - 如何依赖 MFMailComposeViewController 及其类方法进行单元测试?