iOS Swift:无需调整大小即可旋转和缩放 UIView
Posted
技术标签:
【中文标题】iOS Swift:无需调整大小即可旋转和缩放 UIView【英文标题】:iOS Swift: Rotate and Scale UIView without resizing 【发布时间】:2019-01-04 15:21:25 【问题描述】:我有一个 UIView,我想通过平移和捏合手势进行缩放和旋转。但问题是当我缩放视图时,然后当我旋转它时,它会在缩放之前调整回初始值。
extension UIView
func addPinchGesture()
var pinchGesture = UIPinchGestureRecognizer()
pinchGesture = UIPinchGestureRecognizer(target: self,
action: #selector(handlePinchGesture(_:)))
self.addGestureRecognizer(pinchGesture)
@objc func handlePinchGesture(_ sender: UIPinchGestureRecognizer)
self.transform = self.transform.scaledBy(x: sender.scale, y: sender.scale)
sender.scale = 1
// ROTATION
extension UIView
func addRotationGesture()
var rotationGesture = RotationGestureRecognizer()
rotationGesture = RotationGestureRecognizer(target: self,
action: #selector(handleRotationGesture(_:)))
self.addGestureRecognizer(rotationGesture)
@objc func handleRotationGesture(_ sender: RotationGestureRecognizer)
var originalRotation = CGFloat()
switch sender.state
case .began:
sender.rotation = sender.lastRotation
originalRotation = sender.rotation
case .changed:
let newRotation = sender.rotation + originalRotation
self.transform = CGAffineTransform(rotationAngle: newRotation) // Rotation is fine but it is resizing view
// self.transform = self.transform.rotated(by: newRotation / CGFloat(180 * Double.pi)) // NOT WORKING i.e. irregular rotation
case .ended:
sender.lastRotation = sender.rotation
default:
break
缩放前
缩放后
旋转后
我希望它在不影响视图大小的情况下旋转。我怎样才能做到这一点?
【问题讨论】:
【参考方案1】:您在应用旋转变换时正在重置视图的比例变换。创建一个属性来保持视图的原始比例。
var currentScale: CGFloat = 0
当捏合完成时,将 currentScale 值存储到当前比例。然后在旋转时也使用这个比例,然后再应用旋转。
let scaleTransform = CGAffineTransform(scaleX: currentScale, y: currentScale)
let concatenatedTransform = scaleTransform.rotated(by: newRotation)
self.transform = concatenatedTransform
您正在使用扩展来添加手势识别器,因此您无法存储 currentScale。您还可以从当前变换值中获取视图的比例值。这是您的代码的样子,
extension UIView
var currentScale: CGPoint
let a = transform.a
let b = transform.b
let c = transform.c
let d = transform.d
let sx = sqrt(a * a + b * b)
let sy = sqrt(c * c + d * d)
return CGPoint(x: sx, y: sy)
func addPinchGesture()
var pinchGesture = UIPinchGestureRecognizer()
pinchGesture = UIPinchGestureRecognizer(target: self,
action: #selector(handlePinchGesture(_:)))
self.addGestureRecognizer(pinchGesture)
@objc func handlePinchGesture(_ sender: UIPinchGestureRecognizer)
self.transform = self.transform.scaledBy(x: sender.scale, y: sender.scale)
sender.scale = 1
// ROTATION
extension UIView
func addRotationGesture()
var rotationGesture = RotationGestureRecognizer()
rotationGesture = RotationGestureRecognizer(target: self,
action: #selector(handleRotationGesture(_:)))
self.addGestureRecognizer(rotationGesture)
@objc func handleRotationGesture(_ sender: RotationGestureRecognizer)
var originalRotation = CGFloat()
switch sender.state
case .began:
sender.rotation = sender.lastRotation
originalRotation = sender.rotation
case .changed:
let scale = CGAffineTransform(scaleX: currentScale.x, y: currentScale.y)
let newRotation = sender.rotation + originalRotation
self.transform = scale.rotated(by: newRotation)
case .ended:
sender.lastRotation = sender.rotation
default:
break
我使用这个answer作为提取比例值的参考。
【讨论】:
它可以工作,但为什么它不能通过let newRotation = sender.rotation + originalRotation self.transform = self.transform.rotated(by: newRotation)
工作??
@AbhishekThapliyal 如果您不重置视图转换,那应该确实有效。
你能帮帮我吗,检查第一个答案中的 cmets ??? ***.com/questions/62372147/…【参考方案2】:
我遇到了同样的问题一旦我用手指捏住,然后从按钮旋转后,它会自动从当前缩小,但我在下面设置了逻辑。
@objc func rotateViewPanGesture(_ recognizer: UIPanGestureRecognizer)
touchLocation = recognizer.location(in: superview)
let center = CGRectGetCenter(frame)
switch recognizer.state
case .began:
deltaAngle = atan2(touchLocation!.y - center.y, touchLocation!.x - center.x) - CGAffineTrasformGetAngle(transform)
initialBounds = bounds
initialDistance = CGpointGetDistance(center, point2: touchLocation!)
case .changed:
let ang = atan2(touchLocation!.y - center.y, touchLocation!.x - center.x)
let angleDiff = deltaAngle! - ang
let a = transform.a
let b = transform.b
let c = transform.c
let d = transform.d
let sx = sqrt(a * a + b * b)
let sy = sqrt(c * c + d * d)
let currentScale = CGPoint(x: sx, y: sy)
let scale = CGAffineTransform(scaleX: currentScale.x, y: currentScale.y)
self.transform = scale.rotated(by: -angleDiff)
layoutIfNeeded()
case .ended:
print("end gesture status")
default:break
【讨论】:
以上是关于iOS Swift:无需调整大小即可旋转和缩放 UIView的主要内容,如果未能解决你的问题,请参考以下文章
使 UIImageView 及其 UIImage 按比例缩放而无需额外的填充
UICollectionView - 在设备旋转上调整单元格大小 - Swift