iOS 动画从入门到无需可入!

一、简介

iOS动画主要是指Core Animation框架。官方使用文档地址为:Core Animation Guide。Core Animation是iOS和macOS平台上负责图形渲染与动画的基础框架。Core Animation可以作用与动画视图或者其他可视元素,为你完成了动画所需的大部分绘帧工作。你只需要配置少量的动画参数(如开始点的位置和结束点的位置)即可使用Core Animation的动画效果。Core Animation将大部分实际的绘图任务交给了图形硬件来处理,图形硬件会加速图形渲染的速度。这种自动化的图形加速技术让动画拥有更高的帧率并且显示效果更加平滑,不会加重CPU的负担而影响程序的运行速度。

乔帮主在2007年的WWDC大会上亲自为你演示Core Animation的强大:点击查看视频

二.iOS动画的调用方式

第一种调用方式:
_demoView.frame = CGRectMake(0, SCREEN_HEIGHT/2-50, 50, 50);
        [UIView animateWithDuration:1.0f animations:^{
      _demoView.frame = CGRectMake(SCREEN_WIDTH, SCREEN_HEIGHT/2-50, 50, 50);
} completion:^(BOOL finished) {
_demoView.frame = CGRectMake(SCREEN_WIDTH/2-25, SCREEN_HEIGHT/2-50, 50, 50);
}];
第二种:UIView [begin commit]模式(首尾式)
_demoView.frame = CGRectMake(0, SCREEN_HEIGHT/2-50, 50, 50);
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0f];
_demoView.frame = CGRectMake(SCREEN_WIDTH, SCREEN_HEIGHT/2-50, 50, 50);
[UIView commitAnimations];
其中最为有价值的是一个叫动画组的概念是进行UIimageView的帧动画
  //  1.3把数组存入UIImageView中
    self.animationImageView.animationImages = array;
    
    //  1.4  option
    self.animationImageView.animationRepeatCount = 1;
    
    //  fps  12
    self.animationImageView.animationDuration = frames / 12;
    
    //  1.5播放动画
    [self.animationImageView startAnimating];

//    self.animationImageView.animationImages = nil;
    
    [self.animationImageView performSelector:@selector(setAnimationImages:) withObject:nil afterDelay:self.animationImageView.animationDuration];
demo2.gif
第三种调用动画方式- 核心动画
  • 核心动画基本概念
  • 基本动画
  • 关键帧动画
  • 动画组
  • 转场动画

三.Core Animation简介

Core Animation,中文翻译为核心动画,它是一组非常强大的动画处理API,使用它能做出非常炫丽的动画效果,而且往往是事半功倍。也就是说,使用少量的代码就可以实现非常强大的功能。
Core Animation可以用在Mac OS X和iOS平台。
Core Animation的动画执行过程都是在后台操作的,不会阻塞主线程。
要注意的是,Core Animation是直接作用在CALayer上的,并非UIView

一.核心动画继承结构
image.png
二.Core Animation的使用步骤

开发步骤:
1.首先得有CALayer
2.初始化一个CAAnimation对象,并设置一些动画相关属性
3.通过调用CALayer的addAnimation:forKey:方法,增加CAAnimation对象到CALayer中,这样就能开始执行动画了
4.通过调用CALayer的removeAnimationForKey:方法可以停止CALayer中的动画

三.CAAnimation——简介

是所有动画对象的父类,负责控制动画的持续时间和速度,是个抽象类,不能直接使用,应该使用它具体的子类
属性说明:(红色代表来自CAMediaTiming协议的属性)

  • duration:动画的持续时间
  • repeatCount:重复次数,无限循环可以设置HUGE_VALF或者MAXFLOAT
  • repeatDuration:重复时间
  • removedOnCompletion:默认为YES,代表动画执行完毕后就从图层上移除,图形会恢复到动画执行前的状态。如果想让图层保持显示动画执行
    后的状态,那就设置为NO,不过还要设置fillMode为kCAFillModeForwards
  • fillMode:决定当前对象在非active时间段的行为。比如动画开始之前或者动画结束之后
  • beginTime:可以用来设置动画延迟执行时间,若想延迟2s,就设置为-
    CACurrentMediaTime()+2,CACurrentMediaTime()为图层的当前时间
  • timingFunction:速度控制函数,控制动画运行的节奏
  • delegate:动画代理
四.CAAnimation——动画填充模式
fillMode属性值(要想fillMode有效,最好设置removedOnCompletion = NO)
  • kCAFillModeRemoved 这个是默认值,也就是说当动画开始前和动画结束后,动画对layer都没有影响,动画结束后,layer会恢复到之前的状态
  • kCAFillModeForwards 当动画结束后,layer会一直保持着动画最后的状态
  • kCAFillModeBackwards 在动画开始前,只需要将动画加入了一个layer,layer便立即进入动画的初始状态并等待动画开始。
  • kCAFillModeBoth 这个其实就是上面两个的合成.动画加入后开始之前,layer便处于动画初始状态,动画结束后layer保持动画最后的状态
五.CAAnimation——速度控制函数

速度控制函数(CAMediaTimingFunction)

  • kCAMediaTimingFunctionLinear(线性):匀速,给你一个相对静态的感觉
  • kCAMediaTimingFunctionEaseIn(渐进):动画缓慢进入,然后加速离开
  • kCAMediaTimingFunctionEaseOut(渐出):动画全速进入,然后减速的到达目的地
  • kCAMediaTimingFunctionEaseInEaseOut(渐进渐出):动画缓慢的进入,中间加速,然后减速的到达目的地。这个是默认的动画行为。
六.CALayer上动画的暂停和恢复
#pragma mark 暂停CALayer的动画
-(void)pauseLayer:(CALayer*)layer
{
    CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];

    // 让CALayer的时间停止走动
      layer.speed = 0.0;
    // 让CALayer的时间停留在pausedTime这个时刻
    layer.timeOffset = pausedTime;
}
CALayer上动画的恢复
#pragma mark 恢复CALayer的动画
-(void)resumeLayer:(CALayer*)layer
{
    CFTimeInterval pausedTime = layer.timeOffset;
    // 1. 让CALayer的时间继续行走
      layer.speed = 1.0;
    // 2. 取消上次记录的停留时刻
      layer.timeOffset = 0.0;
    // 3. 取消上次设置的时间
      layer.beginTime = 0.0;    
    // 4. 计算暂停的时间(这里也可以用CACurrentMediaTime()-pausedTime)
    CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
    // 5. 设置相对于父坐标系的开始时间(往后退timeSincePause)
      layer.beginTime = timeSincePause;
}
七.CAPropertyAnimation

是CAAnimation的子类,也是个抽象类,要想创建动画对象,应该使用它的两个子类:
CABasicAnimation
CAKeyframeAnimation

属性说明:

  • keyPath:通过指定CALayer的一个属性名称为keyPath(NSString类型),并且对CALayer的这个属性的值进行修改,达到相应的动画效果。比如,指定@“position”为keyPath,就修改CALayer的position属性的值,以达到平移的动画效果
八.CABasicAnimation——基本动画

基本动画,是CAPropertyAnimation的子类

属性说明:

  • fromValue:keyPath相应属性的初始值
  • toValue:keyPath相应属性的结束值

动画过程说明:

  • 随着动画的进行,在长度为duration的持续时间内,keyPath相应属性的值从fromValue渐渐地变为toValue
  • keyPath内容是CALayer的可动画Animatable属性
  • 如果fillMode=kCAFillModeForwards同时removedOnComletion=NO,那么在动画执行完毕后,图层会保持显示动画执行后的状态。但在实质上,图层的属性值还是动画执行前的初始值,并没有真正被改变。
baseAnimation.gif
九.CAKeyframeAnimation——关键帧动画
  • 关键帧动画,也是CAPropertyAnimation的子类,与CABasicAnimation的区别是:
    CABasicAnimation只能从一个数值(fromValue)变到另一个数值(toValue),而CAKeyframeAnimation会使用一个NSArray保存这些数值

属性说明:

  • values:上述的NSArray对象。里面的元素称为“关键帧”(keyframe)。动画对象会在指定的时间(duration)内,依次显示values数组中的每一个关键帧
  • path:可以设置一个CGPathRef、CGMutablePathRef,让图层按照路径轨迹移动。path只对CALayer的anchorPoint和position起作用。如果设置了path,那么values将被忽略
  • keyTimes:可以为对应的关键帧指定对应的时间点,其取值范围为0到1.0,-

![Uploading keyframeAnimation_390929.gif . . .]
keyTimes中的每一个时间值都对应values中的每一帧。如果没有设置keyTimes,各个关键帧的时间是平分的

CABasicAnimation可看做是只有2个关键帧的CAKeyframeAnimation

keyframeAnimation.gif
十.CAAnimationGroup——动画组
  • 动画组,是CAAnimation的子类,可以保存一组动画对象,将CAAnimationGroup对象加入层后,组中所有动画对象可以同时并发运行

属性说明:

  • animations:用来保存一组动画对象的NSArray
  • 默认情况下,一组动画对象是同时运行的,也可以通过设置动画对象的-
    beginTime属性来更改动画的开始时间
animationGroup.gif
十一.转场动画——CATransition
  • CATransition是CAAnimation的子类,用于做转场动画,能够为层提供移出屏幕和移入屏幕的动画效果。iOS比Mac OS X的转场动画效果少一点
  • UINavigationController就是通过CATransition实现了将控制器的视图推入屏幕的动画效果
  • 动画属性:
  • type:动画过渡类型
  • subtype:动画过渡方向
  • startProgress:动画起点(在整体动画的百分比)
  • endProgress:动画终点(在整体动画的百分比)
subtype:动画过渡方向
    kCATransitionFromRight 从右侧进入
    kCATransitionFromLeft 从左侧进入
    kCATransitionFromTop 从顶部进入
    kCATransitionFromBottom 从底部进入
    startProgress:动画起点(在整体动画的百分比)
    endProgress:动画终点(在整体动画的百分比)
transition.gif
image.png
Apple 官方的SDK其实只提供了四种过渡效果。
  • kCATransitionFade 渐变效果
  • kCATransitionMoveIn 进入覆盖效果
  • kCATransitionPush 推出效果
  • kCATransitionReveal 揭露离开效果
    注意点
  • 私有api,不建议开发者们使用。因为苹果公司不提供维护,并且有可能造成你的app审核不通过。

四.使用UIView动画函数实现转场动画

单视图
+ (void)transitionWithView:(UIView *)view duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion;

参数说明:

  • duration:动画的持续时间
  • view:需要进行转场动画的视图
  • options:转场动画的类型
  • animations:将改变视图属性的代码放在这个block中
  • completion:动画结束后,会自动调用这个block
双视图
+ (void)transitionFromView:(UIView *)fromView toView:(UIView *)toView duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options completion:(void (^)(BOOL finished))completion;

参数说明:

  • duration:动画的持续时间
  • options:转场动画的类型
  • animations:将改变视图属性的代码放在这个block中
  • completion:动画结束后,会自动调用这个block

五.粒子动画

粒子动画.gif
在iOS 5中,苹果引入了一个新的CALayer子类叫做CAEmitterLayer。CAEmitterLayer是一个高性能的粒子引擎,被用来创建实时例子动画如:烟雾,火,雨等等这些效果。

CAEmitterLayer看上去像是许多CAEmitterCell的容器,这些CAEmitierCell定义了一个例子效果。你将会为不同的例子效果定义一个或多个CAEmitterCell作为模版,同时CAEmitterLayer负责基于这些模版实例化一个粒子流。一个CAEmitterCell类似于一个CALayer:它有一个contents属性可以定义为一个CGImage,另外还有一些可设置属性控制着表现和行为。

在iOS中实现粒子特效,有对应的的属性CAEmitterLayer,它是Layer的子类,用它来实现粒子特效不会怎么占用资源,从而去影响UI的流程性。
粒子CAEmitterLayer发射器的基本属性

我来举个通俗易懂的例子吧CAEmitterLayer就像大炮,决定了(1)哪里发射(2)大炮有多大CAEmitterCell就像是炮弹,觉得了(1)初速度(2)加速度(3)炮弹类型(4)发射后的角度 等等
粒子CAEmitterLayer发射器的基本属性
//是否允许在规定的范围内
@property BOOL masksToBounds;

//发射器的形状
//kCAEmitterLayerPoint 点的形状,粒子从一个点发出
//kCAEmitterLayerLine 线的形状,粒子从一条线发出
//kCAEmitterLayerRectangle 矩形形状,粒子从一个矩形中发出
//kCAEmitterLayerCuboid 立方体形状,会影响z平面的效果
//kCAEmitterLayerCircle 圆形,粒子会在圆形范围发射
//kCAEmitterLayerSphere 球形
@property(copy) NSString *emitterShape;

//发射器的发射模式
//kCAEmitterLayerPoints 从发射器中发出
//kCAEmitterLayerOutline 从发射器边缘发出
//kCAEmitterLayerSurface 从发射器表面发出
//kCAEmitterLayerVolumen 从发射器中点发出
@property(copy) NSString *emitterMode;

// 发射器的尺寸大小
@property CGSize emitterSize;

//发射器在xy平面的中心位置
@property CGPoint emitterPosition;

//发射器在Z平面的位置
@property CGFloat emitterZPosition;
粒子的属性,也就是特效,需要用到CAEmitterCell这个类
//类方法创建发射单元
+ (instancetype)emitterCell;
//粒子的创建速率
@property float birthRate;
//粒子的生存时间
@property float lifetime;
//粒子的生存时间容差
@property float lifetimeRange;
//粒子在Z轴方向的发射角度
@property CGFloat emissionLatitude;
//粒子在xy平面的发射角度
@property CGFloat emissionLongitude;
//粒子发射角度的容差
@property CGFloat emissionRange;
//粒子的速度
@property CGFloat velocity;
//粒子速度的容差
@property CGFloat velocityRange;
//x,y,z三个方向的加速度
@property CGFloat xAcceleration;
@property CGFloat yAcceleration;
@property CGFloat zAcceleration;
//缩放大小,缩放容差和缩放速度
@property CGFloat scale;
@property CGFloat scaleRange;
@property CGFloat scaleSpeed;
//旋转度与旋转容差
@property CGFloat spin;
@property CGFloat spinRange;
@property CGColorRef color;\
//粒子在rgb三个色相上的容差和透明度的容差
@property float redRange;
@property float greenRange;
@property float blueRange;
@property float alphaRange;
//粒子在RGB三个色相上的变化速度和透明度的变化速度
@property float redSpeed;
@property float greenSpeed;
@property float blueSpeed;
@property float alphaSpeed;
//渲染粒子,可以设置为一个CGImage的对象
@property(strong) id contents;

//渲染的范围
@property CGRect contentsRect;
代码使用
使用:

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self setup];
    }
    return self;
}

- (void)setup {
    self.emitterLayer.masksToBounds = YES;
    self.emitterLayer.emitterShape = kCAEmitterLayerLine;
    self.emitterLayer.emitterMode = kCAEmitterLayerSurface;
    self.emitterLayer.emitterSize = self.frame.size;
    self.emitterLayer.emitterPosition
    = CGPointMake(self.bounds.size.width / 2.f, -20);
}

- (void)show {
    CAEmitterCell *rainFlake = [CAEmitterCell emitterCell];
    rainFlake.birthRate = 25.f;
    rainFlake.speed = 10.f;
    rainFlake.velocity = 10.f;
    rainFlake.velocityRange = 10.f;
    rainFlake.yAcceleration = 1000.f;
    rainFlake.contents = (__bridge id _Nullable)([UIImage imageNamed:@"234"].CGImage);
    rainFlake.color = [UIColor blackColor].CGColor;
    rainFlake.lifetime = 7.f;
    rainFlake.scaleRange = 0.f;
    rainFlake.scale = 0.2f;
    //添加动画
    self.emitterLayer.emitterCells = @[rainFlake];
}
效果展示
下雨.gif
![星星.gif](http://upload-images.jianshu.io/upload_images/1170421-57934d29912e713c.gif?imageMogr2/auto-orient/strip)

六.第三方框架-POP框架

facebook/*pop

image.png
POP是一个在iOS与OS X上通用的极具扩展性的动画引擎。它在基本的静态动画的基础上增加的弹簧动画与衰减动画,使之能创造出更真实更具物理性的交互动画。POP的API可以快速的与现有的ObjC代码集成并可以作用于任意对象的任意属性。POP是个相当成熟且久经考验的框架,Facebook出品的令人惊叹的Paper应用中的所有动画和效果即出自POP。
pop弹簧效果.gif
使用

POP默认支持三种动画,但同时也支持自定义动画。
• POPBasicAnimation
• POPSpringAnimation
• POPDecayAnimation
• POPCustomAnimation //自定义动画

1. POPBasicAnimation使用最广泛 提供固定时间间隔的动画(如淡入淡出效果)
    //基础动画
    UIView *baseAnimation = [[UIView alloc]init];
    baseAnimation.backgroundColor = [UIColor yellowColor];
    baseAnimation.frame = CGRectMake(0, 0, 100, 100);
    baseAnimation.center = self.view.center;
    [self.view addSubview:baseAnimation];
    
    //设置动画
    POPBasicAnimation *popBaseAnimation = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerPosition];
    popBaseAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(baseAnimation.center.x, 400)];
    popBaseAnimation.duration = 3.f;
    popBaseAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
    [baseAnimation.layer pop_addAnimation:popBaseAnimation forKey:nil];
    self.popView = baseAnimation;
popBaseAnimation.gif
可以看到,添加一个动画最少仅需三步
1.  定义一个animation对象,并指定对应的动画属性
2.  设置初始值和默认值(初始值可以不指定,会默认从当前值开始)
3.  添加到想产生动画的对象上
2.POPSpringAnimation

POPSpringAnimation也许是大多数人使用POP的理由,其提供一个类似弹簧一般的动画效果.

    UIView *springAnimation = [[UIView alloc]init];
    springAnimation.backgroundColor = [UIColor blueColor];
    springAnimation.frame = CGRectMake(0, 0, 100, 100);
    springAnimation.center = self.view.center;
    [self.view addSubview:springAnimation];
    
    POPSpringAnimation *popSpringAnimation = \
[POPSpringAnimation animationWithPropertyNamed:kPOPViewBounds];
    popSpringAnimation.springSpeed = 0;
    popSpringAnimation.toValue = [NSValue valueWithCGRect:CGRectMake(0, 0, 300, 300)];
    [springAnimation.layer pop_addAnimation:popSpringAnimation forKey:nil];
    self.popView = springAnimation;
popSpringAnimation.gif
POPSpringAnimation可配置的属性与默认值为
  • springBounciness:4.0 //[0-20] 弹力 越大则震动幅度越大
  • springSpeed :12.0 //[0-20] 速度 越大则动画结束越快
  • dynamicsTension :0 //拉力 接下来这三个都跟物理力学模拟相关 数值调整起来也很费时 没事不建议使用哈
  • dynamicsFriction:0 //摩擦 同上
  • dynamicsMass :0 //质量 同上

3.POPDecayAnimation

POPDecayAnimation提供一个过阻尼效果(其实Spring是一种欠阻尼效果),可以实现类似UIScrollView的滑动衰减效果

        
        //添加一个减速动画
        POPDecayAnimation *decayAnimation = \
[POPDecayAnimation animationWithPropertyNamed:kPOPLayerPosition];
        //获取加速度
        CGPoint velocity = [recognizer velocityInView:self.view];
        decayAnimation.velocity = [NSValue valueWithCGPoint:velocity];
        [recognizer.view.layer pop_addAnimation:decayAnimation forKey:nil];
popDecayAnimation.gif
注意:这里对POPDecayAnimation设置toValue是没有意义的,会被忽略(因为目的状态是动态计算得到的)

POPDecayAnimation可配置的属性与默认值为

  • 注意:POPDecayAnimation也是没有duration字段的,其动画持续时间由velocity与deceleration决定

七.第三方框架 Lottie框架

airbnb/lottie-ios

什么是Lottie?

  • 首先要说的是:什么是Lottie呢?由Airbnb开发的Lottie是一个将After Effects动画提供给任意一个iOS,macOS,Android还有React Native原生APP的文件库。这些动画通过一个叫Bodymovin的开源After Effects插件,以JSON文件的形式进行输出。Lottie通过JSON格式下载动画数据并实时提供给开发者。
    换句话说,你也可以通过设计器直接把JSON文件放入Xcode project,让Lottie帮你下载动画。当然别误会,你还是需要为你的动画写一些代码,但是你会发现Lottie的确将为你的动画编码节省大量的时间。
lottieDemo.gif

Lottie 动画文件

在使用Lottie之前,你需要一个以JSON文件形式输出的动画数据库。如果你已经有了一个After Effects动画,用Bodymovin插件来创建JSON文件。
如果你不会使用After Effects呢?你要如何准备你的动画?你可以雇一位设计师为你设计动画,或者你学会用After Effects。
幸运的是,这里还有一个选项,那就是:Lottie Files

lottieFileDemo.gif
用CocoaPods安装Lottie动画库

当你创建完项目,离开Xcode,打开Terminal。我们将为安装Lottie动画库创建一个Podfile。我想你应该已经有一些使用CocoaPods的经验并且已经把它安装在你的电脑中了。
在terminal中运行下列指令来创建一个Podfile。

/**
 lottie动画展示
 */
- (void)playAnimationWithName: (NSString *)name {

    
    NSString *path = [[NSBundle mainBundle]pathForResource:name ofType:nil ];
    LOTAnimationView *lotAnimation = [LOTAnimationView animationWithFilePath:path];
    
    lotAnimation.frame = CGRectMake(0, 0, 400, 400);
    lotAnimation.center = self.view.center;
    lotAnimation.contentMode = UIViewContentModeScaleAspectFill;
    [self.view addSubview:lotAnimation];
    [lotAnimation play];
    lotAnimation.loopAnimation = YES;
    self.lotAnimation = lotAnimation;
}

demo展示

lottieAnimation.gif
本篇动画作为自己的总结.其中引用大量的博主的动画文章.没有任何商业用途.都是用于学习跟总结回头.诸君共勉!!!

以下为本文的出入跟资料:

1.使用带粒子效果的 CAEmitterLayer视频教学
2.POP基础动画视频教学
3.Lottie简介 & iOS集成使用
4.Lottie初级教程:打造iOS APP完美动画
5.iOS动画(Core Animation)总结
6.M了个J - Core Animation1-简介
7.iOS中粒子发射(封装下雨,下雪,喷火等特效)
8.iOS那些简单的动画(不定期更新)
9iOS动画之用CAEmitterLayer实现炫酷的动画
10动画demo大综合github社区

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

推荐阅读更多精彩内容

  • 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥ios动画全貌。在这里你可以看...
    每天刷两次牙阅读 8,471评论 6 30
  • 在iOS实际开发中常用的动画无非是以下四种:UIView动画,核心动画,帧动画,自定义转场动画。 1.UIView...
    请叫我周小帅阅读 3,082评论 1 23
  • 汉字字母数字排序 Collator Collator 用来简化我们处理各种语言之间的差别性。Collator 主要...
    探戏者阅读 645评论 0 0
  • 01 我是小透明,3周前斥巨资买了一只定制包,在我苦等快递的时候,物流信息提示已收货。但我并没有接到快递员的电话,...
    魔都八点办阅读 1,007评论 1 1
  • 晓明(我还没想好今后怎么称呼你),因为我,你今天一天都很难受,对不起,我会用心去对你好,请相信我,其实我也不知道该...
    我期待的是阅读 141评论 0 0