In a subclass of UIButton, I attach the UIButton to a UIAttachmentBehavior that lets a user drag the button around the screen with their finger.
In - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
I add the button to the UIAttachmentBehavior, then add the behavior to the UIDynamicAnimator. During - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
I update the anchor of the UIAttachmentBehavior to the touch point; this creates the desired drag effect.
Now I wish to use CGAffineTransformScale to increase the size of the button when the touch begins so the user can see the button under their finger. My issue is that the transform I apply with CGAffineTransformScale is immediately over written the second I add the attachment behavior. The result is a quick flicker of the button scaling up, but then it returns back to the original size.
I have tried [_animator removeAllBehaviors]
before applying the CGAffineTransformScale, then adding the behaviors back. I have also tried [_animator updateItemUsingCurrentState:self]
after applying the CGAffineTransformScale, just before adding the attachment behavior. Neither resolve the issue.
UPDATE 1: Thinking about HalR's answer below, I decided to try applying the scale transform with every touch. So, I added the CGAffineTransformScale call to both the touchesMoved:
and touchesEnded
. I am using CGAffineTransformScale vs CGAffineTransformMakeScale because it allows me to preserve the slight rotation the attachment behavior adds. It got me a lot closer. The button now moves around the screen while being scaled. It isn't perfect though. There is a flicker when you are not moving around the screen, and if you stop moving, but keep the touch down, the button returns to the original size. Almost there...any suggestions?
Here is my updated code:
@interface DragButton : UIButton < UIDynamicAnimatorDelegate >
#import "DragButton"
#import <QuartzCore/QuartzCore.h>
@implementation DragButton
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesBegan:touches withEvent:event];
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation = [touch locationInView:self.referenceView];
self.transform = CGAffineTransformMakeScale(1.5, 1.5);
_touchAttachmentBehavior = [[UIAttachmentBehavior alloc] initWithItem:self attachedToAnchor:touchLocation];
[_animator addBehavior:_touchAttachmentBehavior];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesMoved:touches withEvent:event];
UITouch *touch = [[event allTouches] anyObject];
CGPoint touchLocation = [touch locationInView:self.referenceView];
self.transform = CGAffineTransformScale(self.transform, 1.5, 1.5);
_touchAttachmentBehavior.anchorPoint = touchLocation;
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesEnded:touches withEvent:event];
self.transform = CGAffineTransformScale(self.transform, 1.5, 1.5);
[_animator removeBehavior:_touchAttachmentBehavior];
}