IOS动画技术详解

视图动画

UIView动画块

ios4.0之后在UIView类中提供以下几个处理动画的方法。

+animateWithDuration:animations
+animateWithDuration:animations:completion
+animateWithDuration:delay:options:animations:completion

其中animateWithDuration后面的参数是动画的持续时间。而animations后面是一个block代码块,具体的动画内容就写在这个代码块里面。delay是动画延迟多少时间后执行,如果设置为0就表示马上执行。好啦,接下来我们来看一个例子吧。动画效果如下:


import UIKit

class AnimationBlokViewController: UIViewController {
    @IBOutlet weak var ball: UIImageView!//关联UIImageView为图片设置动画
    var flag = 1
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
//为button设置一个点击事件,点击后执行动画
    @IBAction func click(sender: AnyObject) {
        UIView.animateWithDuration(1.5) {
            var frame = self.ball.frame
            frame.origin.y += CGFloat(100 * self.flag)
            self.flag *= -1 
            self.ball.frame = frame
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}
过渡动画

ios4.o之后在UIView中增加了两个过度动画的方法
+transitionWithView:duration:options:animations:completion:制定的容器内创建过渡动画。
+transitionFromView:toView:duration:options:completion:指定的两个视图之间创建过渡动画。
接下来让我们看看一个例子吧。在视图中创建4个button分别关联下面四个方法。点击就执行对应的过渡动画。值得注意的是其中options参数含有多个值时在oc中是按位或符号|将多个参数连接起来,而在swift中会报错,在swift中我们使用传递数组的形式[]传递多个参数。
相关的options参数有:
1.TransitionFlipLeft:从左往右翻转
2.TransitionFlipRight:从右往左翻转
3.TransitionCurlUp:向上翻页
4.TransitionCurlDown:向下翻页
5.TransitionCrossDissolve:交叉溶解效果
6.TransitionFlipFromTop:从上往下翻转
7.TransitionFlipFromBottom:从下往上翻转
8.CurveEaseInOut:缓入缓出,开始和结束时减速
9.CurveEaseIn:缓入,开始时减速
10.CurveEaseOut:缓出,结束时减速
11.CurveEaseLinear:线性,匀速运动
其中前七个或者后四个不能同时有两个或者以上在一个数组中使用否则会冲突。
动画效果如下:


import UIKit

class TrasitionViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
    
//从左往右翻转
    @IBAction func FlipFromLeft(sender: AnyObject) {
        UIView.transitionWithView(self.view, duration: 3.0, options:[UIViewAnimationOptions.CurveEaseOut,UIViewAnimationOptions.TransitionFlipFromLeft], animations: {
            print("动画开始")
            }) { (finished) in
                print("动画完成")
        }
    }

//从右往左翻转
    @IBAction func FlipFromRight(sender: AnyObject) {
        UIView.transitionWithView(self.view, duration: 3.0, options: [UIViewAnimationOptions.CurveEaseOut,UIViewAnimationOptions.TransitionFlipFromRight], animations: {
            print("动画开始")
        }) { (finished) in
            print("动画完成")
        }
    }
    
//向上翻页
    @IBAction func CurlUP(sender: AnyObject) {
        UIView.transitionWithView(self.view, duration: 3.0, options: [UIViewAnimationOptions.CurveEaseOut,UIViewAnimationOptions.TransitionCurlUp], animations: {
            print("动画开始")
        }) { (finished) in
            print("动画完成")
        }
    }
    
//向下翻页
    @IBAction func CurlDown(sender: AnyObject) {
        UIView.transitionWithView(self.view, duration: 3.0, options: [UIViewAnimationOptions.CurveEaseOut,UIViewAnimationOptions.TransitionCurlDown], animations: {
            print("动画开始")
        }) { (finished) in
            print("动画完成")
        }
    }
}```
####自定义过渡动画
视图之间过渡,跳转有两种情况,一种是树形结构导航,而另一种是模态视图导航。树形结构导航是通过UINavigationController控制视图的堆栈实现视图的过渡,模态导航是通过UIViewController控制视图实现的。针对这两种跳转,我们的自定义过渡动画也分为这两种。
在ios自定义过渡动画类需要实现UIViewControllerAnimateTransitiong协议的方法。其中有两个重要的方法。
1.-animateTransition:执行自定义的动画。
2.-transitionDuration:设置动画执行的时间。
接下来我们还是用实例说话:将模态导航和树形结构导航用法一起演示一遍:
![](http://chuantu.biz/t5/33/1473579787x1987391531.gif)

import UIKit

class SlideTransitionAnimator: NSObject,UIViewControllerAnimatedTransitioning {

func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {
    return 1.5
}

func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
    let fromVC = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)
    let toVC = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)
    let transformedStartFrame = toVC!.view.frame
    
    let origin = transformedStartFrame.origin
    let width = transformedStartFrame.width
    let height = transformedStartFrame.height
    let transformedEndframe = CGRectMake((origin.x)-width, origin.y,width, height)
    transitionContext.containerView()?.addSubview((fromVC?.view)!)
    transitionContext.containerView()?.addSubview((toVC?.view)!)
    
    UIView.animateWithDuration(3, animations: {
        toVC?.view.frame = transformedEndframe
        toVC?.view.alpha = 0.5
        }) { (finished) in
            toVC?.view.frame = transformedEndframe
            toVC?.view.alpha = 1.0
            transitionContext.completeTransition(true)
    }
}

}

import UIKit

class CustomViewController: UIViewController ,UINavigationControllerDelegate,UIViewControllerTransitioningDelegate{

override func viewDidLoad() {
    super.viewDidLoad()
    self.navigationController?.delegate = self
    self.transitioningDelegate = self
}

@IBAction func treeClick(sender: AnyObject) {
    let VC = UIGravityViewController()
    self.navigationController?.showViewController(VC, sender: nil)
}

@IBAction func presentClick(sender: AnyObject) {
    let VC = UIGravityViewController()
    self .presentViewController(VC, animated: true) { 
        print("过渡完成")
    }
    
}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
   
        let destionViewController = segue.destinationViewController as UIViewController
        destionViewController.transitioningDelegate = self
}

func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
    let animator = SlideTransitionAnimator()
    return animator
}

func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
    let animator = SlideTransitionAnimator()
    return animator
}

 func navigationController(navigationController: UINavigationController, animationControllerForOperation operation: UINavigationControllerOperation, fromViewController fromVC: UIViewController, toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
    let animator = SlideTransitionAnimator()
    return animator
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

}

####UIKit力学
UIKit力学是IOS7推出的技术,作用是使视图对象具有真实的物理运动效果。
其中包括的力学效果有:
#####1.重力行为(UIGravityBehavior)
重力行为能够模拟视图对象受重力影响而掉落的效果。效果图如下:

![gravity.gif](http://upload-images.jianshu.io/upload_images/1746439-3c60e669c4bd15fa.gif?imageMogr2/auto-orient/strip)

import UIKit

class UIGravityViewController: UIViewController {
@IBOutlet weak var ballImageView: UIImageView!
var animator : UIDynamicAnimator!
var gravity : UIGravityBehavior!

override func viewDidLoad() {
    super.viewDidLoad()
    self.title = "重力行为"
}

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)
    self.animator = UIDynamicAnimator(referenceView: self.view)
    //实例重力行为
    self.gravity = UIGravityBehavior(items: [self.ballImageView])
    //设置重力的方向
    let gravityDirection : CGVector = CGVectorMake(0.0, 0.1)
    self.gravity.gravityDirection = gravityDirection
    self.animator.addBehavior(self.gravity) 
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

}```

2.碰撞行为(UICollisionBehavior)

如同物理世界一样物体碰撞会反弹效果。效果图如下:

collision.gif
import UIKit

class UICollisonViewController: UIViewController {
    @IBOutlet weak var ballImageView: UIImageView!
    
    var collision : UICollisionBehavior!
    var animator : UIDynamicAnimator!
    var gravity : UIGravityBehavior!

    override func viewDidLoad() {
        super.viewDidLoad()
        self.title = "碰撞行为"
    }

    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)
        self.animator = UIDynamicAnimator(referenceView: self.view)
        //重力行为
        self.gravity = UIGravityBehavior(items: [self.ballImageView])
        let gravityDirection : CGVector = CGVectorMake(0.0, 0.1)
        self.gravity.gravityDirection = gravityDirection
        self.animator.addBehavior(self.gravity)
        //碰撞行为
        self.collision = UICollisionBehavior(items: [self.ballImageView])
        self.collision.translatesReferenceBoundsIntoBoundary = true
        self.animator.addBehavior(self.collision)
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}```
#####3.吸附行为(UIAttachmentBehavior)
吸附行为可以实现两个物体彼此牵制,就好像用一根棍子将两个物体连接在一起。效果图如下:

![attachment.gif](http://upload-images.jianshu.io/upload_images/1746439-6d3bd327c889af58.gif?imageMogr2/auto-orient/strip)

import UIKit

class UIAttachmentViewController: UIViewController,UICollisionBehaviorDelegate {

@IBOutlet weak var attachmentPoint: UIImageView!
@IBOutlet weak var box: UIImageView!
@IBOutlet weak var barrier: UIImageView!
var collision : UICollisionBehavior!
var animator : UIDynamicAnimator!
var gravity : UIGravityBehavior!
var attach : UIAttachmentBehavior!

override func viewDidLoad() {
    super.viewDidLoad()
    self.title = "吸附行为"
}

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)
    self.animator = UIDynamicAnimator(referenceView: self.view)
    //重力行为
    self.gravity = UIGravityBehavior(items: [self.box])
    self.animator.addBehavior(self.gravity)
    //碰撞行为
    self.collision = UICollisionBehavior(items: [self.box])
    let width = self.barrier.frame.size.width
    let origin = self.barrier.frame.origin
    self.collision.addBoundaryWithIdentifier("barrier", fromPoint: origin, toPoint: CGPointMake(origin.x+width, origin.y))
    self.collision.translatesReferenceBoundsIntoBoundary = true
    self.collision.collisionDelegate = self
    self.animator.addBehavior(self.collision)
    let itemBehaviour = UIDynamicItemBehavior(items: [self.box])
    itemBehaviour.elasticity = 0.5
    self.animator.addBehavior(itemBehaviour)
}
//碰撞行为协议
internal func collisionBehavior(behavior: UICollisionBehavior, beganContactForItem item: UIDynamicItem, withBoundaryIdentifier identifier: NSCopying?, atPoint p: CGPoint){
    //吸附行为
    self.attach = UIAttachmentBehavior(item: self.attachmentPoint, attachedToItem: self.box)
    self.animator.addBehavior(self.attach)
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

}```

4.推行为(UIPushBehavior)

推行为可以使视图对象朝某个方向运动,这个推力有瞬间(UIPushBehaviorModeInstantaneous)(UIPushBehaviorModeContinuous)两种。效果图如下:

push.gif
import UIKit

class UIPushViewController: UIViewController,UICollisionBehaviorDelegate {

    @IBOutlet weak var barrier: UIImageView!
    @IBOutlet weak var box: UIImageView!
    @IBOutlet weak var attachmentPoint: UIImageView!
    var firstConcact = false
    
    var collision : UICollisionBehavior!
    var animator : UIDynamicAnimator!
    var gravity : UIGravityBehavior!
    var attach : UIAttachmentBehavior!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.title = "推行为"
    }
    
    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)
        self.animator = UIDynamicAnimator(referenceView: self.view)
        self.gravity = UIGravityBehavior(items: [self.box])
        self.animator.addBehavior(self.gravity)
        
        self.collision = UICollisionBehavior(items: [self.box])
        let width = self.barrier.frame.size.width
        let origin = self.barrier.frame.origin
        self.collision.addBoundaryWithIdentifier("barrier", fromPoint: origin, toPoint: CGPointMake(origin.x+width, origin.y))
        self.collision.translatesReferenceBoundsIntoBoundary = true
        self.collision.collisionDelegate = self
        self.animator.addBehavior(self.collision)
        let itemBehaviour = UIDynamicItemBehavior(items: [self.box])
        itemBehaviour.elasticity = 0.5
        self.animator.addBehavior(itemBehaviour)
    }
    
    internal func collisionBehavior(behavior: UICollisionBehavior, beganContactForItem item: UIDynamicItem, withBoundaryIdentifier identifier: NSCopying?, atPoint p: CGPoint){
        if !self.firstConcact {
        self.firstConcact = true
        
        self.attach = UIAttachmentBehavior(item: self.attachmentPoint, attachedToItem: self.box)
        self.animator.addBehavior(self.attach)
        //设置推行为
        let push = UIPushBehavior(items: [self.box],mode: UIPushBehaviorMode.Instantaneous)
        //设置推行为的方向和力度
        push.setAngle(CGFloat(-M_PI/4.0), magnitude: 5.0)
        self.animator.addBehavior(push)
        
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}```
#####5.甩行为(UISnapBehavior)
能够使物体朝某个方向甩出,并有瞬间加速度,由慢及快,再由快及慢,最后停止在目标点。效果图如下:

![snap.gif](http://upload-images.jianshu.io/upload_images/1746439-741dc692417379f9.gif?imageMogr2/auto-orient/strip)

import UIKit

class UISnapViewController: UIViewController {
var animator : UIDynamicAnimator!
var snap : UISnapBehavior!

@IBOutlet weak var box: UIImageView!

override func viewDidLoad() {
    super.viewDidLoad()
    box.userInteractionEnabled = true;
    box.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(UISnapViewController.snapClick(_:))))
      self.title = "甩行为"
}

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)
    self.animator = UIDynamicAnimator(referenceView: self.view)
   
}

func snapClick(sender: AnyObject) {
print("甩")
let gesture = sender as! UITapGestureRecognizer
let point = gesture.locationInView(self.view)
if self.snap != nil {
self.animator.removeBehavior(self.snap)
}
self.snap = UISnapBehavior(item: self.box, snapToPoint: point)
self.animator.addBehavior(self.snap)
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

}```

6.行为限制(DynamicItemBehavior)

行为限制于上面五个行为不同,它是用来设置力学行为参数的。参数如下:
(1)density:密度,如果一个100x100点的物体密度是1.0作用力是1.0那么它的加速度是100点/s^2
(2)elasity:弹性系数,取值范围0.0-1.0。其中0.0代表没有反弹,1.0代表完全弹性碰撞。
(3)friction:摩擦系数,0.0表示没有摩擦力,1.0表示摩擦力很强。还可以设置超过1.0的跟大的摩擦力。
(4)resistance:阻力,0.0表示没有阻力,CGFLOAT_MAX表示最大阻力。
(5)allowsRotation:是否允许旋转。
(6)angularResistance:角阻力,物体旋转是旋转方向的阻力。
我们来看看DynamicItemBehavior具体怎么使用吧:

 let itemBehaviour = UIDynamicItemBehavior(items:[self.view])
        itemBehaviour.elasticity = 0.5
        itemBehaviour.allowsRotation = true
        itemBehaviour.friction = 0.0
        itemBehaviour.resistance = 0.0
        self.animator.addBehavior(itemBehaviour)

Core Animation框架

(1)隐式动画是一种最简单动画,不用设置定时器,不用考虑线程或者重画,它的很多属性都是默认的。
(2)显式动画是一种使用CABasicAnimation创建的动画通过CABasicAnimation,可以更明确的定义属性如何改变动画。
动画效果如下:


隐式动画
import UIKit

class ExplicitViewController: UIViewController {
    @IBOutlet weak var plane: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()
        self.plane.layer.opacity = 0.25
    }

    //不透明度从0.25-1.0
    @IBAction func implicitClick(sender: AnyObject) {
        let moveTransform = CGAffineTransformMakeTranslation(180, 200)
        self.plane.layer.setAffineTransform(moveTransform)
        self.plane.layer.opacity = 1;
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}```
#####显式动画

import UIKit

class ExplicitViewController: UIViewController {
@IBOutlet weak var plane: UIImageView!

override func viewDidLoad() {
    super.viewDidLoad()
    self.plane.layer.opacity = 0.25
}

@IBAction func explicitClick(sender: AnyObject) {
let opAnim = CABasicAnimation(keyPath: "opacity")
//定义动画时间
opAnim.duration = 3.0
//将透明的从0.25-1.0
opAnim.fromValue = 0.25
opAnim.toValue = 1.0
//指定累计上次值
opAnim.cumulative = true
//动画重复2次
opAnim.repeatCount = 2
//保持动画结束值
opAnim.fillMode = kCAFillModeForwards
//动画结束时不停止
opAnim.removedOnCompletion = false
self.plane.layer.addAnimation(opAnim, forKey: "animateOpacity")

    let moveTransform = CGAffineTransformMakeTranslation(180, 200)
    let moveAnim = CABasicAnimation(keyPath: "transform")
    moveAnim.duration = 6.0
    moveAnim.toValue = NSValue(CATransform3D: CATransform3DMakeAffineTransform(moveTransform))
    moveAnim.fillMode = kCAFillModeForwards
    moveAnim.removedOnCompletion = false
    self.plane.layer.addAnimation(moveAnim, forKey: "animateTransform")
    opAnim.fillMode = kCAFillModeForwards
    opAnim.removedOnCompletion = false
    
}
override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

}```

关键帧动画
import UIKit

class ExplicitViewController: UIViewController {
    @IBOutlet weak var plane: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()
        self.plane.layer.opacity = 0.25
    }

 @IBAction func keyFrameClick(sender: AnyObject) {
        let opAnim = CAKeyframeAnimation(keyPath: "opacity")
        opAnim.duration = 6.0
        opAnim.values = [0.25,0.75,1.0]
        opAnim.keyTimes = [0.0,0.5,1.0]
        opAnim.fillMode = kCAFillModeForwards
        opAnim.removedOnCompletion = false
        self.plane.layer.addAnimation(opAnim, forKey: "animateOpacity")
        
        let moveTransform = CGAffineTransformMakeTranslation(180, 200)
        let moveAnim = CABasicAnimation(keyPath: "transform")
        moveAnim.duration = 6.0
        moveAnim.toValue = NSValue(CATransform3D: CATransform3DMakeAffineTransform(moveTransform))
        moveAnim.fillMode = kCAFillModeForwards
        moveAnim.removedOnCompletion = false
        self.plane.layer.addAnimation(moveAnim, forKey: "animateTransform")
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}```
#####使用路径
效果图如下:

![usePath.gif](http://upload-images.jianshu.io/upload_images/1746439-bdfb4ecc4f660fe4.gif?imageMogr2/auto-orient/strip)

import UIKit

class PathViewController: UIViewController {
@IBOutlet weak var ball: UIImageView!
var flag = 1
@IBOutlet weak var button: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
}

@IBAction func click(sender: AnyObject) {
    self.button.alpha = 0.0
    //创建可变路径
    let startPath = CGPathCreateMutable()
    CGPathMoveToPoint(startPath, nil, 160.0, 100.0)
    CGPathAddLineToPoint(startPath, nil, 100.0, 280.0)
    CGPathAddLineToPoint(startPath, nil, 260.0, 170.0)
     CGPathAddLineToPoint(startPath, nil, 60.0, 170.0)
    CGPathAddLineToPoint(startPath, nil, 220.0, 280.0)
     //封闭子路径
    CGPathCloseSubpath(startPath)
    
    let animation = CAKeyframeAnimation(keyPath: "position")
    animation.duration = 5.0
     //只有关键帧动画才有setPath方法
    animation.path = startPath
    animation.delegate = self
    self.ball.layer.addAnimation(animation, forKey: "position")

}

override func animationDidStop(anim: CAAnimation, finished flag: Bool) {
    UIView.animateWithDuration(1.0) {
        self.button.alpha = 1.0
    }
}
override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

}

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

推荐阅读更多精彩内容

  • 翻译自“View Controller Programming Guide for iOS”。 1 弹出视图控制器...
    lakerszhy阅读 3,194评论 2 20
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 11,616评论 4 59
  • 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥ios动画全貌。在这里你可以看...
    每天刷两次牙阅读 8,321评论 6 30
  • This evening, my niece and I went to do some 广场舞. 广场舞, or...
    doooodles阅读 568评论 0 1
  • “崽啊~归来吃饭嘞~”,听着奶奶一声声绵长的呼唤,阿强恋恋不舍地一步三回头从村口回来,满脸失望地牵着奶奶的手回家。...
    午桥阅读 247评论 0 0