4

在 UIButton 的一个子类中,我将 UIButton 附加到 UIAttachmentBehavior,它允许用户用手指在屏幕上拖动按钮。

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event我将按钮添加到 UIAttachmentBehavior,然后将行为添加到 UIDynamicAnimator。在- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event我将 UIAttachmentBehavior 的锚点更新为触摸点期间;这将创建所需的拖动效果。

现在我希望使用 CGAffineTransformScale 在触摸开始时增加按钮的大小,以便用户可以看到他们手指下的按钮。我的问题是,我使用 CGAffineTransformScale 应用的转换在我添加附件行为的第二次被立即覆盖。结果是按钮快速闪烁放大,但随后又恢复到原始大小。

[_animator removeAllBehaviors]在应用 CGAffineTransformScale 之前尝试过,然后将行为添加回来。[_animator updateItemUsingCurrentState:self]在应用 CGAffineTransformScale 之后,在添加附件行为之前,我也尝试过。既不能解决问题。

更新 1:考虑到下面 HalR 的回答,我决定尝试在每次触摸时应用比例变换。因此,我将 CGAffineTransformScale 调用添加到touchesMoved:touchesEnded。我正在使用 CGAffineTransformScale 与 CGAffineTransformMakeScale,因为它允许我保留附件行为添加的轻微旋转。它让我更接近了。该按钮现在在缩放时在屏幕上移动。虽然它并不完美。当您不在屏幕上移动时会出现闪烁,如果您停止移动,但按住触摸,按钮将恢复到原始大小。差不多了……有什么建议吗?

这是我更新的代码:

@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];
}
4

1 回答 1

0

如何UIAttachmentBehavior影响视图?

它通过修改视图的变换来实现。

在这个Ray Wenderlich 教程中,Colin Eberhardt 记录了变换,因为视图受到行为的影响。

即使从未直接设置或修改转换,它也会随着视图被行为移动而改变。

所以你不能设置你的变换,并希望它保持设置,因为它是由行为设置的。

附带说明一下,如果您尝试将变换设置为按 1.5 缩放,则应使用以下命令:

self.transform = CGAffineTransformMakeScale(1.5, 1.5);

否则每次你touchesBegan被调用时,它都会再增长 50%。

在 UIDynamicAnimator 的文档中,它说:

“动态动画师会自动读取您添加到其中的每个动态项目的初始状态(位置和旋转),然后负责更新项目的状态。如果您在添加动态项目后主动更改它的状态动态动画师,调用此方法要求动画师读取并合并新状态。”

因此,只需在添加行为后调用您的转换,然后调用 updateItemUsingCurrentState:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesBegan:touches withEvent:event];

    UITouch *touch = [[event allTouches] anyObject];
    CGPoint touchLocation = [touch locationInView:self.referenceView];

    _touchAttachmentBehavior = [[UIAttachmentBehavior alloc] initWithItem:self attachedToAnchor:touchLocation];
    [_animator addBehavior:_touchAttachmentBehavior];
    self.transform = CGAffineTransformMakeScale(1.5, 1.5);
    [_animator updateItemUsingCurrentState:self];
}
于 2013-11-14T04:15:44.697 回答