图像上类似 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
}
}
我一直在尝试在图像上实现类似 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
}
}