Reputation: 2523
I have a view that has a pan gesture recognizer on it to grow the overall height of the view as you swipe it up or down. This works well enough for now but I also wanted to add a drop shadow that I had designed and make sure that it kept with the height of the changing draggable view. However, this is producing some strange effects and I want to see if there is a way to fix this
The relevant code to handle changing the view height and the shadow height is as follows
// SET SHADOW FOR DRAGABLE VIEW PATH IN VIEW DID LOAD
draggableView.layer.shadowColor = UIColor.black.cgColor
draggableView.layer.shadowOffset = CGSize(width: 0, height: 12)
draggableView.layer.shadowOpacity = 0.33
draggableView.layer.shadowRadius = 8
draggableView.layer.shadowPath = UIBezierPath(roundedRect:
draggableView.bounds, cornerRadius: 12).cgPath
// INSIDE THE RECOGNIZER HANDLER
if recognizer.state == .began || recognizer.state == .changed {
translation = recognizer.translation(in: self.view)
recognizer.setTranslation(CGPoint(x: 0.0, y: 0.0), in: self.view)
let endPosition = recognizer.location(in: draggableView) // the posiion at which PanGesture Ended
difference = endPosition.y - startPosition.y
var newFrame = draggableView.frame
newFrame.origin.x = draggableView.frame.origin.x
newFrame.origin.y = draggableView.frame.origin.y + difference
// HERE WE SET THE HEIGHT OF THE VIEW THAT IS BEING "DRAGGED"
newFrame.size.height = draggableView.frame.size.height - difference
// HERE WE UPDATE THE SHADOW PATH WITH THE NEW DRAGGABLE VIEW BOUNDS
draggableView.layer.shadowPath = UIBezierPath(roundedRect: draggableView.bounds, cornerRadius: 12).cgPath
draggableView.frame = newFrame
}
The effect I'm getting is the shadow not quite updating in time with the current pan gesture, here is a gif of what that looks like
I'm hoping there is a way I can get this to work without this weird behavior, I'm fairly new to swift though I understand the concepts it's more about not really knowing all the best ways to go about doing things
Upvotes: 1
Views: 769
Reputation: 25261
You need to invert the order of the following two lines of code
draggableView.layer.shadowPath = UIBezierPath(roundedRect: draggableView.bounds, cornerRadius: 12).cgPath
draggableView.frame = newFrame
The reason is that you are updating the potision (Frame) of your draggableView
in the PanGesture delegate method. However, you are updating the shadow frame (line 1) BEFORE updating the position (frame) of the draggable view (line 2). So, inverting the two lines will work for you
In your case, you are updating frames of two views (draggable and shadow). We can see that the CPU is struggling trying to updating both of them since it's lagging (especially in the shadow part since you are re-drawing it.)
My suggestions is that you can create a parent transparent view and put your current draggable view inside and draw the shadow. This will happen only once in your viewDidLoad
. Then inside gesture deletege, you will only update frame of the parent view. In this case, you do not need to update the shadow every time and the dragging will be more smooth
Upvotes: 1