iOS 为移动动画中的View添加touch事件

对Core Animation来说,不管是显式动画还是隐式动画,对其设置frame都是立即设置的,比如说给一个UIView做移动动画,虽然看起来frame在持续改变,但其时它的frame已经是最终值了,这种情况下,哪怕这个UIView是UIButton的实例,其触发touch事件的范围还是最终frame的地方。比如一个Button的frame是(0,0,100,100),要把它从0,0移动到200,200,在这种情况下:

  1. 如果你使用的是显式动画(CAKeyframeAnimation和CABasicAnimation),是通过指定path或values来进行动画的,它的frame并没有改变,touch范围还是(0,0,100,100)这个范围内
  2. 如果你使用的是隐式动画,是通过设置frame来进行动画的,那么它的touch范围就是(200,200,100,100)这个范围内

如果我们要为移动动画中的View添加touch事件,就需要在后面用到hitTest。我们先创建一个动画Layer:

CGSize layerSize = CGSizeMake(100, 100);
CALayer *movingLayer = [CALayer layer];
movingLayer.bounds = CGRectMake(0, 0, layerSize.width, layerSize.height);
[movingLayer setBackgroundColor:[UIColor orangeColor].CGColor];
movingLayer.anchorPoint = CGPointMake(0, 0);
[self.view.layer addSublayer:movingLayer];
self.movingLayer = movingLayer;

这里面只有anchorPoint重要一些,因为anchorPoint能影响position的取值,对Layer来说,frame是抽象的,只有bounds和position是真实存在的,并且设置frame和设置anchorPoint的顺序不同,开始看到的结果也不同:

先设置anchorPoint开始就能得到正确的结果,即position为0,0,如果设置bounds的话就没那么麻烦,顺序就无所谓了。之所以要设置anchorPoint,是因为后面的CAKeyframeAnimation将用position来做动画,如果anchorPoint为默认值(即0.5,0.5)的话,将会出现一个x、y轴一半的偏移,一张图解释anchorPoint的取值:

position是以anchorPoint为原点的,默认这个原点在中心位置,自然就会出现x、y轴的偏移,其实只要我在动画中将position做个偏移就不用设置anchorPoint,但是我觉得动画从0到终点更直观一些,所以这才是设置anchorPoint的原因。最后用一个weak属性引用动画Layer并把这个Layer添加到self.view.layer中。

接下来是动画部分:

CAKeyframeAnimation *moveLayerAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
//moveLayerAnimation.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, 0)];
//moveLayerAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(320 - self.movingLayer.bounds.size.width, 0)];
moveLayerAnimation.values = @[[NSValue valueWithCGPoint:CGPointMake(0, 0)],
                              [NSValue valueWithCGPoint:CGPointMake(320 - self.movingLayer.bounds.size.width, 0)]];
moveLayerAnimation.duration = 2.0;
moveLayerAnimation.autoreverses = YES;
moveLayerAnimation.repeatCount = INFINITY;
moveLayerAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
[self.movingLayer addAnimation:moveLayerAnimation forKey:@"move"];

如果是用CABasicAnimation做动画,则用fromValue及toValue替换setValues,timingFunction直接用线性,不用做其他变换,关于这个属性的预置值,我在另一篇博文中有提到。
接下来为self.view添加手势识别:

........
    self.tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(click:)];
    [self.view addGestureRecognizer:self.tapGesture];
}

-(void)click:(UITapGestureRecognizer *)tapGesture {
    CGPoint touchPoint = [tapGesture locationInView:self.view];
    if ([self.movingLayer.presentationLayer hitTest:touchPoint]) {
        NSLog(@"presentationLayer");
    }
}

我在最开始的时候有提到,动画的过程只是看起来是动态变换的,其内部的值已经是固定的了,在这种情况下,Layer内部会通过复制一个当前Layer的副本来展示动画过程,而我们可以通过访问Layer的presentationLayer属性来得到这个副本的副本,通过presentationLayer我们可以知道当前动画已经进行到了屏幕的哪个位置上了,再直接通过hitTest来判定是不是一次有效点击即可。

iOS 为移动动画中的View添加touch事件

时间: 2024-10-23 07:29:43

iOS 为移动动画中的View添加touch事件的相关文章

给网页中的元素添加onclick事件(引自锋利的jQuery)

<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta name="generator" content="editplus" /> <title>给网页中的元素添加onclick事件</p></title> <script src="jquery-1.7.1

Android 源码解析View的touch事件分发机制

概述 本篇主要分析的是touch事件的分发机制,网上关于这个知识点的分析文章非常多.但是还是想通过结合自身的总结,来加深自己的理解.对于事件分发机制,我将使用两篇文章对其进行分析,一篇是针对View的事件分发机制解析,一篇是针对ViewGroup的事件分发机制解析.本片是对View的事件分发机制进行解析,主要采用案例结合源码的方式来进行分析. 前言 在分析事件分发机制之前,我们先来学习一下基本的知识点,以便后面的理解. View中有两个关键方法参与到Touch事件分发 dispatchTouch

iOS开发之动画中的时间

概述 在动画中,我们会指定动画的持续时间.例如 scaleAnimation.duration = self.config.appearDuration 那么这个时间是怎么定义的呢?是指的绝对时间吗? 层级时间结构 layer在屏幕上的显示位置是根据父layer的位置以及本身相对于父layer偏移定义的. 与此类似,每一个layer都有自己的time space,计算本地时间(local time)时候,需要根据父layer的时间以及一定的转换规则来计算出本地时间. 这个规则就是CAMediaT

填报表中也可以添加 html 事件

在实际的项目开发中,填报表的应用十分广泛. 多数情况下,填报表会作为整个项目的一部分配合需求灵活使用,但有时也会受大项目环境的影响,产生一些特别的要求.比如,通常报表单元格的数据类型大多是文本,有时却需要借助 HTML 或者 JavaScript 实现一些交互效果,例如在报表中添加一些说明性的提示.自定义功能性按钮等.显然,单纯的文本数据类型不支持这种交互操作,那么我们就会想填报表是不是能够支持 HTML 数据类型的用法呢?如果支持又该怎么使用呢? 答案肯定是支持的(你懂得),下面我们就举个栗子

Android——ViewPager和内部view之间的事件分发及轮播图

viewpager 在滑动的过程中是如何触发view身上的事件的,换句话说,viewpager在滑动的过程中到底是滑动的它里面的view,还是滑动的viewpager本身? 一.示例代码: 1.自定义ViewPager:MyViewPager,重新dispatchTouchEvent方法,添加一些事件处理的log信息. package com.example.viewpagerdemo; import android.content.Context; import android.support

自定义View系列教程07--详解ViewGroup分发Touch事件

自定义View系列教程01–常用工具介绍 自定义View系列教程02–onMeasure源码详尽分析 自定义View系列教程03–onLayout源码详尽分析 自定义View系列教程04–Draw源码分析及其实践 自定义View系列教程05–示例分析 自定义View系列教程06–详解View的Touch事件处理 自定义View系列教程07–详解ViewGroup分发Touch事件 PS:如果觉得文章太长,那就直接看视频吧 在上一篇中已经分析完了View对于Touch事件的处理,在此基础上分析和理

如何解决IOS 动画中 Autolayout 与View Transforms的冲突

IOS 的动画放大与缩小,并非按照找它的中心点放大和缩小,而是左上角 .我分析了下原来是Autolayout 与View Transforms的冲突造成的. - (void) addSubviewWithZoomInAnimation:(UIView*)view duration:(float)secs option:(UIViewAnimationOptions)option { // first reduce the view to 1/100th of its original dimen

iOS核心动画中的常用类型

CATransaction 当我们在自定义的图层上修改某些支持动画的属性时,系统会为该属性的修改自动产生动画.这种其实属于隐式动画.隐式动画要得益于CATransaction. 一个CATransaction从调用CATransaction.begin()开始,以CATransaction.commit()结束.在这其间对图层属性的修改,会受该Transaction的控制,可以通过setAnimationDuration修改Transaction的duration. 系统的隐式动画是因为在Run

[转载]iOS中侧边栏的添加

原文地址:iOS中侧边栏的添加作者:伤心的小果冻 1.添加系统框架 2.添加三方类库 3.创建一个MenuViewController作为侧边滑动时候显示的视图 //  MenuViewController.h //  sideTableView // //  Created by Dong on 13-9-26. //  Copyright (c) 2013年 dong. All rights reserved. // #import <UIKit/UIKit.h> @interface M