2013-11-14 4 views
3

В подклассе UIButton я прикрепляю UIButton к UIAttachmentBehavior, который позволяет пользователю перетаскивать кнопку по экрану пальцем.Использование CGAffineTransformScale с UIAttachmentBehavior (UIDynamicAnimator)

В - (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 vs 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]; 
} 
+1

вы пытались добавить UIImageView подвида к кнопке, и применяя ваши преобразования к слою этого подвид, и, таким образом, оставляя свое поведение, чтобы иметь свой путь с помощью кнопки, то подвью будет использовать его преобразование поверх этого? – HalR

ответ

0

Как UIAttachmentBehavior влияет на вид?

Он делает это, изменяя преобразование вида.

В этом Ray Wenderlich tutorial Колин Эберхардт регистрирует преобразование, так как на представление влияет поведение.

Несмотря на то, что преобразование никогда не устанавливается или не изменяется напрямую, оно изменяется, когда представление перемещается поведением.

Таким образом, вы не можете установить свое преобразование и надеяться, что он останется установленным, потому что он задается поведением.

В стороне записки, если вы пытаетесь установить преобразование в масштабе 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]; 
} 
+0

Righ t, UIAttachmentBehavior изменяет преобразование. Но почему я не могу сказать, что это «изменить измененное» преобразование? Моя интерпретация документации для 'updateItemUsingCurrentState:' заключается в том, что она должна позволить мне активно изменять масштаб. 'Динамический аниматор автоматически считывает начальное состояние (положение и вращение) каждого динамического элемента, который вы добавляете к нему, а затем берет на себя ответственность за обновление состояния элемента. Если вы активно изменяете состояние динамического элемента после добавления его в динамический аниматор, вызовите этот метод, чтобы попросить аниматора прочитать и включить новое состояние. – chazzwozzer

+0

BTW, спасибо за отзыв на CGAffineTransformMakeScale ... good вызов. – chazzwozzer