Motion Design for iOS——翻译3

动画翻译3

自然的动画


可以使用标准的时间曲线,但那并不是最优方案,并且不一定会带给用户令人赞叹和愉悦的感觉,因为标准时间曲线型的动画总会个人一种机械而不流畅的感觉,不像实际生活中的物件接受到外力所作出的一些反应。
如果我们想要做出真实自然的动画效果,就要探究真实环境中物体受到外力时做出的反应,然后去模仿物体当时的反应。而这个正是处理软件中的动画效果的秘密诀窍。

但是一个真实自然的动作是什么样的呢?哪个可以作为物体根据物理法则移动的例子呢?

tanhuang.png

一个在末端系着一个物体的弹簧可以很好的说明这个问题。它运动起来像是你可以预见的那样,因为你之前已经很熟悉末端带有物体的弹簧的运动轨迹。它的运动轨迹和标准的Ease曲线又是很不同的,我们看下末端有物体的弹簧的运动轨迹。

guiji.png

zuni.png

这些曲线表示的是系在弹簧末端的物体的运动轨迹,以及弹簧的张力、摩擦力和质量是如何影响这个运动轨迹的。
如果仔细观察上图中的黑色线的话,它代表的是有阻尼的系统的运动轨迹,它会在达到稳定状态之前来回的震荡。这个阻尼弹簧动作能够使动画具有弹性效果。例如:这种弹簧的动画效果几乎贯穿Facebook paper整个APP中。
中间的蓝色曲线也代表的是有阻尼的系统,但是它更加的平滑,这种细微的感觉能够使你的APP变得更加的热情洋溢和青春。
红色的曲线描绘的是基本没有弹性的并且只在基本要稳定的状态下弹射了一下。如果一个物体基本不摆动并且没有一次弹跳效果,只是简单的缓慢降速达到最终值,那么就被成为是过阻尼的。

弹簧效果的动画运动曲线和easing类型的动画曲线比较相似(因为它们都是曲线!),但是它们的实现机制是不同的。easing动画曲线是通过定义不同的贝塞尔曲线来操纵句柄来影响曲线的形状的。但是,有许多曲线和波动并不能用贝塞尔曲线来进行描述,而其中就包括质量——阻尼弹簧系统。
这种类型的运动通常备用来创作流畅的、弹簧效果的动画,可以通过末端的物体的质量、弹簧的张力、以及阻尼的大小等来影响曲线形状。

弹.png
  • 质量 是指系在弹簧末端的物体的质量。
  • 张力 是指弹簧能够拉长多少并且决定于弹簧的厚度和环绕方式。
  • 阻尼或者摩擦力 是指当你从水中拔出手或者是想要在水中快走所收到的阻力。

这些都是定义弹簧动画的关键因素。

如果你想自己封装实现一些web 、iOS或者是其它平台的弹簧效果的动画,你就必须了解一些弹簧系统动画背后的一些数学原理。而对于iOS来说,已经有了一些优秀的动画框架(由苹果公司和其它公司构建的),可以使用这些现存的框架来实现一些流畅自然、弹簧效果动画。

当我们仔细观察一些动画代码之前,我们应该讨论一下iOS的界面和动画发展。

从UIKit & 核心动画开始

从最基本的层面上将,屏幕上所显示的控件都属于UIView类。他们是矩形的,通过坐标系和纬度来定义他们显示在屏幕上的位置和尺寸。UIViewUIKit框架中用来构建界面的最基本的。每一个View有可能在内部绘有文字、形状、图片等。例如,status bar是显示在屏幕顶部的一条长的窄的View,而它内部的所有控件(时间、电池标识、信号强度指示等)都是些其他的View。
有一些特殊的UIView是具有独特的功能和属性的。像UIButton是用来构建界面按钮的,而UIImageView则是用来展示图片的,UILabel是用来展示文字信息,UITableView是用来展示一些表格数据。你也可以自定义一些View用来展示一些你想展示的任何东西
下面是一个屏幕截屏,该界面被分解为多个不同的View。

jietu.png
  • 1、carrier图片View
  • 2、WiFi信号强度指示
  • 3、当前时间
  • 4、电量指示
  • 5、“汉堡包”菜单按钮
  • 6、标题栏
  • 7、一个用来切换子菜单的按钮
  • 8、一个* UITableViewCell*的View,用来显示UITableView的一行展示的所有元素。
  • 9、UILabel展示的标题
  • 10、评论按钮,包含有评论的数目以及一个表示评论的气泡图
  • 11、显示转发URL地址的UILabel
  • 12、用UILabel展示的数据

如果你对iOS界面开发不是很熟悉的话,可以仔细观察下自己喜欢的APP,看看能不能对完成的界面进行分解,这样你就可以将他们按照分解的部分进行代码实现。

UIView承担着很多责任,其中一个就是需要响应外界的事件。界面里的任何View都可以响应外界事件,你也可以定义某些特殊的View能够响应用户对他们的点击事件。
UIView在本质上是一个包含图形内容的矩形。处于其他View的上层或者紧挨着其他View,也可能有一些很好的透明的效果。
你可以想象一下,在一个屏幕上移动View是一个多么大的挑战。

苹果公司推出核心动画的原因

核心动画Core Animation是一个快速有效实现图形复合效果动画框架。虽然他的名字里含有animation,但是如果你认为它只能做这些事情,那你就大错特错了。实际上,它负责将所有的View渲染到屏幕上、进行快速的透明度计算、图片过滤和可视效果。虽然当初是为iOS设计的,但是自从OSX 10.5以后,在Mac平台上同样适用。
为了管理由GPU渲染到屏幕上的图形内容,Core AnimationCALayer作为主力。CALayer才是那个实实在在做界面渲染工作的,实际上,UIView是封装了CALayer和核心动画,并且在苹果内部称为“Layer kit”!当你操纵屏幕上显示的View的位置或者维度的时候,你实际上是在移动它的CALayer。核心动画在硬件管理层上合成和操纵你APP界面内容的展示,使显示变得流畅而不卡顿。iOS所能实现的动画效果,都是因为核心动画框架的原因。

kuangjia.png

层可以像UIView对象一样,存在于界面等级框架中来构建交互界面。你可以用CALayer代替UIView对象来构建交互界面,就像将UIView对象放在一个父子层级关系(superview-subview)中一样,将CALayer放在父子层的层级关系(superlayer-sublayer)中。
虽然可以完全使用CALayer而不是UIView来实现界面搭建,但是大多数的iOS开发者并不是直接使用CALayer而是用UIView对象进行搭建,除非需要一次性的处理大量的图形。如果你想直接修改View的某些属性,你可以在任何时候取到相对应的layer层,例如,可以通过操纵CALayer来设置一个View对象的圆角半径(corner radius)。
简单动画


是时候上一部分代码了。让我们开始设置屏幕上一个View对象的圆角半径。因为是一个快速简单案例的原因,我们将这个UIView对象放在main window上,但是如果你是在做一个真实的APP的话,就需要将这个View对象放在管理当前屏幕的一个控制器中。

注意:如果你是刚刚开始接触iOS开发和Objective-C,我建议先看一下我写的对 Obj-C and Cocoa的[介绍]:https://designthencode.com/scratch/,也或者你可以继续学习。

UIView *redBall = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 100, 100)];
redBall.backgroundColor = [UIColor redColor];
redBall.layer.cornerRadius = 50;
[self.window addSubview:redBall];

我们创建了一个红色的UIView对象,然后通过定义他的X和Y坐标以及宽高限制在屏幕上的显示位置。我们设置它的backgroundColor为红色。像上面讲过的那样,如果要设置一个View对象的圆角,可以通过View对象的layer层来设置,所以我们使用layer.cornerRadius为50(View对象宽高的一半)。如果你将这段代码写在APP的代理文件当中-application:didFinishLaunchingWithOptions方法中,你会在程序一启动的时候就看到下面这样的情形。

hongqiu.png

是不是很有意思呢?接下来我们要给它设置动画效果了。
iOS提供了一些产生动画的机制:给一个层添加CAAnimation或者使用block来设置UIView对象的动画效果的值。接下来我们要通过block方式使UIView对象的尺寸从原始尺寸变为原来尺寸的2倍。

UIView *redBall = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 100, 100)];
redBall.backgroundColor = [UIColor redColor];
redBall.layer.cornerRadius = 50;
[self.window addSubview:redBall];

[UIView animateWithDuration:.5 delay:0
    options:UIViewAnimationOptionCurveEaseInOut animations:^{
    redBall.transform = CGAffineTransformMakeScale(2.0, 2.0);
} completion:NULL];

这段代码调用了+animateWithDuration:delay:options:animations:completion:这个UIView对象提供的一些实现动画效果方法中的其中一种。第一个参数:duration设置为0.5秒,第二个参数delay设置为0.
这个options参数是用来让我们选择动画进行的方式的,而对于本例来说我们选择了UIViewAnimationOptionCurveEaseInOut这种效果,而这种效果是一个简单的ease-in-out的时间曲线。其它的曲线有线性、 ease-in 和 ease-out。
接下来,我们在block代码块中设置了动画效果最终的状态值。核心动画会自动的在当前值和最终值之间流畅的修改尺寸的值,产生流畅的动画效果。在这个案例当中,我希望动画最终效果是球的尺寸变为原来最初尺寸的两倍,所以我设置了transform属性设置为了一个新的值,他是一个矩阵用来表示如何通过线性代数方式修改当前对象属性。有多种操纵当前View对象的transform属性的方法(缩放比例、旋转、位置)等,所以苹果提供了一系列的函数来修改这些你感兴趣的值,我们的例子中就是对缩放比例进行的修改。设置transform属性为CGAffineTransformMakeScale(2.0, 2.0),意味着我们希望除了缩放比例以外的其它属性值保持不变,而尺寸则变为原来的两倍。
因为我们并不想在这个动画结束以后有其它的动作,所以我们将完成参数设置为NULL

如果我们在block代码块中修改几个View对象相关的属性,那么这个属性值会在动画持续时间内随着尺寸大小的改变而改变。现在我们在这个代码块中继续修改一些其它相关属性。

UIView *redBall = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 100, 100)];
redBall.backgroundColor = [UIColor redColor];
redBall.layer.cornerRadius = 50;
[self.window addSubview:redBall];

[UIView animateWithDuration:.5 delay:0
    options:UIViewAnimationOptionCurveEaseInOut animations:^{
    redBall.backgroundColor = [UIColor greenColor];
    redBall.transform = CGAffineTransformConcat(
        CGAffineTransformMakeScale(2.0, 2.0),
        CGAffineTransformMakeTranslation(75, 0));
} completion:NULL];

首先,我们将backgroundColor的属性从红色变为绿色。核心动画会自动改变并添加中间颜色。
接下来,我们改变了View对象的两个transform属性:它的尺寸和位移。位移就是将View对象向上、下、左、右进行移动。在我们的案例当中,我们将View对象向右移动了75.我们使用CGAffineTransformConcat()函数将两个属性变化的动画合并成为一个,然后我们可以将一个单独的transform矩阵赋值给这个View对象。

现在理解了吗?虽然矩阵转换有点复杂并且不是太好理解,但是因为苹果的整合,所以即使你没有线性代数的额背景,也可以实现很好的动画效果。改变一个View对象的transform矩阵是一个很好地实现动画的方法。

iOS7里的弹簧动画

从iOS7开始,苹果开始给当前的动画系列中添加了弹簧效果动画方法。实际上,增加的不仅仅是这些。UIKit Dynamics框架是一个融合了物理原理的,你可以给View对象添加一些诸如万有引力现象、粘性弹簧效果以及外力的效果。
我们可以看一下iOS7更新的对额外参数实现弹簧效果的动画代码块。

UIView *redBall = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 100, 100)];
redBall.backgroundColor = [UIColor redColor];
redBall.layer.cornerRadius = 50;
[self.window addSubview:redBall];

[UIView animateWithDuration:3 delay:0 usingSpringWithDamping:.3
    initialSpringVelocity:0 options:0 animations:^{
    redBall.transform = CGAffineTransformMakeTranslation(300, 0);
} completion:NULL];

这是一个很长的方法,这里出现了一些我们之前方法中所没有出现过的参数。包括阻尼和初始的弹簧速度。弹簧的阻尼是一个介于0~1之间的值,1表示的是过阻尼弹簧系统,没有震荡效果,0表示的是没有阻尼的情况,会出现很多的震荡效果。速度参数表示的是物体初始状态下运动的快慢,这个效果在配合手势使用的时候是很有用的。
我们例子中,我们设置弹簧阻尼为0.3(一个合理的值),速度为0.动画持续时间被延长了,因为震荡效果的存在,小球要花一些时间来平复。
个人认为,iOS7提供的方法并没有按照我认为的应有的方式来运动,或者说他们并没有提供足够的接口来改进这个动画效果。当你构建了一个Mac APP并且需要这个UIKit Dynamics动画的时候就悲剧了。如果你的应用是iOS7之前的版本呢?因为你并不能在iOS7之前的版本中使用这个动画效果。
那么我们应该如何实现自然地、弹簧效果的动画呢?有么有其它的选择方案呢?我下面将给大家介绍的方案绝对算得上是很好的替代方案,我对这两个框架有着毫不掩饰的喜欢,并且在之前提交的APP中都是用了这两个框架,而且会在以后继续使用。
一个是 JNWSpringAnimation,一个是Pop by Facebook

JNWSpringAnimation

这个框架是由一个Mac和iOS开发者所写的。为了更好地理解为什么它是强大的。我们就不得不再次说说核心动画了。
像之前提到过的那样,核心动画的时间曲线是由贝塞尔曲线定义的。在核心动画里,你可以设置线性、ease——in 和ease-in-out or ease-out ,又或者你可以自主的像在CSS中一样来控制贝塞尔曲线的控制点。
但是,你并不能通过这种方式来定义弹簧动画,因为它们的形状太过高级了。那么,我们应该怎么办呢?我们能不能创作一个类似的动画效果呢?
【动画图】
除了之前我们所介绍那种复杂的不好理解的动画效果,苹果还为开发者提供了一个CAKeyframeAnimation
CAKeyframeAnimation动画是一种可以设置多个值的一种动画效果,你可以使用它来实现复杂的动画效果,比如控件上一秒在这个位置,然后下一秒在下一个方位。
JNWSpringAnimation工作的额方式是,先定义弹簧的阻尼、张力和质量,然后告诉你要进行动画的属性,然后JNWSpringAnimation会给每一个部分设置1/60秒时间的动画,并最终通过调用CAKeyframeAnimation来实现多个属性的动画效果。你所要做的,就是给CALayer设置keyframe动画效果,核心动画会一秒钟遍历这些60次知道到达最终值状态和动画完成。

让我们来看一下如何使用JNWSpringAnimation来对不同的属性实现不同的弹簧动画效果。我们将对之前的红色的球的尺寸从原始变为原来的两倍,以一种定义好的曲线效果。

JNWSpringAnimation *scale =
    [JNWSpringAnimation animationWithKeyPath:@"transform.scale"];

在一开始,我们定义一个JNWSpringAnimation对象,一个新的动画实例,并且命名为scale。我们把初始化值传递给了transform.scale,但是这是什么意思呢?这个key path只是一个我们想要实现动画效果的属性。这个是CALayer对象的一个属性,也是我们使用keyframe动画所真正要操纵的属性。还记得为什么核心动画的主力是CALayer么?

JNWSpringAnimation *scale =
    [JNWSpringAnimation animationWithKeyPath:@"transform.scale"];
scale.damping = 9;
scale.stiffness = 100;
scale.mass = 2;

我们也必须要JNWSpringAnimation知道要哪些属性产生动画效果,也要知道这些属性的开始值和终值。

JNWSpringAnimation *scale =
    [JNWSpringAnimation animationWithKeyPath:@"transform.scale"];
scale.damping = 9;
scale.stiffness = 100;
scale.mass = 2;
scale.fromValue = @(1.0);
scale.toValue = @(2.0);

既然JNWSpringAnimation知道动画的初始值和终值以及我们想要模仿的弹簧效果,现在我们可以将这些效果赋值给我们想要进行动画的小球的层(CALayer)了。

JNWSpringAnimation *scale =
    [JNWSpringAnimation animationWithKeyPath:@"transform.scale"];
scale.damping = 9;
scale.stiffness = 100;
scale.mass = 2;
scale.fromValue = @(1.0);
scale.toValue = @(2.0);

[redBall.layer addAnimation:scale forKey:scale.keyPath];

核心动画包含有三个layer层,每个曾都在展示屏幕内容中发挥着至关重要的作用。

  • 模态层(model layer )模态层显示layer的所有属性,即使是静态的没有动画的。例如,我们给一个矩形设置圆角属性,我们就是给模态层的属性进行设置。每当你修改layer的一个属性值,都会更新模态层。模态层中的属性在动画过程中不会改变,并且能够反映添加动画之前的一些状况。
  • 展示层(presentation layer)这个层显示一些正在进行动画的一些属性,不应该设置这个层中额一些属性,相反的,你可以从当前layer中读取一些当前动画中layer的一些属性。
  • 渲染层(render)用来真正的渲染屏幕上的一些图形。你不需要和它进行交互或者式知道现在的状态。

当我们给一个层添加动画的时候,动画操纵的是展示层的值,而当完成时候,动画就会自动从当前层上移除而且这个层的值也会回到layer真实的静态的值。

JNWSpringAnimation *scale =
    [JNWSpringAnimation animationWithKeyPath:@"transform.scale"];
scale.damping = 9;
scale.stiffness = 100;
scale.mass = 2;
scale.fromValue = @(1.0);
scale.toValue = @(2.0);

[redBall.layer addAnimation:scale forKey:scale.keyPath];
redBall.transform = CGAffineTransformMakeScale(2.0, 2.0);

通过手动的将transform的值改为2.0倍,layer也会保持在最终值的状态。
你也许会想,当我们用UIView动画的时候并没有遇到这种问题嘛。UIView的block形式是创建动画的一种最简便的方法。但是又要受限于默认的给定的几种动画形式或者是弹簧黄动画的版本问题。如果你想全面控制你的动画,你就要转用CAAnimation,而JNWSpringAnimation就是其中一个。

JNWSpringAnimation *scale =
    [JNWSpringAnimation animationWithKeyPath:@"transform.scale"];
scale.damping = 13;
scale.stiffness = 540;
scale.mass = 11;

scale.fromValue = @(1.0);
scale.toValue = @(2);

[redBall.layer addAnimation:scale forKey:scale.keyPath];
redBall.transform = CGAffineTransformMakeScale(2.0, 2.0);

这个弹簧动画效果就会比较慢,而且震荡幅度相对较大,

下一个例子是没有震荡效果,并且会快速的降速并且慢慢的达到最终的状态。这就是所说的过阻尼的效果。

// All the other parts of the code are the same
scale.damping = 6;
scale.stiffness = 6;
scale.mass = 1;

接下来我们看看如何实现弹簧效果的旋转动画:

JNWSpringAnimation *scale =
    [JNWSpringAnimation animationWithKeyPath:@"transform.rotation"];
scale.damping = 10;
scale.stiffness = 100;
scale.mass = 3;

scale.fromValue = @(0);
scale.toValue = @(M_PI_2);

[redBall.layer addAnimation:scale forKey:scale.keyPath];
redBall.transform = CGAffineTransformMakeRotation(M_PI_2);

因为是个旋转动画,所以初始值和最终值都会是通过弧度制来进行定义的,为了方便,我们使用CGAffineTransformMakeRotation()函数来设置模态层的值。

JNWSpringAnimation *scale = [JNWSpringAnimation
    animationWithKeyPath:@"transform.translation.x"];
scale.damping = 7;
scale.stiffness = 7;
scale.mass = 1;

scale.fromValue = @(0);
scale.toValue = @(400);

[redBall.layer addAnimation:scale forKey:scale.keyPath];
redBall.transform = CGAffineTransformMakeTranslation(400, 0);

为了达到最终效果,我们通过CGAffineTransformMakeTranslation(400, 0)属性来设置transform属性的值。

JNWSpringAnimation *scale = [JNWSpringAnimation
    animationWithKeyPath:@"transform.scale"];
scale.damping = 9;
scale.stiffness = 9;
scale.mass = 1;
scale.fromValue = @(1);
scale.toValue = @(4.0);

[redBall.layer addAnimation:scale forKey:scale.keyPath];
redBall.transform = CGAffineTransformScale(redBall.transform, 4.0, 4.0);

JNWSpringAnimation *rotate = [JNWSpringAnimation
    animationWithKeyPath:@"transform.rotation"];
rotate.damping = 9;
rotate.stiffness = 9;
rotate.mass = 1;
rotate.fromValue = @(0);
rotate.toValue = @(M_PI);

[redBall.layer addAnimation:rotate forKey:rotate.keyPath];
redBall.transform = CGAffineTransformRotate(redBall.transform, M_PI);

第一个动画是一个尺寸从1.0 ~ 4.0倍大小变化的动画,第一个不同点是,这个动画结合了之前的例子的效果。
这里我们使用了CGAffineTransformScale()而不是CGAffineTransformMakeScale()函数,CGAffineTransformMakeScale(),使用这个函数的原因是我们把当前的变化效果作为第一个参数,一起操纵这个layer的转变矩阵。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,347评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,435评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,509评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,611评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,837评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,987评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,730评论 0 267
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,194评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,525评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,664评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,334评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,944评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,764评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,997评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,389评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,554评论 2 349

推荐阅读更多精彩内容

  • 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥ios动画全貌。在这里你可以看...
    每天刷两次牙阅读 8,471评论 6 30
  • 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥iOS动画全貌。在这里你可以看...
    F麦子阅读 5,104评论 5 13
  • 目录 ** UIView 动画 ** ** Core Animation ** ** FaceBook POP动画...
    方向_4d0d阅读 1,594评论 0 3
  • 在iOS实际开发中常用的动画无非是以下四种:UIView动画,核心动画,帧动画,自定义转场动画。 1.UIView...
    请叫我周小帅阅读 3,082评论 1 23
  • 1. 磁盘 1.1 seq_page_cost 描述:顺序磁盘访问时单个页面的读取开销,默认为1.0 场景说明:在...
    thought阅读 1,198评论 0 2