我正在UILabel
上应用平移手势。我使用一个手指刻度来增大和减小UILabel
的大小。
我尝试使用scale
从字体大小中添加和减去值,但是我没有得到确切的结果。
@objc
func handleRotateGesture(_ recognizer: UIPanGestureRecognizer) {
let touchLocation = recognizer.location(in: self.superview)
let center = self.center
switch recognizer.state {
case .began:
self.deltaAngle = CGFloat(atan2f(Float(touchLocation.y - center.y), Float(touchLocation.x - center.x))) - CGAffineTransformGetAngle(self.transform)
self.initialBounds = self.bounds
self.initialDistance = CGPointGetDistance(point1: center, point2: touchLocation)
case .changed:
let angle = atan2f(Float(touchLocation.y - center.y), Float(touchLocation.x - center.x))
let angleDiff = Float(self.deltaAngle) - angle
self.transform = CGAffineTransform(rotationAngle: CGFloat(-angleDiff))
if let label = self.contentView as? UILabel {
var scale = CGPointGetDistance(point1: center, point2: touchLocation) / self.initialDistance
let minimumScale = CGFloat(self.minimumSize) / min(self.initialBounds.size.width, self.initialBounds.size.height)
scale = max(scale, minimumScale)
let scaledBounds = CGRectScale(self.initialBounds, wScale: scale, hScale: scale)
var pinchScale = scale
pinchScale = round(pinchScale * 1000) / 1000.0
var fontSize = label.font.pointSize
if(scale > minimumScale){
if (self.bounds.height > scaledBounds.height) {
// fontSize = fontSize - pinchScale
label.font = UIFont(name: label.font.fontName, size: fontSize - pinchScale)
}
else{
// fontSize = fontSize + pinchScale
label.font = UIFont(name: label.font.fontName, size: fontSize + pinchScale)
}
} else {
label.font = UIFont( name: label.font.fontName, size: fontSize)
}
print("PinchScale -- \(pinchScale), FontSize = \(fontSize)")
self.bounds = scaledBounds
} else {
var scale = CGPointGetDistance(point1: center, point2: touchLocation) / self.initialDistance
let minimumScale = CGFloat(self.minimumSize) / min(self.initialBounds.size.width, self.initialBounds.size.height)
scale = max(scale, minimumScale)
let scaledBounds = CGRectScale(self.initialBounds, wScale: scale, hScale: scale)
self.bounds = scaledBounds
}
self.setNeedsDisplay()
default:
break
}
}
但是,我们可以使用UIPinchGestureRecognizer
来实现。但是,如何使用UIPanGestureRecognizer
达到相同的效果?任何帮助,将不胜感激。谢谢。
答案 0 :(得分:1)
现在,您正在为标签的当前字体大小添加和删除点。我建议使用一种更简单的模式,使其与您在其他地方所做的工作更加一致,即仅捕获手势开始时的初始点大小,然后在用户的手指移动时将比例尺应用于保存的值。所以,我建议:
定义属性以保存初始字体大小:
var initialPointSize: CGFloat = 0
在手势的.began
中,捕获当前大小
initialPointSize = (contentView as? UILabel)?.font?.pointSize ?? 0
在.changed
中,调整字体大小:
let pinchScale = (scale * 1000).rounded() / 1000
label.font = label.font.withSize(initialPointSize * pinchScale)
顺便说一句,我不确定是否有必要将scale
舍入到小数点后三位,但是您在原始代码段中保留了该位,所以我保留了该位。
我个人会使用与transform
相同的基本模式:
定义属性以捕获起始角度和视图的当前transform
:
var initialAngle: CGFloat = 0
var initialTransform: CGAffineTransform = .identity
在.began
中,捕获当前的起始角度和现有的变换:
initialAngle = atan2(touchLocation.y - center.y, touchLocation.x - center.x)
initialTransform = transform
在.changed
中,更新transform
:
let angle = atan2(touchLocation.y - center.y, touchLocation.x - center.x)
transform = initialTransform.rotated(by: angle - initialAngle)
这样可以避免使用CGAffineTransformGetAngle
对与当前变换相关的角度进行反向工程,而只需将rotated(by:)
应用于保存的变换。
因此,这与点大小和边界一样,表示一个一致的模式:在.began
中捕获起始值,然后在.changed
中应用所需的任何更改。
一些不相关的观察结果
不需要所有这些self.
引用。只是增加了噪音,使阅读代码变得更加困难。
CGFloat
和Float
之间的所有这些强制类型转换都是不需要的。如果您使用atof2
函数而不是atof2f
,它们都将与CGFloat
一起使用,而不会进行任何强制转换。例如,代替
let angle = atan2f(Float(touchLocation.y - center.y), Float(touchLocation.x - center.x))
let angleDiff = Float(self.deltaAngle) - angle
self.transform = CGAffineTransform(rotationAngle: CGFloat(-angleDiff))
您可以这样做:
let angle = atan2(touchLocation.y - center.y, touchLocation.x - center.x)
transform = CGAffineTransform(rotationAngle: angle - deltaAngle)
您实际上不需要当前在整个代码段中散布的所有投射。
所有这些bounds.size.width
和bounds.size.height
分别可以分别为bounds.width
和bounds.height
,从而再次消除了代码中的噪声。
调整字体大小时,而不是:
label.font = UIFont(name: label.font.fontName, size: fontSize)
您应该使用:
label.font = label.font.withSize(fontSize)
这样,您可以保留字体的所有基本特征(粗细等),并只需调整大小即可。
在您的if let label = contentView as? UILabel
测试中,else
子句中相同的五行代码也出现在if
子句中。您只需将这些常见行移到if
-else
语句之前,然后就可以完全丢掉else
子句,从而简化代码。