1

This related SO question does display a similar issue to my own but the answer supplied does not fix my problems.

I have a refresh button which I animate when it is tapped. It's a UIBarButtonItem, created in storyboard and the image I used to create is:

enter image description here

AFAIK - the image is square and the circle depicted is centred and true.

When I tap the image I call this animation code:

#define DEGREES_TO_RADIANS(angle) ((angle) / 180.0 * M_PI)
- (void)animateRefreshButton;
{
    UIBarButtonItem *item = self.refreshButton;
    UIView *view = [item valueForKey:@"view"];

    [UIView animateWithDuration:0.5 delay:0.3 options:UIViewAnimationOptionCurveEaseInOut animations: ^
     {
         view.transform = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(180));
     } completion: ^(BOOL finished)
     {
         view.transform = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(0));

     }];
}

However the animation "jumps" and it also affects the title. See gif:

enter image description here

I have tried quite a few things but the video above is about the best animation I can get to. Things I've tried include:

  • adding the image to the buttons's custom view and animating that.
  • adjusting image insets (but it's different on every device and rotation)
  • adjusting the size of the image itself to match the size the navigation bar "turns it into", approx 50x30
  • applying different animation blocks to try and mask the "jump" (horrible)

If anyone had a similar problem and solved it then any pointers would be great

Also, if I'm mis-guided with the technique I'm using please let me know.

I did check the image and it seems fine but someone out there may know better.

Community
  • 1
  • 1
Damo
  • 12,840
  • 3
  • 51
  • 62
  • Actually, I don't see the problem in your video: There is an initial delay after the click of 0.3 sec, the image rotates by 180 degrees in 1/2 sec, and the title does not change. So, what is the problem? – Reinhard Männer Nov 11 '15 at 19:23
  • The image moves up after tapping it – Damo Nov 12 '15 at 09:02

1 Answers1

0

Ok - the secret to this was discovering that by default the image that is used by a UIBarButtonItem is re-sized to 50x30

UIBarButtonItem *item = self.refreshButton;
UIView *view = [item valueForKey:@"view"];

At this point I put a breakpoint in and checked the frame of the view and it was size 50 x 30 !

In addition I added a custom view of the rotation image, sized 50 x 30 to the button and rotated that.

#pragma mark - UIRefreshControl method(s)

- (void)configureSpinningView;
{
    // 50x30 is the size that the nav bar sets for the buttons image...

    self.refreshControlSpinningImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 50, 30)];
    self.refreshControlSpinningImageView.image = [UIImage imageNamed:@"btnSync"];
    self.refreshControlSpinningImageView.autoresizingMask = UIViewAutoresizingNone;
    self.refreshControlSpinningImageView.contentMode = UIViewContentModeCenter;

    UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(refreshTapped:)];

    [self.refreshControlSpinningImageView addGestureRecognizer:tapRecognizer];
}

#pragma mark - aimation(s)

#define DEGREES_TO_RADIANS(angle) ((angle) / 180.0 * M_PI)
- (void)animateRefreshButton;
{
    [self.refreshButton setCustomView:self.refreshControlSpinningImageView];

    [UIView animateWithDuration:0.5 delay:0.3 
options:UIViewAnimationOptionCurveEaseInOut animations: ^
    {
        self.refreshControlSpinningImageView.transform = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(180));
    } completion: ^(BOOL finished)
    {
        self.refreshControlSpinningImageView.transform = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(0));

        [self.refreshButton setCustomView:nil];
      }];
} 

#pragma mark - IBAction(s)

- (IBAction)refreshTapped:(UIBarButtonItem *)sender;
{
  //deletia

  [self animateRefreshButton];
}

Here is the video of the fix:

enter image description here

Damo
  • 12,840
  • 3
  • 51
  • 62