前言
对View进行放大缩小、移动、旋转,其实是很常见的需求,最开始在OC上,很早的几年,还是用的touch事件来实现,这种实现方式很繁琐,呈现的效果也不是很好。
后来,苹果也逐步的淘汰了这种方式,出了手势这种模式,极大程度上的缩减了代码量,而且操作简单,上手迅速,OC上手势的使用方式网上比比皆是,这里就不细说,着重介绍Swift View手势控制方法。
实现
添加旋转、缩放、移动手势,如下:
1 2 3 4 5 6 7 8 9 10 11
| //Rotation let rotationGestureRecognizer = UIRotationGestureRecognizer(target: self, action: #selector(EditPhotoViewController.rotateView(_:))) photoImageView?.addGestureRecognizer(rotationGestureRecognizer)
//Scale pinch let pinchGestureRecognizer = UIPinchGestureRecognizer(target: self, action: #selector(EditPhotoViewController.pinchView(_:))) photoImageView?.addGestureRecognizer(pinchGestureRecognizer)
//Move let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(EditPhotoViewController.panView(_:))) photoImageView?.addGestureRecognizer(panGestureRecognizer)
|
以下代码使用变量如下:
private var cropFrame = CGRect.zero //图片上限制框的frame
private var latestFrame = CGRect.zero //最大缩放frame
private var rotationAngle: CGFloat = 0.0 //旋转的角度
给变量设置初始值:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| private func resetShowImageViewFrame() { rotationAngle = 0.0
photoImageView?.image = originalImage photoImageView?.transform = .identity
// scale to fit the screen cropFrame = photoOverLayView?.transparentArea ?? CGRect.zero
var oriWidth: CGFloat = cropFrame.size.width var oriHeight: CGFloat = (originalImage?.size.height ?? 0.0) * (oriWidth / (originalImage?.size.width ?? 0.0)) if ((originalImage?.size.width)!/(originalImage?.size.height)!) > (CGFloat)(standardPostImgWidth)/(CGFloat)(standardPostImgHeight) { oriHeight = cropFrame.size.height oriWidth = (originalImage?.size.width ?? 0.0) * (oriHeight / (originalImage?.size.height ?? 0.0)) } let oriX: CGFloat = cropFrame.origin.x + (cropFrame.size.width - oriWidth) / 2 let oriY: CGFloat = cropFrame.origin.y + (cropFrame.size.height - oriHeight) / 2 oldFrame = CGRect(x: oriX, y: oriY, width: oriWidth, height: oriHeight) latestFrame = oldFrame photoImageView?.frame = oldFrame largeFrame = CGRect(x: 0, y: 0, width: limitRatio * oldFrame.size.width, height: limitRatio * oldFrame.size.height) }
|
旋转实现
1 2 3 4 5 6 7 8 9 10
| @objc func rotateView(_ rotationGestureRecognizer: UIRotationGestureRecognizer?) { let view: UIView? = photoImageView if rotationGestureRecognizer?.state == .began || rotationGestureRecognizer?.state == .changed { view?.transform = (view?.transform.rotated(by: (rotationGestureRecognizer?.rotation)!))! rotationAngle = rotationAngle + (rotationGestureRecognizer?.rotation ?? 0.0) rotationGestureRecognizer?.rotation = 0 } else if rotationGestureRecognizer?.state == .ended { latestFrame = photoImageView?.frame ?? CGRect.zero } }
|
缩放实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| @objc func pinchView(_ pinchGestureRecognizer: UIPinchGestureRecognizer?) { let view: UIView? = photoImageView if pinchGestureRecognizer?.state == .began || pinchGestureRecognizer?.state == .changed { if rotationAngle == 0 { //narrow if (pinchGestureRecognizer?.scale)! <= CGFloat(1.0) && ((photoImageView?.width)! <= cropFrame.size.width || (photoImageView?.height)! <= cropFrame.size.height) { return } } //amplification if (pinchGestureRecognizer?.scale)! > CGFloat(1.0) && ((photoImageView?.width)! > 5000 || (photoImageView?.height)! > 5000) { return } view?.transform = (view?.transform.scaledBy(x: (pinchGestureRecognizer?.scale)!, y: (pinchGestureRecognizer?.scale)!))! pinchGestureRecognizer?.scale = 1 } else if pinchGestureRecognizer?.state == .ended { if rotationAngle == 0 { var newFrame: CGRect? = photoImageView?.frame //newFrame = handleScaleOverflow(newFrame ?? CGRect.zero) newFrame = handleBorderOverflow(newFrame ?? CGRect.zero) UIView.animate(withDuration: TimeInterval(BOUNDCE_DURATION), animations: { self.photoImageView?.frame = newFrame ?? CGRect.zero self.latestFrame = newFrame ?? CGRect.zero }) } else { latestFrame = photoImageView?.frame ?? CGRect.zero } } }
|
平移实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| @objc func panView(_ panGestureRecognizer: UIPanGestureRecognizer?) { let view = panGestureRecognizer?.view; if (panGestureRecognizer?.state == .began || panGestureRecognizer?.state == .changed) { let translation = panGestureRecognizer?.translation(in: view?.superview) view?.center = CGPoint(x: (view?.center.x)! + (translation?.x)!, y: (view?.center.y)! + (translation?.y)!) panGestureRecognizer?.setTranslation(CGPoint.zero, in: view?.superview) } else if panGestureRecognizer?.state == .ended { if rotationAngle == 0 { //bounce to original frame var newFrame: CGRect? = photoImageView?.frame newFrame = handleBorderOverflow(newFrame ?? CGRect.zero) UIView.animate(withDuration: TimeInterval(BOUNDCE_DURATION), animations: { self.photoImageView?.frame = newFrame ?? CGRect.zero self.latestFrame = newFrame ?? CGRect.zero }) } else { latestFrame = photoImageView?.frame ?? CGRect.zero } } }
|
最终效果