Прямо сейчас вы добавляете и удаляете точки к текущему размеру шрифта метки. Я бы предложил более простой шаблон, более соответствующий тому, что вы делаете в другом месте, а именно просто захват начального размера точки в начале жеста, а затем, когда палец пользователя двигается, примените масштаб к этому сохраненному значению. Итак, я бы предложил:
Определить свойство для сохранения исходного размера шрифта:
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
до трех знаков после запятой, но у вас это было в исходном фрагменте кода, поэтому я сохранил это.
Лично я бы следовал тот же паттерн basi c с 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)
Таким образом, вы сохраните все основные характеристики шрифта (вес и т. д. * 1111). *.) и просто измените размер.
В вашем тесте if let label = contentView as? UILabel
те же пять строк кода в вашем предложении else
появляются и в предложении if
, Вам следует просто переместить эти общие строки перед оператором if
- else
, и тогда вы можете полностью потерять предложение else
, упрощая ваш код.