Reputation: 267
I am working on the Pinch Gesture for a 3D Model in Arkit, I am having an issue, When i scale the Model it lags and doesn't give me the smooth response. It's working fine but i need to make it smoother.
@objc func scalePiece(gestureRecognizer : UIPinchGestureRecognizer) { guard gestureRecognizer.view != nil else { return }
if gestureRecognizer.state == .began || gestureRecognizer.state == .changed {
let scale = Float(gestureRecognizer.scale)
let newscalex = scale / currentscalex
let newscaley = scale / currentscaley
let newscalez = scale / currentscalez
self.drone.scale = SCNVector3(newscalex, newscaley, newscalez)
}}
Any tips would be appreciated.
Upvotes: 0
Views: 1315
Reputation: 2415
Replace the / by * both for all three axis and reset the scale of gesture recognizer. In other words multiply with the scale instead of dividing the scale.
To prevent it from scaling exponentially, reset the gestureRecognizer.scale after you read it, to 1.0. For example:
if gestureRecognizer.state == .began || gestureRecognizer.state == .changed {
let scale = Float(gestureRecognizer.scale)
let newscalex = scale * self.drone.scale.x
let newscaley = scale * self.drone.scale.y
let newscalez = scale * self.drone.scale.z
self.drone.scale = SCNVector3(newscalex, newscaley, newscalez)
gestureRecognizer.scale = 1.0
}
Resetting the gestureRecognizer is basically an alternative approach to storing the original scale in state began and applying the scale factor from the recognizer to that one before assigning it to the current. This situation is described specifically in the docs: https://developer.apple.com/documentation/uikit/touches_presses_and_gestures/handling_uikit_gestures/handling_pinch_gestures in the Important note.
Upvotes: 1
Reputation: 1611
You may have some logic behind currentscale
and calculated newscale
, but simply gestureRecognizer.scale
gives smooth scaling. I think you get jerky scaling because you set scale
directly. Use SCNAction.scale
let action = SCNAction.scale(by: gestureRecognizer.scale, duration: 0.1)
lv.runAction(action)
gestureRecognizer.scale = 1
instead of
self.drone.scale = SCNVector3(newscalex, newscaley, newscalez)
And if you have different scale value for x,y,z then use customAction
let action = SCNAction.customAction(duration: 0.1) { (yourNode, elapsedTime) in
let percentage = elapsedTime / 0.1
let newscalex = scale / currentscalex * percentage
let newscaley = scale / currentscaley * percentage
let newscalez = scale / currentscalez * percentage
yourNode.scale = SCNVector3(newscalex, newscaley, newscalez)
}
Upvotes: 3