CALayer 动画缩放,中心固定在 iOS7

CALayer Animation Scale with fixed centre on iOS7

我一直在为我认为会很容易的事情而苦思冥想。一个脉冲圈,SO上有几个例子,但我仍然无法解决最后一件事。

使用下面的代码,我确实有一个可以很好地扩展和收缩的圆,但是在收缩期间,缩放是从 CGRect 的图层框架(左上角)完成的。扩展工作正常,expansion/contraction 在 iOS8 上工作正常。问题只发生在 iOS7.

我试过设置锚点,在展开时平移视图……似乎没有任何效果……我做错了什么,我不知道是什么。

如果有人想尝试使用下面的代码,您只需要一个 UIViewController、一个标签和一个按钮,连接到下面的 IBOutlets。

这是我在将我的应用程序提交到 App Store 之前的最后一个已知错误...:\

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController


@end




#import "ViewController.h"

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UILabel *label;
@property (weak, nonatomic) IBOutlet UIButton *button;
@property (nonatomic) BOOL isExpanded;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.isExpanded = YES;
    self.label.layer.cornerRadius = self.label.frame.size.width/2;
    self.label.layer.masksToBounds = YES;

    // Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
-(void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];

}
- (IBAction)ExpandOrCollapse:(id)sender {
    [self.button setEnabled:NO];
    CGFloat animationDuration = 0.30f; // Your duration
    CGFloat animationDelay = 0.0f; // Your delay (if any)

    if (self.isExpanded) {

       CGAffineTransform t = CGAffineTransformMakeScale(.17f, .17f);

        CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
        scaleAnimation.duration = animationDuration;
        scaleAnimation.fromValue = [NSNumber numberWithFloat:1.0f];

        scaleAnimation.toValue = [NSNumber numberWithFloat:0.17f];

        [self.label.layer addAnimation:scaleAnimation forKey:@"scale"];

        [UIView animateWithDuration:animationDuration
                              delay:animationDelay
                            options: UIViewAnimationOptionCurveEaseIn
                         animations:^{
                         }
                         completion:^(BOOL finished){
                             self.isExpanded = NO;
                             [self.label setTransform:t];
                             [self.button setEnabled:YES];
                         }];
    }else{

        CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
        scaleAnimation.duration = animationDuration;

        scaleAnimation.fromValue = [NSNumber numberWithFloat:0.17f];

        scaleAnimation.toValue = [NSNumber numberWithFloat:1.0f];

        [self.label.layer addAnimation:scaleAnimation forKey:@"scale"];

        [UIView animateWithDuration:0.3
                              delay:0
                            options: UIViewAnimationOptionCurveEaseIn
                         animations:^{

                         }
                         completion:^(BOOL finished){
                             [self.button setEnabled:YES];
                             [self.label setTransform:CGAffineTransformMakeScale(1.0, 1.0f)];
                             self.isExpanded = YES;
                         }];
    }
}
@end

编辑

对于 eiran,这是他修改后的代码。不幸的是问题仍然存在..

    #import "ViewController.h"

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UILabel *label;
@property (weak, nonatomic) IBOutlet UIButton *button;
@property (nonatomic) BOOL isExpanded;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.isExpanded = YES;
    self.label.layer.cornerRadius = self.label.frame.size.width/2;
    self.label.layer.masksToBounds = YES;

    // Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
-(void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];

}
- (IBAction)ExpandOrCollapse:(id)sender {
    [self.button setEnabled:NO];
    CGFloat animationDuration = 0.30f; // Your duration
    CGFloat animationDelay = 0.0f; // Your delay (if any)

    if (self.isExpanded) {
        [UIView animateWithDuration:animationDuration
                              delay:animationDelay
                            options: UIViewAnimationOptionCurveEaseIn
                         animations:^{
                             [self.label setTransform:CGAffineTransformScale(CGAffineTransformIdentity, 0.17f, 0.17f)];
                         }
                         completion:^(BOOL finished){
                             self.isExpanded = NO;
                             [self.button setEnabled:YES];
                         }];
    }else{

        [UIView animateWithDuration:0.3
                              delay:0
                            options: UIViewAnimationOptionCurveEaseIn
                         animations:^{
                             [self.label setTransform:CGAffineTransformScale(CGAffineTransformIdentity, 1.0f, 1.0f)];
                         }
                         completion:^(BOOL finished){
                             [self.button setEnabled:YES];

                             self.isExpanded = YES;
                         }];
    }
}

这似乎对我有用:

[UIView animateWithDuration:0.75
                      delay:0
                    options:UIViewAnimationOptionRepeat|UIViewAnimationOptionAutoreverse|UIViewAnimationOptionAllowUserInteraction
                 animations:^{
                     self.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.95, 0.95);
                 }completion:^(BOOL b){
                 }];

这是一个重复缩放动画。

编辑: 那么好吧:)苹果以神秘的方式工作。 我已经为您找到了解决方案,但我不确定问题出在哪里。 在 ios 7.1 中,如果您使用情节提要,缩放会按您所说的进行。 但是,如果您动态添加组件,则动画效果很好。将此添加到您的代码中并查看:

      - (void)viewDidLoad {
    [super viewDidLoad];
    self.isExpanded = YES;


    UIButton* b = [UIButton buttonWithType:UIButtonTypeCustom];
    [b setFrame:CGRectMake(100, 400, 120, 40)];
    [b addTarget:self action:@selector(expand:) forControlEvents:UIControlEventTouchUpInside];
    [b setBackgroundColor:[UIColor blueColor]];
    [b setTitle:@"added dynamically" forState:UIControlStateNormal];
    [self.view addSubview:b];

    }

    -(void)expand:(UIButton*)sender{
        CGFloat animationDuration = 0.30f; // Your duration
        CGFloat animationDelay = 0.0f; // Your delay (if any)

    if (self.isExpanded) {
        [UIView animateWithDuration:animationDuration
                              delay:animationDelay
                            options: UIViewAnimationOptionCurveEaseIn
                         animations:^{
                             [sender setTransform:CGAffineTransformScale(CGAffineTransformIdentity, 0.8f, 0.8f)];
                         }
                         completion:^(BOOL finished){
                             self.isExpanded = NO;
                         }];
    }else{

        [UIView animateWithDuration:0.3
                              delay:0
                            options: UIViewAnimationOptionCurveEaseIn


                    animations:^{
                         [sender setTransform:CGAffineTransformScale(CGAffineTransformIdentity, 1.0f, 1.0f)];
                     }
                     completion:^(BOOL finished){
                         self.isExpanded = YES;
                     }];
}

}

正如你所说,它固定在 ios 8。 我认为这可能与约束有关,但看起来没有。

在此处添加了一个演示此测试的项目: the test

希望对你有帮助,英兰。