Day 6
今天要帶大家的是第三種手勢 UIPinchGestureRecognizer,"捏" 手勢是一種連續手勢,可跟踪觸摸屏幕的前兩個手指之間的距離,那我們就裡用此偵測距離來做3D模組上的比例縮放,如下:
@objc func didPinch(_ pinch: UIPinchGestureRecognizer) {
guard let _ = object else { return }
var originalScale = object?.scale
switch pinch.state {
case .began:
originalScale = object?.scale
pinch.scale = CGFloat((object?.scale.x)!)
case .changed:
guard var newScale = originalScale else { return }
if pinch.scale < 0.0005 {
newScale = SCNVector3(x: 0.0005, y: 0.0005, z: 0.0005)
}else if pinch.scale > 2{
newScale = SCNVector3(2, 2, 2)
}else{
newScale = SCNVector3(pinch.scale, pinch.scale, pinch.scale)
}
object?.scale = newScale
case .ended:
guard var newScale = originalScale else { return }
if pinch.scale < 0.0005 {
newScale = SCNVector3(x: 0.0005, y: 0.0005, z: 0.0005)
}else if pinch.scale > 2{
newScale = SCNVector3(2, 2, 2)
}else{
newScale = SCNVector3(pinch.scale, pinch.scale, pinch.scale)
}
object?.scale = newScale
pinch.scale = CGFloat((object?.scale.x)!)
default:
pinch.scale = 1.0
originalScale = nil
}
}
UIPinchGestureRecognizer,一樣有很多種形態,這邊是用到 .began .changed .ended ,在這邊後兩者做的事基本上是一樣的,只是想確保在 .ended 時所有的數值是跟 .changed 的時候是一樣的,如果不加應該也是沒關係的。
- 首先,一樣確保 object 有值,並宣告 originalScale 記錄原先比例大小。
- 接下來我是用 switch 來判斷形態。
- .began 中,再次確認 object 原先比例大小,並將 object 的 x 軸比例轉型態為 CGFloat 給 pinch。
- .changed 中,先確認 originalScale 是否有值,並用判斷給予模組縮放大小的最大值與最小值。
- 如過都不是以上三種型態,就把比例調回初始,並清空 originalScale 。
目前已經做到三種手勢了,addGesture() 會像這樣:
func addGesture() {
let pinch = UIPinchGestureRecognizer(target: self, action: #selector(didPinch(_:)))
let rotate = UIPanGestureRecognizer(target: self, action: #selector(didRotate(_:)))
let pan = UILongPressGestureRecognizer(target: self, action: #selector(didPan(_:)))
sceneView.addGestureRecognizer(pan)
sceneView.addGestureRecognizer(pinch)
sceneView.addGestureRecognizer(rotate)
}