图像上类似 Snapchat 的文字

Snapchat-like text on image

我一直在尝试在图像上实现类似 Snapchat 的编辑文本。 到目前为止,我所做的是在 UIImageView 的中心实现一个 UILabel,我向这个 UILabel 添加了 3 个手势:UIPanGestureRecognizer、UIPinchGestureRecognizer 和 UIRotationGestureRecognizer。

我已经成功实现了 Pan 方法,但是我很难像他们那样使 Pinch + Rotation 平滑,我得到了糟糕的结果 T_T

你们认为这是如何制作的?这涉及哪些组件以及如果您有任何阅读/观看 material 我可以用来完成此操作。

谢谢:)

编辑:

这些是我实现的处理收缩和旋转的方法:

func handlePinch(recognizer: UIPinchGestureRecognizer) {
    if let view = recognizer.view as? UILabel {
        view.transform = CGAffineTransformScale(view.transform, recognizer.scale, recognizer.scale)
    }
}

func handleRotate(recognizer: UIRotationGestureRecognizer) {
    if let view = recognizer.view as? UILabel {
        view.transform = CGAffineTransformRotate(view.transform, recognizer.rotation)
    }
}

预览视频,了解我实现的捏合是如何工作的: https://drive.google.com/file/d/0B-AVM51jxsvUY2RUUHdWbGo5QlU/view?usp=sharing

我不确定这是否正是您要找的(我从未使用过 snapchat),但这可能会给您一些想法

https://github.com/danielinoa/DIImageView

我不确定这个有捏合手势,但我也不完全确定你的意思是如何使用它。

这是该项目的演示: https://www.cocoacontrols.com/controls/diimageview

一般来说,我建议您在每次尝试实施此类操作时检查 cocoacontrols。通常有可靠的示例可以帮助您入门,有时,您会找到您所需要的。

对于"it scales up / down way too much in a very aggressive way":

您需要根据自己的需要来处理捏合手势比例值。

从您的识别器方法中,您获得的比例值为:

    var pinchScale: CGFloat = recogniser.scale

您需要修改此值,例如根据需要将其减少 /10 或 /100,并在标签转换中使用此值,而不是使用 pangesture scale。

您遇到的问题是,您的代码采用当前变换并根据当前 "movement" 添加另一个变换,因此您在单个手势期间移动时会累积变化(实际上是复合变化)。

保留旋转、缩放和移动的实例变量,更新每个手势识别器动作中的相关变量(您还需要在每个手势开始时存储每个状态,因此您可以应用增量到初始状态),并使用这三个变量从头开始创建转换。创建转换当然应该分解为一个单独的函数,因为您将多次使用它。

找到了一个解决方案,显然我在旋转和收缩中需要做的就是始终重置视图的旋转/缩放。 例如,将我的 recognizer.scale 设置为 1.0,将 recognizer.rotation 设置为 0.0。

这是我的代码示例:

func handlePan(recognizer: UIPanGestureRecognizer) {
    let translation = recognizer.translationInView(view)
    if let view = recognizer.view {
        view.center = CGPoint(x:view.center.x + translation.x,
            y:view.center.y + translation.y)
    }
    recognizer.setTranslation(CGPointZero, inView: view)
}

func handlePinch(recognizer: UIPinchGestureRecognizer) {
    if let view = recognizer.view as? UILabel {
        let pinchScale: CGFloat = recognizer.scale
        view.transform = CGAffineTransformScale(view.transform, pinchScale, pinchScale)
        recognizer.scale = 1.0
    }
}

func handleRotate(recognizer: UIRotationGestureRecognizer) {
    if let view = recognizer.view as? UILabel {
        let rotation: CGFloat = recognizer.rotation
        view.transform = CGAffineTransformRotate(view.transform, rotation)
        recognizer.rotation = 0.0
    }
}