如何使用 Pan Gesture 增加/减少字体大小?
Posted
技术标签:
【中文标题】如何使用 Pan Gesture 增加/减少字体大小?【英文标题】:How to Increase/Decrease font size with Pan Gesture? 【发布时间】:2020-03-19 03:47:11 【问题描述】:我正在对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
做同样的效果呢?任何帮助,将不胜感激。谢谢。
【问题讨论】:
“没有得到确切的结果”不是一个有用的问题描述。请说明期望的结果与实际发生的情况。 【参考方案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
舍入到小数点后三位,但您的原始代码 sn-p 中包含了这一点,所以我保留了它。
就个人而言,我会遵循与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)
您实际上不需要任何当前散布在整个代码 sn-p 中的强制转换。
所有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
子句,从而简化您的代码。
【讨论】:
以上是关于如何使用 Pan Gesture 增加/减少字体大小?的主要内容,如果未能解决你的问题,请参考以下文章
Spritekit中的Pan Gesture Recognizer移动对象
如何在 iOS Swift4 中滚动时增加/减少 UILabel 字体大小以及宽度和高度