如何点击运动中的Button(控件)

来源:互联网 发布:手机编程用什么语言 编辑:程序博客网 时间:2024/05/18 00:30

这个问题是在之前做项目的时候遇到的,今天就顺便总结并扩展一下,由于界面动画比较多,需要点击运动中的button,在网上找了很久也没找到合适的答案,最后在解决其他问题时发现此问题的解决方案,首先还是先说明下常用的动画:

  • Core Animation动画实现位移效果
- (void)viewDidLoad {    [super viewDidLoad];    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];    button.frame = CGRectMake(100, 100, 50, 50);    button.backgroundColor = [UIColor redColor];    [button addTarget:self action:@selector(click:) forControlEvents:UIControlEventTouchUpInside];    [self.view addSubview:button];     //创建basic位移动画    CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:@"position"];    //起点,fromValue是对象类型,所以CGPoint必须封装成对象    basicAnimation.fromValue = [NSValue valueWithCGPoint:button.center];    //到哪个点,记得移动的是视图的中心点    basicAnimation.toValue   = [NSValue valueWithCGPoint:CGPointMake(100, 550)];    //动画运行总时间    basicAnimation.duration  = 3.0;    //重复次数//    basicAnimation.repeatCount = MAXFLOAT;    //是否倒退//    basicAnimation.autoreverses = YES;    //设置为线性移动    basicAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];    //设置视图在动画结束后停留在结束位置,这两个代码同时设置才有效果    basicAnimation.fillMode = kCAFillModeForwards;    basicAnimation.removedOnCompletion = NO;    //加载动画 注意这里是layer层的动画    [button.layer addAnimation:basicAnimation forKey:nil];}- (void)click:(UIButton *)button {    NSLog(@"click");}

运行程序点击button,你会发现,只有在初始化的那个位置是能够点击到的,并不能实现点击运动中的button

这里只需要添加一个类CADisplayLink,具体解释看代码实现

 - (void)viewDidLoad {    [super viewDidLoad];    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];    button.frame = CGRectMake(100, 100, 50, 50);    button.backgroundColor = [UIColor redColor];    [button addTarget:self action:@selector(click:) forControlEvents:UIControlEventTouchUpInside];    button.tag = 1000;    [self.view addSubview:button];    CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:@"position"];    //可以不写fromValue    //起点,fromValue是对象类型,所以CGPoint必须封装成对象    basicAnimation.fromValue = [NSValue valueWithCGPoint:button.center];    //到哪个点    basicAnimation.toValue   = [NSValue valueWithCGPoint:CGPointMake(100, 550)];    //动画运行总时间    basicAnimation.duration  = 100.0;    //重复次数//    basicAnimation.repeatCount = MAXFLOAT;    //是否倒退//    basicAnimation.autoreverses = YES;    //设置为线性移动    basicAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];    //设置视图在动画结束后停留在结束位置,这两个代码同时设置才有效果    basicAnimation.fillMode = kCAFillModeForwards;    basicAnimation.removedOnCompletion = NO;    //加载动画 注意这里是layer层的动画    [button.layer addAnimation:basicAnimation forKey:nil];    //创建CADisplayLink类,iPhone6中等同于屏幕刷新频率为60hz,也就是每秒调用60次displaylinkHandle方法,Pop动画看起来很流畅,就是使用了此机制    CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displaylinkHandle)];    //加入到RunLoop主事件中    [displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];} - (void)click:(UIButton *)button {    NSLog(@"click");} - (void)displaylinkHandle {    //根据tag值获取到前面创建的button    UIButton *getButton = (UIButton *)[self.view viewWithTag:1000];    //获得button的layer层,这里一定是presentationLayer,不然layer不对应    CALayer *layer = (CALayer *)[getButton.layer presentationLayer];    //获取当前layer的中心点    CGPoint point = [[layer valueForKey:@"position"] CGPointValue];    getButton.layer.position = point;}

现在点击移动中的button,可以看到控制台会不断打印消息,如此便能实现点击效果,这个只是简单的位移动画,要是动画按照贝塞尔曲线运动,view位移动画,或者是仿射变换又该如何操作,贝塞尔曲线运动和位移处理大体相同,就不在赘述了,要是真不会,就给我留言,下面就说说其他两种动画

  • view位移动画
    由于此动画必须是在动画结束时才能进行点击,所以如果要点击移动中的控件,需要将动画暂停,然后触发点击事件,再进行动画,理论上是可行的,一般来说如果需要位移动画完全可以通过layer层动画完成。

  • 仿射变换
    以中心点为圆心,在圆周上运动

- (void)viewDidLoad {    [super viewDidLoad];    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];    button.frame = CGRectMake(100, 100, 30, 30);    button.center = self.view.center;    button.backgroundColor = [UIColor redColor];    [button addTarget:self action:@selector(click:) forControlEvents:UIControlEventTouchUpInside];    button.tag = 1000;    //设置锚点    button.layer.anchorPoint = CGPointMake(-2, -2);    [self.view addSubview:button];    CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkHandle)];    [displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];}- (void)click:(UIButton *)button {    NSLog(@"click");}- (void)displayLinkHandle {    UIButton *getButton = (UIButton *)[self.view viewWithTag:1000];    getButton.layer.transform = CATransform3DRotate(getButton.layer.transform, M_PI * 2 * (1.0 / 360.0), 0, 0, 1);}

总结:在遇到问题过程中,需要学会总结,并举一反三才能扩展更多的知识,在使用CADisplayLink类时,需要记的它的方法是每秒调用60次,使用对象方法[displayLink invalidate];可以停止调用

0 0
原创粉丝点击