0

Much like other apps, my app has a "welcome" page controller with a quick overview of the features. During this overview, I draw a UITabBar and have a circle show where the relevant feature is seen below:

Circle over UITabBarItem

I draw the circle using the following code that is executed every time a page is drawn:

double circleSize = 75;
[circleView removeFromSuperview];
circleView = [[UIView alloc] initWithFrame:CGRectMake(circleX,
                                                      circleY,
                                                      circleSize,
                                                      circleSize)];
circleView.layer.cornerRadius = (circleSize / 2);
circleView.layer.borderColor = [UIColor VancityTransitBlue].CGColor;
circleView.layer.borderWidth = 2;

I wish to have this circle appear to "breath" (grow slowly then shrink back to its original size). I use the exact code from my answer to this question:

[UIView animateWithDuration:1
                      delay:0
                    options:UIViewKeyframeAnimationOptionAutoreverse | UIViewKeyframeAnimationOptionRepeat
                 animations:^{
                     circleView.transform = CGAffineTransformMakeScale(1.5, 1.5);
                 }
                 completion:nil];

This circle is shared across three pages of the page controller and draws just fine. The animation works just fine on the first page, periodically works on the second page, and never works on the third page.

How can I have the animation play on every page for every circle view?

ecnepsnai
  • 1,882
  • 4
  • 28
  • 56

2 Answers2

1

Here is a solution that works across all tabs. The animation can be moved around while in progress. You may want to use a better mechanism to manage the animation so that it can be cancelled efficiently. The code below is implemented in the Tab Controller. Ensure -showOverTabBarItem: and -hideCircleView are executed on main thread. It has been built, linked, ran and tested.

enter image description here

Show

-(void)showOverTabBarItem:(CGFloat)x {
    [self hideCircleView];

    self.circleView.frame =({
        CGRect frame = self.circleView.frame;
        frame.origin.x = x;
        frame;
    });
    [self.view addSubview:self.circleView];

    [UIView animateWithDuration:1
                          delay:0
                        options:UIViewKeyframeAnimationOptionAutoreverse | UIViewKeyframeAnimationOptionRepeat
                     animations:^{
                         self.circleView.transform = CGAffineTransformMakeScale(1.5, 1.5);
                     }
                     completion:nil];
}

Hide

-(void)hideCircleView { [self.circleView removeFromSuperview]; }

Initialize

Such as in viewDidLoad.

double circleSize = 75;
CGFloat circleY = self.view.bounds.size.height-(circleSize/2);

self.circleView = [[UIView alloc] initWithFrame:CGRectMake(0,
                                                           circleY,
                                                           circleSize,
                                                           circleSize)];
self.circleView.layer.cornerRadius = (circleSize / 2);
self.circleView.layer.borderColor = [UIColor blueColor].CGColor;
self.circleView.layer.borderWidth = 2;

Invoke

Pass the horizontal position to your animation: [self showOverTabBarItem: self.view.bounds.size.width/2];

Keep the view around

This is a critical step: when your -removeFromSuperView, you want to make sure that the object does not get recycled.

@interface TabController ()
@property (nonatomic, retain) UIView * circleView;
@end
SwiftArchitect
  • 47,376
  • 28
  • 140
  • 179
0

Why have you alloc the circle every time a page drawn?

You can remove these lines (just need these for the first init):

if (circleView == nil) {
    circleView = [[UIView alloc] initWithFrame:CGRectMake(circleX,
                                                          circleY,
                                                          circleSize,
                                                          circleSize)];
    circleView.layer.cornerRadius = (circleSize / 2);
    circleView.layer.borderColor = [UIColor VancityTransitBlue].CGColor;
    circleView.layer.borderWidth = 2;
}

For add to another page: remove from current page

    [circleView removeFromSuperview];
    [circleView.layer removeAllAnimations];

and then add it to another page:

[self.view addSubView:circleView];
[UIView animateWithDuration:1
                      delay:0
                    options:UIViewKeyframeAnimationOptionAutoreverse | UIViewKeyframeAnimationOptionRepeat
                 animations:^{
                     circleView.transform = CGAffineTransformMakeScale(1.5, 1.5);
                 }
                 completion:nil];
tuledev
  • 10,177
  • 4
  • 29
  • 49
  • Err, are you suggesting that I add that line? Because it's already there... 2nd line of the 1st code block. – ecnepsnai Aug 13 '15 at 06:03
  • @ecnepsnai I edited my answer. Can you show more details about [UIView animateWithDuration ...] ?. E.g.: Where did you place this line?, ... – tuledev Aug 13 '15 at 06:07
  • It's in the same scope as the first code block, and I call `[self.view addSubView:circleView];` immediately after. – ecnepsnai Aug 13 '15 at 06:09
  • @ecnepsnai can you try with my codes? And what's happen? – tuledev Aug 13 '15 at 06:18