今晚月色真美

前言

对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
}
}
}

最终效果

未命名.gif

 评论

本站总字数统计:49.8k

感谢您的浏览, 本站总访问量为 次 。
载入天数...载入时分秒...