├── .gitignore ├── LICENSE ├── README.md └── TransitionAnimation ├── BMAnimateTransition.h ├── BMAnimateTransition.m ├── BMInteractiveTransition.h ├── BMInteractiveTransition.m ├── BMTabBarController.h ├── BMTabBarController.m ├── ColorUtils.h ├── ColorUtils.m ├── DetailController.h ├── DetailController.m ├── DetailTableViewCell.h ├── DetailTableViewCell.m ├── FXBlurView.h ├── FXBlurView.m ├── HomeViewController.h ├── HomeViewController.m ├── MenuViewController.h ├── MenuViewController.m ├── MessageViewController.h ├── MessageViewController.m ├── MyTableViewCell.h ├── MyTableViewCell.m ├── PersonProfileViewController.h ├── PersonProfileViewController.m ├── PhotoCircleController.h ├── PhotoCircleController.m ├── SettingViewController.h ├── SettingViewController.m ├── TransitionAnimation.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── contents.xcworkspacedata ├── TransitionAnimation ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── AppIcon29@2x.png │ │ ├── AppIcon29@3x.png │ │ ├── AppIcon40@2x.png │ │ ├── AppIcon40@3x.png │ │ ├── AppIcon60@2x.png │ │ ├── AppIcon60@3x.png │ │ └── Contents.json │ ├── BackIcon.imageset │ │ ├── Contents.json │ │ └── back.png │ ├── CellAvatars │ │ ├── Contents.json │ │ ├── Jashion.imageset │ │ │ ├── Contents.json │ │ │ └── FE508EFC-24DD-4040-8852-AF6E172F5670.png │ │ ├── Kevin Burr.imageset │ │ │ ├── 7BBCD252-759F-48D4-960E-DC17CC0DC01D.png │ │ │ └── Contents.json │ │ ├── Marry.imageset │ │ │ ├── Contents.json │ │ │ └── DAF7267A-1436-4938-B7F5-640264EB2D4E.png │ │ ├── Sean Furr.imageset │ │ │ ├── 421DEE67-5968-40E3-AD5A-EF602A859755.png │ │ │ └── Contents.json │ │ ├── Sheet.imageset │ │ │ ├── 9516CAED-3453-4F2D-9996-06E24EDBF612.png │ │ │ └── Contents.json │ │ ├── Stan.imageset │ │ │ ├── 961BDD4A-6C6A-44A4-BE88-13B56FD03085.png │ │ │ └── Contents.json │ │ ├── Sulian.imageset │ │ │ ├── 650C8C65-EE7C-45ED-B550-06760DF79A8F.png │ │ │ └── Contents.json │ │ └── morgan.imageset │ │ │ ├── 98C1386A-F0A7-4D1C-B56D-3FDBEBF0FD3E.png │ │ │ └── Contents.json │ ├── Contents.json │ ├── DeleteButtonIcon.imageset │ │ ├── Contents.json │ │ └── delete.png │ ├── HomeGroup │ │ ├── Contents.json │ │ ├── DetailGroup │ │ │ ├── CommentIcon.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── comment-wap.png │ │ │ ├── Contents.json │ │ │ ├── FollowIcon.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── eye.png │ │ │ └── LikeIcon.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── like.png │ │ └── PersonGroup │ │ │ ├── Contents.json │ │ │ ├── DeleteIcon.imageset │ │ │ ├── Contents.json │ │ │ └── delete.png │ │ │ ├── PersonImages │ │ │ ├── Animal.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── E43536DC-9DCC-491D-A6A5-23920A5C4DBF.png │ │ │ ├── Castle.imageset │ │ │ │ ├── BFC1FA51-B0CE-4F58-8A3B-AD16A76D9033.png │ │ │ │ └── Contents.json │ │ │ ├── Chart.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── DBB662FF-0EFA-4C0D-A319-5788C1D824DD.png │ │ │ ├── Contents.json │ │ │ ├── PeaceMidNight.imageset │ │ │ │ ├── 1FD89134-812A-4895-B231-C884EFAE9CF1.png │ │ │ │ └── Contents.json │ │ │ ├── Signal.imageset │ │ │ │ ├── 0F17F868-DE1A-476F-92FD-6820A51636B6.png │ │ │ │ └── Contents.json │ │ │ ├── Sun.imageset │ │ │ │ ├── 953E9AAF-4ECC-4C99-9B4A-AFC9DF1674FC.png │ │ │ │ └── Contents.json │ │ │ └── Web.imageset │ │ │ │ ├── 266CBAFD-484F-44E1-8312-E282482A781F.png │ │ │ │ └── Contents.json │ │ │ ├── PersonRight.imageset │ │ │ ├── Contents.json │ │ │ └── 动物.png │ │ │ └── PersooLeft.imageset │ │ │ ├── Contents.json │ │ │ └── 动漫.png │ ├── HomeMenu.imageset │ │ ├── Contents.json │ │ └── menu.png │ ├── LauncgSplashImage.imageset │ │ ├── BgImage@960x1136.png │ │ └── Contents.json │ ├── LaunchImage.launchimage │ │ ├── Contents.json │ │ ├── transparent@1242x2208-1副本.png │ │ ├── transparent@640x1136副本.png │ │ ├── transparent@640x960副本.png │ │ └── transparent@750x1334副本.png │ ├── PhotoAddButton.imageset │ │ ├── 2x副本.png │ │ ├── 3x副本.png │ │ └── Contents.json │ ├── TapGroup │ │ ├── Contents.json │ │ ├── HomeSelect.imageset │ │ │ ├── Contents.json │ │ │ └── home.png │ │ ├── HomeUnSelect.imageset │ │ │ ├── Contents.json │ │ │ └── home (1).png │ │ ├── MessageSelect.imageset │ │ │ ├── Contents.json │ │ │ └── message.png │ │ ├── MessageUnSelect.imageset │ │ │ ├── Contents.json │ │ │ └── message.png │ │ ├── SettingSelect.imageset │ │ │ ├── Contents.json │ │ │ └── setting.png │ │ └── SettingUnSelect.imageset │ │ │ ├── Contents.json │ │ │ └── setting.png │ └── WhiteCircleImage.imageset │ │ ├── Contents.json │ │ └── circle.png ├── Info.plist └── main.m ├── UIImage+Tint.h └── UIImage+Tint.m /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata 19 | 20 | ## Other 21 | *.xccheckout 22 | *.moved-aside 23 | *.xcuserstate 24 | *.xcscmblueprint 25 | 26 | ## Obj-C/Swift specific 27 | *.hmap 28 | *.ipa 29 | 30 | # CocoaPods 31 | # 32 | # We recommend against adding the Pods directory to your .gitignore. However 33 | # you should judge for yourself, the pros and cons are mentioned at: 34 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 35 | # 36 | # Pods/ 37 | 38 | # Carthage 39 | # 40 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 41 | # Carthage/Checkouts 42 | 43 | Carthage/Build 44 | 45 | # fastlane 46 | # 47 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 48 | # screenshots whenever they are needed. 49 | # For more information about the recommended setup visit: 50 | # https://github.com/fastlane/fastlane/blob/master/docs/Gitignore.md 51 | 52 | fastlane/report.xml 53 | fastlane/screenshots 54 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 JinHua Huang 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UIViewControllerTransitioningAnimation iOS自定义转场动画 2 | 3 | # 前言 4 | 5 | 由于本人喜欢有趣的动效,在刚开始学习iOS开发时就自己捣腾iOS动画。当时什么也不懂,而且虽然现在看来iOS动画的实现方式就那么几种,但是刚开始弄的时候还是挺费劲的。嘿嘿,虽然现在也不算很牛,但也算入门。我来抛砖引玉了,说的不好不要打我😊。 6 | 7 | # 1.什么是动画? 8 | 9 | 动画,电影,电视,漫画,以前傻傻的分不清,其实也好区分,很明显漫画是不会动的,比如我喜欢看的死神,火影,海贼,动画和电影神马的都是能动的,但是也有点不一样,动画是画出来的,电影则是拍出来的,呵呵哒。 10 | 其实,我觉得一切动画都可以分解成一幅幅画面,所谓的帧动画,只要够强大,什么都挡不住一只笔的风骚。😍 11 | 12 | # 2.为何是60FPS(60帧/秒)? 13 | 14 | 说这个问题之前,我们先说一下电影的24FPS和游戏的60FPS,一部流畅的电影只需24FPS即可,但是游戏24FPS可能会很卡。why? 15 | 有两个原因: 16 | 17 | ### (1)电影成像和游戏成像的原理不一样 18 | 19 | 电影每一帧都包含了一段时间的信息,而游戏则只包含那一瞬间的信息。举个例子,拍照片。如果设置曝光时间过长,则会出现模糊,因为这段时间相机里面的场景变化的痕迹都记录在照片中了,所以会出现模糊不清的照片,如下图: 20 | 21 | ![twocat.png](http://upload-images.jianshu.io/upload_images/968977-e07aab2267758586.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 22 | 23 | 一只模糊的猫头😄,其实这也可以看作一段时间内多帧糅合在一起了。电影虽然帧数低,但是上一针储存了到下一针所需要的变化,所以看起来可以连贯,就像阳光照射在人的视网膜上,会有停留时间。想象一下,站在你对面的人向你招手,速度从慢到快,你是否也不会感觉到卡顿呢?(如果能感觉到卡顿,这个世界就精彩了,想象一下奥运会的短跑项目😄)。而游戏则不一样,游戏显示在屏幕的每一帧都是先经过CPU的处理,然后再经过GPU的处理,最后才会显示在电子屏幕上面(电子屏幕显示相关的细节可以看一下ibireme大神的[iOS保持界面流畅的技巧](http://blog.ibireme.com/2015/11/12/smooth_user_interfaces_for_ios/))。简单来说就是上一帧没有保留下一帧过度所需要的变化,所以,一旦前后画面变化过大,则会感觉到卡顿,因为是突然变化,措手不及。 24 | 25 | ### (2)电影的FPS是稳定的,而游戏则是不稳定的 26 | 27 | 这个可以这样理解,电影一秒24帧,每帧之间的时间间隔是一样的,稳定的,而游戏比如前面30帧时间间隔比较短,后面30帧的时间间隔比较长,也会感觉卡顿,这也是为什么有同样的帧数,有的应用感觉卡顿,有的不卡的原因。 28 | 29 | 总的来说,帧数越多也不一定不卡顿,但是应用显示的帧数在30~60之间一般不会感觉到明显的卡顿。貌似是因为人眼的视觉停留时间为1/24秒,具体是什么鬼,大家自行Google。 30 | 31 | # 3.iOS动画的层级结构 32 | 33 | ![层级关系.png](http://upload-images.jianshu.io/upload_images/968977-33c61736af4698c3.png) 34 | 35 | ### 解析一下上图的层级关系:
36 | 1.UIKit应用于iOS,AppKit应用于Mac OS,可想iOS和Mac OS开发有很多相似之处。
37 | 2.QuartzCore包含Core Animation。
38 | 3.OpenGL ES是跨平台的图形API,属于OpenGL的一个简化版本,是应用程序编程接口,也就是说它只定义了一套规范,具体的实现由设备制造商根据规范去做。QuartZ 2D是苹果公司开发的一套API,它是Core Graphics Framework的一部分,是一套基于C的API框架,使用了Quartz作为绘图引擎。
39 | 4.OpenGL ES可以绘制2D和3D图形,Core Graphics只能绘制2D图形。
40 | 5.CATransform3D包含于Core Animation里面;CGAffineTransform包含于Core Graphics里面。
41 | 6.一般从绘制性能来说:OpenGL ES > Core Graphics > Core Animation,从使用简易来说:Core Animation > Core Graphics > OpenGL ES
42 | 43 | # 4.iOS动画实现 44 | 45 | 首先要清楚CALayer的概念,在MVC框架里面,View是负责用户界面显示的,显而易见,Apple刚开始就让iOS遵循MVC框架,UIView负责显示界面。然而,CALayer才是绘制页面的功臣,UIView只是负责管理CALayer的行为。CALayer里包含了三种树呈现树(presentationLayer tree),模型树(modelLayer tree)以及渲染树(render tree),其中呈现树主要记录了图层从动画开始到结束的所有变化,模型树只记录了最终结果,而渲染树顾名思义是渲染到屏幕上显示的。 46 | 47 | ##### (1)CoreAnimation(基本动画) 48 | 49 | ![CoreAnimation.png](http://upload-images.jianshu.io/upload_images/968977-aab85a824844ee31.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 50 | 51 | 由上图可见CA动画分组动画(CAAnimationGroup),属性动画(CAPropertyAnimation)和转场动画(CATransition),其中属性动画又分为基本动画(CABasicAnimation)和帧动画(CAKeyframAnimation),CA动画还实现了CAMediaTiming接口,提供一些和动画时间有关的功能。 52 | * CABasicAnimation 53 | 54 | ```Objective-C 55 | fromValue: 初始值 56 | toValue: 结束值 57 | 58 | 代码: 59 | //使用CABasicAnimation创建基础动画 60 | CABasicAnimation *anima = [CABasicAnimation animationWithKeyPath:@"position"]; 61 | anima.fromValue = [NSValue valueWithCGPoint:CGPointMake(0, SCREEN_HEIGHT/2-75)]; 62 | anima.toValue = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH, SCREEN_HEIGHT/2-75)]; 63 | anima.duration = 1.0f; 64 | //anima.fillMode = kCAFillModeForwards; 65 | //anima.removedOnCompletion = NO; 66 | [_demoView.layer addAnimation:anima forKey:@"positionAnimation"]; 67 | 注意⚠: 68 | 如果fillMode=kCAFillModeForwards和removedOnComletion=NO,那么在动画执行完毕后,图层会保持显示动画执行后的状态。但在实质上,图层的属性值还是动画执行前的初始值,并没有真正被改变。 69 | ``` 70 | * CAKeyframeAnimation 71 | 72 | ```Objective-C 73 | values : NSArray对象,里面的元素称为”关键帧”(keyframe)。动画对象会在指定的时间(duration)内,依次显示values数组中的每一个关键帧 74 | path : 可以设置一个CGPathRef\CGMutablePathRef,让层跟着路径移动。path只对CALayer的anchorPoint和position起作用。如果你设置了path,那么values将被忽略。 75 | keyTimes : 可以为对应的关键帧指定对应的时间点,其取值范围为0到1.0,keyTimes中的每一个时间值都对应values中的每一帧。当keyTimes没有设置的时候,各个关键帧的时间是平分的。 76 | 77 | 代码: 78 | CAKeyframeAnimation *anima = [CAKeyframeAnimation animationWithKeyPath:@"position"]; 79 | UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(SCREEN_WIDTH/2-100, SCREEN_HEIGHT/2-100, 200, 200)]; 80 | anima.path = path.CGPath; 81 | anima.duration = 2.0f; 82 | [_demoView.layer addAnimation:anima forKey:@"pathAnimation"]; 83 | ``` 84 | * CAAnimationGroup 85 | 86 | ```Objective-C 87 | animations : 用来保存一组动画对象的NSArray 88 | 89 | 代码: 90 | CAKeyframeAnimation *anima1 = [CAKeyframeAnimation animationWithKeyPath:@"position"]; 91 | NSValue *value0 = [NSValue valueWithCGPoint:CGPointMake(0, SCREEN_HEIGHT/2-50)]; 92 | NSValue *value1 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH/3, SCREEN_HEIGHT/2-50)]; 93 | NSValue *value2 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH/3, SCREEN_HEIGHT/2+50)]; 94 | NSValue *value3 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH*2/3, SCREEN_HEIGHT/2+50)]; 95 | NSValue *value4 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH*2/3, SCREEN_HEIGHT/2-50)]; 96 | NSValue *value5 = [NSValue valueWithCGPoint:CGPointMake(SCREEN_WIDTH, SCREEN_HEIGHT/2-50)]; 97 | anima1.values = [NSArray arrayWithObjects:value0,value1,value2,value3,value4,value5, nil]; 98 | 99 | //缩放动画 100 | CABasicAnimation *anima2 = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; 101 | anima2.fromValue = [NSNumber numberWithFloat:0.8f]; 102 | anima2.toValue = [NSNumber numberWithFloat:2.0f]; 103 | 104 | //旋转动画 105 | CABasicAnimation *anima3 = [CABasicAnimationanimationWithKeyPath:@"transform.rotation"]; 106 | anima3.toValue = [NSNumber numberWithFloat:M_PI*4]; 107 | 108 | //组动画 109 | CAAnimationGroup *groupAnimation = [CAAnimationGroup animation]; 110 | groupAnimation.animations = [NSArray arrayWithObjects:anima1,anima2,anima3, nil]; 111 | groupAnimation.duration = 4.0f; 112 | 113 | [_demoView.layer addAnimation:groupAnimation forKey:@"groupAnimation"]; 114 | ``` 115 | * CATransition 116 | 117 | ```Objective-C 118 | CAAnimation的子类,用于做过渡动画或者转场动画,能够为层提供移出屏幕和移入屏幕的动画效果。 119 | 120 | type:动画过渡类型 121 | - kCATransitionFade 渐变效果 122 | - kCATransitionMoveIn 进入覆盖效果 123 | - kCATransitionPush 推出效果 124 | - kCATransitionReveal 揭露离开效果 125 | 私有API提供了其他很多非常炫的过渡动画,比如@”cube”、@”suckEffect”、@”oglFlip”、 @”rippleEffect”、@”pageCurl”、@”pageUnCurl”、@”cameraIrisHollowOpen”、@”cameraIrisHollowClose”等。 126 | 注意点 127 | 私有api,不建议开发者们使用。因为苹果公司不提供维护,并且有可能造成你的app审核不通过。 128 | 129 | subtype:动画过渡方向 130 | * kCATransitionFromRight 从右侧进入 131 | * kCATransitionFromLeft 从左侧进入 132 | * kCATransitionFromTop 从顶部进入 133 | * kCATransitionFromBottom 从底部进入 134 | 135 | startProgress:动画起点(在整体动画的百分比) 136 | endProgress:动画终点(在整体动画的百分比) 137 | 138 | 代码: 139 | CATransition *transition = [CATransition animation]; 140 | transition.type = kCATransitionFade; 141 | transition.subtype = kCATransitionFromLeft; 142 | transition.startProgress = 0; 143 | transition.endProgress = 1; 144 | transition.duration = 0.4; 145 | 146 | SecondViewController *svc = [[SecondViewController alloc] init]; 147 | [self.navigationController.view.layer addAnimation: transition forKey: @"kCATransitionFade"]; 148 | [self.navigationController pushViewController: svc animated: NO]; 149 | ``` 150 | 关于部分keyPath的值: 151 | 152 | | keyPath | 描述 | 153 | | ---------------- |:------:| 154 | | transform.scale | 比例变化 | 155 | | transform.scale.x | 宽的比例变化 | 156 | | transform.scale.y | 高的比例变化 | 157 | | transform.rotation.z | 以z轴为中心轴旋转 | 158 | | opacity | 透明度变化 | 159 | | frame | 形状变化 | 160 | | path | 路径变化 | 161 | 162 | # 5.其他调用动画的方式 163 | 164 | ```Objective-C 165 | (1)UIView块动画 166 | _demoView.frame = CGRectMake(0, SCREEN_HEIGHT/2-50, 50, 50); 167 | [UIView animateWithDuration:1.0f animations:^{ 168 | _demoView.frame = CGRectMake(SCREEN_WIDTH, SCREEN_HEIGHT/2-50, 50, 50); 169 | } completion:^(BOOL finished) { 170 | _demoView.frame = CGRectMake(SCREEN_WIDTH/2-25, SCREEN_HEIGHT/2-50, 50, 50); 171 | }]; 172 | (2)UIView commit动画 //现已不使用 173 | _demoView.frame = CGRectMake(0, SCREEN_HEIGHT/2-50, 50, 50); 174 | [UIView beginAnimations:nil context:nil]; 175 | [UIView setAnimationDuration:1.0f]; 176 | _demoView.frame = CGRectMake(SCREEN_WIDTH, SCREEN_HEIGHT/2-50, 50, 50); 177 | [UIView commitAnimations]; 178 | ``` 179 | # 6.总结 180 | 181 | 有的时候,app加上动画可以提高可玩性,趣味性。动画本身也挺好玩的,有兴趣的同学可以看一下我的Demo,[Objective-C版](https://github.com/jashion/UIViewControllerTransitioningAnimation),[Swift版](https://github.com/jashion/SwiftTransitionAnimation)。 182 | 183 | ![AnimationDemo.gif](http://upload-images.jianshu.io/upload_images/968977-e7d604398501c59a.gif?imageMogr2/auto-orient/strip) 184 | 185 | 186 | -------------------------------------------------------------------------------- /TransitionAnimation/BMAnimateTransition.h: -------------------------------------------------------------------------------- 1 | // 2 | // BMAnimateTransition.h 3 | // TransitionAnimation 4 | // 5 | // Created by jashion on 16/5/10. 6 | // Copyright © 2016年 BMu. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | typedef NS_ENUM(NSInteger, BMAnimateTransitionOPerationType) { 13 | BMAnimateTransitionCustomType = 0, 14 | BMAnimateTransitionSnapViewTransformPush = 1, 15 | BMAnimateTransitionSnapViewTransformPop = 2, 16 | BMAnimateTransitionCircleLayerPush = 3, 17 | BMAnimateTransitionCircleLayerPop = 4, 18 | BMAnimateTransitionTabBarCircleLayer = 5, 19 | BMAnimateTransitionPresentFadeIn = 6, 20 | BMAnimateTransitionPresentFadeOut = 7 21 | }; 22 | 23 | @interface BMAnimateTransition : NSObject 24 | 25 | @property (nonatomic, assign) NSTimeInterval duration; 26 | @property (nonatomic, assign) BMAnimateTransitionOPerationType operation; 27 | 28 | /** 29 | * BMAnimateTransitionSnapViewTransformPushOrPopOrCircleLayerType 30 | */ 31 | 32 | @property (nonatomic, strong) UIView *snapView; 33 | @property (nonatomic, strong) UIView *initalView; 34 | @property (nonatomic, assign) CGRect initalFrame; 35 | @property (nonatomic, strong) UIView *finalView; 36 | @property (nonatomic, assign) CGRect finalFrame; 37 | 38 | /** 39 | * BMAnimateTransition 40 | * 41 | * @param duration duration 42 | * @param operation operation 43 | * 44 | * @return self 45 | */ 46 | 47 | - (instancetype)initWithDuration: (NSTimeInterval)duration operation: (BMAnimateTransitionOPerationType)operation; 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /TransitionAnimation/BMAnimateTransition.m: -------------------------------------------------------------------------------- 1 | // 2 | // BMAnimateTransition.m 3 | // TransitionAnimation 4 | // 5 | // Created by jashion on 16/5/10. 6 | // Copyright © 2016年 BMu. All rights reserved. 7 | // 8 | 9 | #import "BMAnimateTransition.h" 10 | 11 | @interface BMAnimateTransition () 12 | 13 | @property (nonatomic, strong) id transitionContext; 14 | 15 | @end 16 | 17 | @implementation BMAnimateTransition 18 | 19 | - (instancetype)init { 20 | return [self initWithDuration: 0.4 operation: BMAnimateTransitionCustomType]; 21 | } 22 | 23 | - (instancetype)initWithDuration: (NSTimeInterval)duration operation: (BMAnimateTransitionOPerationType)operation { 24 | if (self = [super init]) { 25 | _duration = duration; 26 | _operation = operation; 27 | } 28 | return self; 29 | } 30 | 31 | - (NSTimeInterval)transitionDuration:(id)transitionContext { 32 | return self.duration; 33 | } 34 | 35 | - (void)animateTransition:(id)transitionContext { 36 | self.transitionContext = transitionContext; 37 | UIView *container = [transitionContext containerView]; 38 | UIViewController *fromVC = [transitionContext viewControllerForKey: UITransitionContextFromViewControllerKey]; 39 | UIViewController *toVC = [transitionContext viewControllerForKey: UITransitionContextToViewControllerKey]; 40 | 41 | if (self.operation == BMAnimateTransitionCustomType) { 42 | return; 43 | } 44 | 45 | if (self.operation == BMAnimateTransitionSnapViewTransformPush) { 46 | [container addSubview: toVC.view]; 47 | 48 | self.finalView.hidden = YES; 49 | toVC.view.alpha = 0; 50 | 51 | self.snapView.frame = self.initalFrame; 52 | [container addSubview: self.snapView]; 53 | 54 | [UIView animateWithDuration: self.duration delay: 0.0 usingSpringWithDamping: 0.7 initialSpringVelocity: 1.0 options: UIViewAnimationOptionCurveEaseInOut animations:^{ 55 | self.snapView.frame = self.finalFrame; 56 | toVC.view.alpha = 1.f; 57 | } completion:^(BOOL finished) { 58 | self.finalView.hidden = NO; 59 | [self.snapView removeFromSuperview]; 60 | [transitionContext completeTransition: ![transitionContext transitionWasCancelled]]; 61 | }]; 62 | return; 63 | } 64 | 65 | if (self.operation == BMAnimateTransitionSnapViewTransformPop) { 66 | [container addSubview: toVC.view]; 67 | [container addSubview: fromVC.view]; 68 | 69 | self.initalView.hidden = YES; 70 | self.finalView.hidden = YES; 71 | toVC.view.alpha = 0; 72 | 73 | self.snapView.frame = self.initalFrame; 74 | [container addSubview: self.snapView]; 75 | 76 | [UIView animateWithDuration: self.duration delay: 0.0 usingSpringWithDamping: 0.7 initialSpringVelocity: 1.0 options: UIViewAnimationOptionCurveEaseInOut animations:^{ 77 | self.snapView.frame = self.finalFrame; 78 | toVC.view.alpha = 1; 79 | fromVC.view.alpha = 0; 80 | } completion:^(BOOL finished) { 81 | self.finalView.hidden = NO; 82 | self.initalView.hidden = ![transitionContext transitionWasCancelled]; 83 | [self.snapView removeFromSuperview]; 84 | [transitionContext completeTransition: ![transitionContext transitionWasCancelled]]; 85 | }]; 86 | return; 87 | } 88 | 89 | if (self.operation == BMAnimateTransitionCircleLayerPush) { 90 | [container addSubview: fromVC.view]; 91 | [container addSubview: toVC.view]; 92 | 93 | CGPoint initalPoint = CGPointMake(self.initalFrame.origin.x + self.initalFrame.size.width / 2, self.initalFrame.origin.y + self.initalFrame.size.height / 2); 94 | CGRect rect = toVC.view.bounds; 95 | CGFloat radius = [self calculateRadiusWithInitalPoint: initalPoint frame: rect]; 96 | 97 | UIBezierPath *initalPath = [UIBezierPath bezierPathWithOvalInRect: self.initalFrame]; 98 | UIBezierPath *finalPath = [UIBezierPath bezierPathWithArcCenter: initalPoint radius: radius startAngle: 0 endAngle: M_PI * 2 clockwise: YES]; 99 | 100 | [self circleMaskLayerAnimateWithController: toVC fromPath: initalPath.CGPath toPath: finalPath.CGPath animationKeyName: @"BMAnimateTransitionCircleLayerPush" animationDuration: self.duration]; 101 | 102 | self.snapView.frame = self.initalFrame; 103 | [container addSubview: self.snapView]; 104 | [UIView animateWithDuration: self.duration delay: 0 options: UIViewAnimationOptionCurveEaseOut animations:^{ 105 | self.snapView.transform = CGAffineTransformMakeScale(0.01, 0.01); 106 | self.snapView.alpha = 0; 107 | } completion:^(BOOL finished) { 108 | [self.snapView removeFromSuperview]; 109 | self.snapView.transform = CGAffineTransformIdentity; 110 | self.snapView.alpha = 1; 111 | }]; 112 | return; 113 | } 114 | 115 | if (self.operation == BMAnimateTransitionCircleLayerPop) { 116 | [container addSubview: toVC.view]; 117 | [container addSubview: fromVC.view]; 118 | 119 | CGPoint initalPoint = CGPointMake(self.finalFrame.origin.x + self.finalFrame.size.width / 2, self.finalFrame.origin.y + self.finalFrame.size.height / 2); 120 | CGRect rect = fromVC.view.bounds; 121 | CGFloat radius = [self calculateRadiusWithInitalPoint: initalPoint frame: rect]; 122 | 123 | UIBezierPath *initalPath = [UIBezierPath bezierPathWithArcCenter: initalPoint radius: radius startAngle: 0 endAngle: M_PI * 2 clockwise: YES]; 124 | UIBezierPath *finalPath = [UIBezierPath bezierPathWithOvalInRect: self.finalFrame]; 125 | 126 | [self circleMaskLayerAnimateWithController: fromVC fromPath: initalPath.CGPath toPath: finalPath.CGPath animationKeyName: @"BMAnimateTransitionCircleLayerPop" animationDuration: self.duration]; 127 | 128 | self.finalView.frame = self.finalFrame; 129 | [container addSubview: self.finalView]; 130 | 131 | self.finalView.bounds = CGRectMake(0, 0, 0.1, 0.1); 132 | [UIView animateWithDuration: self.duration delay: 0 options: UIViewAnimationOptionCurveEaseIn animations:^{ 133 | self.finalView.bounds = CGRectMake(0, 0, self.finalFrame.size.width, self.finalFrame.size.height); 134 | } completion:^(BOOL finished) { 135 | [self.finalView removeFromSuperview]; 136 | }]; 137 | return; 138 | } 139 | 140 | if (self.operation == BMAnimateTransitionTabBarCircleLayer) { 141 | [container addSubview: fromVC.view]; 142 | [container addSubview: toVC.view]; 143 | 144 | CGRect rect = toVC.view.frame; 145 | CGRect initalFrame; 146 | if ([toVC.tabBarItem.title isEqualToString: @"Home"]) { 147 | initalFrame = CGRectMake(0, rect.size.height - 49, rect.size.width / 3, 49); 148 | } else if ([toVC.tabBarItem.title isEqualToString: @"Message"]) { 149 | initalFrame = CGRectMake(rect.size.width / 3, rect.size.height - 49, rect.size.width / 3, 49); 150 | } else { 151 | initalFrame = CGRectMake(rect.size.width * 2 / 3, rect.size.height - 49, rect.size.width / 3, 49); 152 | } 153 | CGPoint initalPoint = CGPointMake(initalFrame.origin.x + initalFrame.size.width / 2, initalFrame.origin.y + initalFrame.size.height / 2); 154 | 155 | CGFloat radius = [self calculateRadiusWithInitalPoint: initalPoint frame: rect]; 156 | 157 | UIBezierPath *initalPath = [UIBezierPath bezierPathWithOvalInRect: initalFrame]; 158 | UIBezierPath *finalPath = [UIBezierPath bezierPathWithArcCenter: initalPoint radius: radius startAngle: 0 endAngle: M_PI * 2 clockwise: YES]; 159 | 160 | [self circleMaskLayerAnimateWithController: toVC fromPath: initalPath.CGPath toPath: finalPath.CGPath animationKeyName: @"BMAnimateTransitionTabBarCircleLayer" animationDuration: self.duration]; 161 | return; 162 | } 163 | 164 | if (self.operation == BMAnimateTransitionPresentFadeIn) { 165 | [container addSubview: toVC.view]; 166 | 167 | toVC.view.alpha = 0; 168 | [UIView animateWithDuration: self.duration animations:^{ 169 | toVC.view.alpha = 1.0; 170 | } completion:^(BOOL finished) { 171 | [transitionContext completeTransition: ![transitionContext transitionWasCancelled]]; 172 | }]; 173 | 174 | return; 175 | } 176 | 177 | if (self.operation == BMAnimateTransitionPresentFadeOut) { 178 | [container addSubview: toVC.view]; 179 | [container addSubview: fromVC.view]; 180 | 181 | [UIView animateWithDuration: self.duration animations:^{ 182 | fromVC.view.alpha = 0; 183 | } completion:^(BOOL finished) { 184 | [transitionContext completeTransition: ![transitionContext transitionWasCancelled]]; 185 | }]; 186 | return; 187 | } 188 | } 189 | 190 | #pragma mark - CAAnimationDelegate 191 | 192 | - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag { 193 | [self.transitionContext completeTransition: ![self.transitionContext transitionWasCancelled]]; 194 | [self.transitionContext viewControllerForKey: UITransitionContextFromViewControllerKey].view.layer.mask = nil; 195 | [self.transitionContext viewControllerForKey: UITransitionContextToViewControllerKey].view.layer.mask = nil; 196 | } 197 | 198 | #pragma mark - Private Method 199 | 200 | - (CGFloat)calculateRadiusWithInitalPoint: (CGPoint)initalPoint frame: (CGRect)frame { 201 | CGFloat radius; 202 | if (initalPoint.x >= frame.size.width / 2 && initalPoint.y >= frame.size.height / 2) { 203 | radius = sqrtf(powf(initalPoint.x, 2) + powf(initalPoint.y, 2)); 204 | } else if (initalPoint.x > frame.size.width / 2 && initalPoint.y < frame.size.height / 2) { 205 | radius = sqrtf(powf(initalPoint.x, 2) + powf(frame.size.height - initalPoint.y, 2)); 206 | } else if (initalPoint.x < frame.size.width / 2 && initalPoint.y > frame.size.height / 2) { 207 | radius = sqrtf(powf(frame.size.width - initalPoint.x, 2) + powf(initalPoint.y, 2)); 208 | } else { 209 | radius = sqrtf(powf(frame.size.width - initalPoint.x, 2) + powf(frame.size.height - initalPoint.y, 2)); 210 | } 211 | radius = radius + 20; 212 | return radius; 213 | } 214 | 215 | - (void)circleMaskLayerAnimateWithController: (UIViewController *)controller fromPath: (CGPathRef)fromPath toPath: (CGPathRef)toPath animationKeyName: (NSString *)keyName animationDuration: (NSTimeInterval)duration{ 216 | CAShapeLayer *maskLayer = [CAShapeLayer layer]; 217 | maskLayer.path = toPath; 218 | 219 | controller.view.layer.mask = maskLayer; 220 | CABasicAnimation *maskLayerAnimation = [CABasicAnimation animationWithKeyPath: @"path"]; 221 | maskLayerAnimation.duration = duration; 222 | maskLayerAnimation.fromValue = (__bridge id)fromPath; 223 | maskLayerAnimation.toValue = (__bridge id)toPath; 224 | maskLayerAnimation.delegate = self; 225 | [maskLayer addAnimation: maskLayerAnimation forKey: keyName]; 226 | } 227 | 228 | @end 229 | -------------------------------------------------------------------------------- /TransitionAnimation/BMInteractiveTransition.h: -------------------------------------------------------------------------------- 1 | // 2 | // BMInteractiveTransition.h 3 | // TransitionAnimation 4 | // 5 | // Created by jashion on 16/5/11. 6 | // Copyright © 2016年 BMu. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef NS_ENUM(NSInteger, BMInteractiveTransitionType) { 12 | BMInteractiveTransitionSnapViewTransform = 0, 13 | BMInteractiveTransitionCircleLayer = 1, 14 | BMInteractiveTransitionTabBarCircleLayer = 2 15 | }; 16 | 17 | @interface BMInteractiveTransition : UIPercentDrivenInteractiveTransition 18 | 19 | @property (nonatomic, assign) BOOL interacting; 20 | 21 | - (void)wireToViewController: (UIViewController *)viewController operation: (BMInteractiveTransitionType)operation; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /TransitionAnimation/BMInteractiveTransition.m: -------------------------------------------------------------------------------- 1 | // 2 | // BMInteractiveTransition.m 3 | // TransitionAnimation 4 | // 5 | // Created by jashion on 16/5/11. 6 | // Copyright © 2016年 BMu. All rights reserved. 7 | // 8 | 9 | #import "BMInteractiveTransition.h" 10 | 11 | @implementation BMInteractiveTransition 12 | { 13 | BOOL shouldComplete; 14 | UIViewController *controller; 15 | BMInteractiveTransitionType operationType; 16 | } 17 | 18 | - (void)wireToViewController: (UIViewController *)viewController operation: (BMInteractiveTransitionType)operation{ 19 | controller = viewController; 20 | operationType = operation; 21 | UIScreenEdgePanGestureRecognizer *screenEdgePan = [[UIScreenEdgePanGestureRecognizer alloc] initWithTarget: self action: @selector(handleInteractiveGesture:)]; 22 | screenEdgePan.edges = UIRectEdgeLeft; 23 | [viewController.view addGestureRecognizer: screenEdgePan]; 24 | } 25 | 26 | - (void)handleInteractiveGesture: (UIPanGestureRecognizer *)gesture { 27 | CGPoint translation = [gesture translationInView: gesture.view.superview]; 28 | 29 | switch (gesture.state) { 30 | case UIGestureRecognizerStateBegan: 31 | { 32 | self.interacting = YES; 33 | if (operationType == BMInteractiveTransitionSnapViewTransform || operationType == BMInteractiveTransitionCircleLayer) { 34 | [controller.navigationController popViewControllerAnimated: YES]; 35 | } else if (operationType == BMInteractiveTransitionTabBarCircleLayer) { 36 | } else { 37 | [controller dismissViewControllerAnimated: YES completion: nil]; 38 | } 39 | break; 40 | } 41 | 42 | case UIGestureRecognizerStateChanged: 43 | { 44 | CGFloat fraction = translation.x / (CGRectGetWidth([UIScreen mainScreen].bounds) / 2); 45 | fraction= fminf(fmaxf(fraction, 0.0), 1.0); 46 | shouldComplete = operationType == BMInteractiveTransitionSnapViewTransform ? (fraction > 0.15) : (fraction > 0.5); 47 | [self updateInteractiveTransition: fraction]; 48 | break; 49 | } 50 | 51 | case UIGestureRecognizerStateCancelled: 52 | case UIGestureRecognizerStateEnded: 53 | { 54 | self.interacting = NO; 55 | shouldComplete? [self finishInteractiveTransition] : [self cancelInteractiveTransition]; 56 | break; 57 | } 58 | 59 | default: 60 | break; 61 | } 62 | } 63 | 64 | @end 65 | -------------------------------------------------------------------------------- /TransitionAnimation/BMTabBarController.h: -------------------------------------------------------------------------------- 1 | // 2 | // BMTabBarController.h 3 | // TransitionAnimation 4 | // 5 | // Created by jashion on 16/5/14. 6 | // Copyright © 2016年 BMu. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface BMTabBarController : UITabBarController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /TransitionAnimation/BMTabBarController.m: -------------------------------------------------------------------------------- 1 | // 2 | // BMTabBarController.m 3 | // TransitionAnimation 4 | // 5 | // Created by jashion on 16/5/14. 6 | // Copyright © 2016年 BMu. All rights reserved. 7 | // 8 | 9 | #import "BMTabBarController.h" 10 | 11 | @implementation BMTabBarController 12 | 13 | - (instancetype)init { 14 | if (self = [super init]) { 15 | 16 | } 17 | return self; 18 | } 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /TransitionAnimation/ColorUtils.h: -------------------------------------------------------------------------------- 1 | // 2 | // ColorUtils.h 3 | // TransitionAnimation 4 | // 5 | // Created by jashion on 16/5/7. 6 | // Copyright © 2016年 BMu. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface ColorUtils : NSObject 13 | 14 | + (UIColor *)mainColor; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /TransitionAnimation/ColorUtils.m: -------------------------------------------------------------------------------- 1 | // 2 | // ColorUtils.m 3 | // TransitionAnimation 4 | // 5 | // Created by jashion on 16/5/7. 6 | // Copyright © 2016年 BMu. All rights reserved. 7 | // 8 | 9 | #import "ColorUtils.h" 10 | 11 | @implementation ColorUtils 12 | 13 | + (UIColor *)mainColor { 14 | return [UIColor colorWithRed:1.000 green:0.800 blue:0.000 alpha:1.000]; 15 | } 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /TransitionAnimation/DetailController.h: -------------------------------------------------------------------------------- 1 | // 2 | // DetailController.h 3 | // TransitionAnimation 4 | // 5 | // Created by jashion on 16/5/4. 6 | // Copyright © 2016年 BMu. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface DetailController : UIViewController 12 | 13 | @property (nonatomic, strong) UIImageView *topImageView; 14 | @property (nonatomic, strong) UITableView *detailTableView; 15 | 16 | - (instancetype)initWithTitle: (NSString *)title image: (UIImage *)image; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /TransitionAnimation/DetailController.m: -------------------------------------------------------------------------------- 1 | // 2 | // DetailController.m 3 | // TransitionAnimation 4 | // 5 | // Created by jashion on 16/5/4. 6 | // Copyright © 2016年 BMu. All rights reserved. 7 | // 8 | 9 | #import "DetailController.h" 10 | #import "DetailTableViewCell.h" 11 | #import "HomeViewController.h" 12 | #import "PersonProfileViewController.h" 13 | #import "BMAnimateTransition.h" 14 | #import "BMInteractiveTransition.h" 15 | #import "UIImage+Tint.h" 16 | #import "ColorUtils.h" 17 | 18 | #define kScreenWidth CGRectGetWidth([UIScreen mainScreen].bounds) 19 | #define topImageViewHeight kScreenWidth * 3 / 4 20 | 21 | @interface DetailController () 22 | 23 | @property (nonatomic, strong) BMAnimateTransition *transition; 24 | @property (nonatomic, strong) BMInteractiveTransition *interactive; 25 | 26 | @end 27 | 28 | @implementation DetailController 29 | { 30 | UIView *topImageContainer; 31 | UIImage *topImage; 32 | DetailTableViewCell *selectedCell; 33 | UIView *snapView; 34 | CGRect snapFrame; 35 | NSArray *names; 36 | NSArray *contents; 37 | NSArray *avatars; 38 | NSArray *titles; 39 | } 40 | 41 | - (instancetype)initWithTitle: (NSString *)title image: (UIImage *)image { 42 | if (self = [super init]) { 43 | self.navigationItem.title = title; 44 | self.hidesBottomBarWhenPushed = YES; 45 | _transition = [BMAnimateTransition new]; 46 | _interactive = [BMInteractiveTransition new]; 47 | topImage = image; 48 | names = @[@"morgan", @"Jashion", @"Kevin Burr", @"Sean Furr", @"Marry", @"Stan", @"Sulian", @"Sheet"]; 49 | contents = @[@"Awesome atmosphere.I like it!Can i get your contact?", @"Love it!You are very excellent!God bless you,AMEN.", @"Great!Something like you.I want to learn!Hehe,can you teach me?", @"like it to much.I painted it as you.", @"Nice :)", @"Sweet Lord.This is gorgeous,great job guys!", @"Supernice! Can i have it printed on poster please? :)", @"Whoa!This is amazing."]; 50 | avatars = @[@"morgan", @"Jashion", @"Kevin Burr", @"Sean Furr", @"Marry", @"Stan", @"Sulian", @"Sheet"]; 51 | titles = @[@"Roma Datsyuk", @"Balkan Brothers", @"Shamsuddin", @"Jakub Nespor", @"Thomas Meijer", @"Stan", @"Sulian", @"Sheet"]; 52 | } 53 | return self; 54 | } 55 | 56 | - (void)loadView { 57 | [super loadView]; 58 | 59 | UIButton *backButton = [UIButton buttonWithType: UIButtonTypeSystem]; 60 | backButton.frame = CGRectMake(0, 0, 40, 44); 61 | [backButton setImage: [UIImage imageNamed:@"BackIcon"] forState: UIControlStateNormal]; 62 | [backButton setImageEdgeInsets: UIEdgeInsetsMake(0, - 30, 0, 0)]; 63 | [backButton addTarget: self action: @selector(back) forControlEvents: UIControlEventTouchUpInside]; 64 | self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView: backButton]; 65 | 66 | self.detailTableView = [[UITableView alloc] initWithFrame: [UIScreen mainScreen].bounds style: UITableViewStyleGrouped]; 67 | self.detailTableView.dataSource = self; 68 | self.detailTableView.delegate = self; 69 | [self.detailTableView registerClass: [DetailTableViewCell class] forCellReuseIdentifier: NSStringFromClass([DetailTableViewCell class])]; 70 | self.detailTableView.contentInset = UIEdgeInsetsMake(topImageViewHeight, 0, 0, 0); 71 | self.detailTableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine; 72 | self.detailTableView.separatorInset = UIEdgeInsetsMake(0, 10, 0, 10); 73 | [self.view addSubview: self.detailTableView]; 74 | 75 | topImageContainer = [[UIView alloc] initWithFrame: CGRectMake(0, - topImageViewHeight, kScreenWidth, topImageViewHeight)]; 76 | topImageContainer.clipsToBounds = YES; 77 | [self.detailTableView addSubview: topImageContainer]; 78 | 79 | self.topImageView = [[UIImageView alloc] initWithFrame: topImageContainer.bounds]; 80 | self.topImageView.image = topImage; 81 | self.topImageView.contentMode = UIViewContentModeScaleToFill; 82 | [topImageContainer addSubview: self.topImageView]; 83 | } 84 | 85 | - (void)viewDidAppear:(BOOL)animated { 86 | [super viewDidAppear: animated]; 87 | 88 | for (UIViewController *subVC in self.navigationController.viewControllers) { 89 | if ([subVC isKindOfClass: [HomeViewController class]]) { 90 | self.navigationController.delegate = (HomeViewController *)subVC; 91 | } 92 | } 93 | } 94 | 95 | #pragma mark - UITableViewDataSource 96 | 97 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 98 | return names.count; 99 | } 100 | 101 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 102 | DetailTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: NSStringFromClass([DetailTableViewCell class])]; 103 | [cell setAvatar: [UIImage imageNamed: avatars[indexPath.row]] name: names[indexPath.row] des: contents[indexPath.row]]; 104 | return cell; 105 | } 106 | 107 | #pragma mark - UITableViewDelegate 108 | 109 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 110 | return 80; 111 | } 112 | 113 | - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { 114 | return 60; 115 | } 116 | 117 | - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { 118 | return 0.1; 119 | } 120 | 121 | - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { 122 | UIView *buttonsContainer = [[UIView alloc] initWithFrame: CGRectMake(0, 0, kScreenWidth, 60)]; 123 | buttonsContainer.backgroundColor = [UIColor colorWithWhite: 0.8 alpha: 1.0]; 124 | 125 | CGFloat buttonWidth = (buttonsContainer.frame.size.width - 1) / 3; 126 | CGFloat buttonHeight = buttonsContainer.frame.size.height - 0.5; 127 | 128 | UIButton *clikedLikeButton = [self createButtonWithImage: [[UIImage imageNamed:@"LikeIcon"] imageWithTintColor: [ColorUtils mainColor] blendMode: kCGBlendModeDestinationIn] title: @"2048" frame: CGRectMake(0, 0.5, buttonWidth, buttonHeight)]; 129 | [buttonsContainer addSubview: clikedLikeButton]; 130 | 131 | UIButton *clickedCommentButton = [self createButtonWithImage: [[UIImage imageNamed:@"CommentIcon"] imageWithTintColor: [ColorUtils mainColor] blendMode: kCGBlendModeDestinationIn] title: @"10086" frame: CGRectMake(buttonWidth + 0.5, 0.5, buttonWidth, buttonHeight)]; 132 | [buttonsContainer addSubview: clickedCommentButton]; 133 | 134 | UIButton *clickedFollowButton = [self createButtonWithImage: [[UIImage imageNamed:@"FollowIcon"] imageWithTintColor: [ColorUtils mainColor] blendMode: kCGBlendModeDestinationIn ] title: @"250" frame: CGRectMake(buttonWidth * 2 + 1, 0.5, buttonWidth, buttonHeight)]; 135 | [buttonsContainer addSubview: clickedFollowButton]; 136 | 137 | return buttonsContainer; 138 | } 139 | 140 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 141 | self.navigationController.delegate = self; 142 | selectedCell = [tableView cellForRowAtIndexPath: indexPath]; 143 | selectedCell.selected = NO; 144 | snapView = [selectedCell.avatarImageView snapshotViewAfterScreenUpdates: NO]; 145 | snapFrame = [selectedCell.avatarImageView convertRect: selectedCell.avatarImageView.bounds toView: self.view]; 146 | PersonProfileViewController *person = [[PersonProfileViewController alloc] initWithName: names[indexPath.row] title: titles[indexPath.row] image: topImage]; 147 | [self.interactive wireToViewController: person operation: BMInteractiveTransitionCircleLayer]; 148 | [self.navigationController pushViewController: person animated: YES]; 149 | } 150 | 151 | #pragma mark - UIScrollViewDelegate 152 | 153 | - (void)scrollViewDidScroll:(UIScrollView *)scrollView { 154 | CGFloat offset = scrollView.contentOffset.y + topImageViewHeight + 64; 155 | if (offset < 0) { 156 | topImageContainer.bounds = CGRectMake(0, 0, kScreenWidth - offset, topImageViewHeight - offset); 157 | topImageContainer.center = CGPointMake(kScreenWidth / 2, - topImageViewHeight / 2 + offset / 2); 158 | self.topImageView.frame = topImageContainer.bounds; 159 | } else if(offset > 0){ 160 | self.topImageView.center = CGPointMake(kScreenWidth / 2, topImageViewHeight / 2 + offset / 3); 161 | } else { 162 | [UIView animateWithDuration: 0.1 animations:^{ 163 | topImageContainer.frame = CGRectMake(0, - topImageViewHeight, kScreenWidth, topImageViewHeight); 164 | self.topImageView.frame = topImageContainer.bounds; 165 | }]; 166 | } 167 | } 168 | 169 | #pragma mark - UINavigationControllerDelegate 170 | 171 | - (nullable id )navigationController:(UINavigationController *)navigationController 172 | animationControllerForOperation:(UINavigationControllerOperation)operation 173 | fromViewController:(UIViewController *)fromVC 174 | toViewController:(UIViewController *)toVC { 175 | 176 | 177 | if (operation == UINavigationControllerOperationPush) { 178 | self.transition.operation = BMAnimateTransitionCircleLayerPush; 179 | self.transition.duration = 0.4; 180 | self.transition.snapView = snapView; 181 | self.transition.initalFrame = snapFrame; 182 | return self.transition; 183 | } else if (operation == UINavigationControllerOperationPop) { 184 | self.transition.operation = BMAnimateTransitionCircleLayerPop; 185 | self.transition.duration = 0.4; 186 | self.transition.finalView = snapView; 187 | self.transition.finalFrame = snapFrame; 188 | return self.transition; 189 | } else { 190 | return nil; 191 | } 192 | } 193 | 194 | - (nullable id )navigationController:(UINavigationController *)navigationController 195 | interactionControllerForAnimationController:(id ) animationController { 196 | return self.interactive.interacting ? self.interactive : nil; 197 | } 198 | 199 | #pragma mark - Event Response 200 | 201 | - (void)back { 202 | [self.navigationController popViewControllerAnimated: YES]; 203 | } 204 | 205 | #pragma mark - Private Method 206 | 207 | - (UIButton *)createButtonWithImage: (UIImage *)image title: (NSString *)title frame: (CGRect)frame { 208 | UIButton *button = [UIButton buttonWithType: UIButtonTypeCustom]; 209 | button.frame = frame; 210 | button.backgroundColor = [UIColor whiteColor]; 211 | button.titleLabel.font = [UIFont boldSystemFontOfSize: 16]; 212 | button.titleEdgeInsets = UIEdgeInsetsMake(26, 0, 0, 0); 213 | [button setTitle: title forState: UIControlStateNormal]; 214 | [button setTitleColor: [UIColor blackColor] forState: UIControlStateNormal]; 215 | [button addTarget: self action: @selector(buttonBgColorChange:) forControlEvents: UIControlEventTouchDown]; 216 | [button addTarget: self action: @selector(buttonBgColorReset:) forControlEvents: UIControlEventTouchDragOutside]; 217 | [button addTarget: self action: @selector(buttonClick:) forControlEvents: UIControlEventTouchUpInside]; 218 | UIImageView *imageView = [[UIImageView alloc] initWithImage: image]; 219 | imageView.contentMode = UIViewContentModeCenter; 220 | imageView.bounds = CGRectMake(0, 0, frame.size.height / 2, frame.size.height / 2); 221 | imageView.center = CGPointMake(frame.size.width / 2, frame.size.height / 4); 222 | [button addSubview: imageView]; 223 | return button; 224 | } 225 | 226 | - (void)buttonBgColorChange: (id)sender { 227 | UIButton *button = (UIButton *)sender; 228 | button.backgroundColor = [UIColor colorWithWhite:0.800 alpha:1.000]; 229 | } 230 | 231 | - (void)buttonBgColorReset: (id)sender { 232 | UIButton *button = (UIButton *)sender; 233 | button.backgroundColor = [UIColor whiteColor]; 234 | } 235 | 236 | - (void)buttonClick: (id)sender { 237 | UIButton *button = (UIButton *)sender; 238 | button.backgroundColor = [UIColor whiteColor]; 239 | UIAlertController *alert = [UIAlertController alertControllerWithTitle: @"Congratulation!" message: @"Hello world!" preferredStyle: UIAlertControllerStyleAlert]; 240 | UIAlertAction *action = [UIAlertAction actionWithTitle: @"OK!" style: UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { 241 | [alert dismissViewControllerAnimated: YES completion: nil]; 242 | }]; 243 | [alert addAction: action]; 244 | [self presentViewController: alert animated: YES completion: nil]; 245 | } 246 | 247 | @end 248 | -------------------------------------------------------------------------------- /TransitionAnimation/DetailTableViewCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // DetailTableViewCell.h 3 | // TransitionAnimation 4 | // 5 | // Created by jashion on 16/5/7. 6 | // Copyright © 2016年 BMu. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface DetailTableViewCell : UITableViewCell 12 | 13 | @property (nonatomic, strong) UIImageView *avatarImageView; 14 | 15 | - (void)setAvatar: (UIImage *)image name: (NSString *)name des: (NSString *)des; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /TransitionAnimation/DetailTableViewCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // DetailTableViewCell.m 3 | // TransitionAnimation 4 | // 5 | // Created by jashion on 16/5/7. 6 | // Copyright © 2016年 BMu. All rights reserved. 7 | // 8 | 9 | #import "DetailTableViewCell.h" 10 | #import "ColorUtils.h" 11 | 12 | @implementation DetailTableViewCell 13 | { 14 | UILabel *nameLabel; 15 | UILabel *desLabel; 16 | } 17 | 18 | - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { 19 | if (self = [super initWithStyle: style reuseIdentifier: reuseIdentifier]) { 20 | [self buildView]; 21 | } 22 | return self; 23 | } 24 | 25 | - (void)buildView { 26 | _avatarImageView = [[UIImageView alloc] initWithFrame: CGRectMake(10, 10, 50, 50)]; 27 | _avatarImageView.layer.cornerRadius = 25; 28 | _avatarImageView.layer.masksToBounds = YES; 29 | [self.contentView addSubview: _avatarImageView]; 30 | 31 | CGRect rect = [UIScreen mainScreen].bounds; 32 | nameLabel = [[UILabel alloc] initWithFrame: CGRectMake(70, 5, rect.size.width - 80, 25)]; 33 | nameLabel.font = [UIFont systemFontOfSize: 16]; 34 | nameLabel.textColor = [ColorUtils mainColor]; 35 | [self.contentView addSubview: nameLabel]; 36 | 37 | desLabel = [[UILabel alloc] initWithFrame: CGRectMake(70, 26, rect.size.width - 80, 54)]; 38 | desLabel.font = [UIFont systemFontOfSize: 15]; 39 | desLabel.textColor = [UIColor blackColor]; 40 | desLabel.numberOfLines = 0; 41 | [self.contentView addSubview: desLabel]; 42 | } 43 | 44 | - (void)setAvatar: (UIImage *)image name: (NSString *)name des: (NSString *)des { 45 | _avatarImageView.image = image; 46 | nameLabel.text = name; 47 | desLabel.text = des; 48 | } 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /TransitionAnimation/FXBlurView.h: -------------------------------------------------------------------------------- 1 | // 2 | // FXBlurView.h 3 | // 4 | // Version 1.6.4 5 | // 6 | // Created by Nick Lockwood on 25/08/2013. 7 | // Copyright (c) 2013 Charcoal Design 8 | // 9 | // Distributed under the permissive zlib License 10 | // Get the latest version from here: 11 | // 12 | // https://github.com/nicklockwood/FXBlurView 13 | // 14 | // This software is provided 'as-is', without any express or implied 15 | // warranty. In no event will the authors be held liable for any damages 16 | // arising from the use of this software. 17 | // 18 | // Permission is granted to anyone to use this software for any purpose, 19 | // including commercial applications, and to alter it and redistribute it 20 | // freely, subject to the following restrictions: 21 | // 22 | // 1. The origin of this software must not be misrepresented; you must not 23 | // claim that you wrote the original software. If you use this software 24 | // in a product, an acknowledgment in the product documentation would be 25 | // appreciated but is not required. 26 | // 27 | // 2. Altered source versions must be plainly marked as such, and must not be 28 | // misrepresented as being the original software. 29 | // 30 | // 3. This notice may not be removed or altered from any source distribution. 31 | // 32 | 33 | 34 | #import 35 | #import 36 | #import 37 | 38 | 39 | #pragma GCC diagnostic push 40 | #pragma GCC diagnostic ignored "-Wobjc-missing-property-synthesis" 41 | 42 | 43 | #import 44 | #undef weak_ref 45 | #if __has_feature(objc_arc) && __has_feature(objc_arc_weak) 46 | #define weak_ref weak 47 | #else 48 | #define weak_ref unsafe_unretained 49 | #endif 50 | 51 | 52 | @interface UIImage (FXBlurView) 53 | 54 | - (UIImage *)blurredImageWithRadius:(CGFloat)radius iterations:(NSUInteger)iterations tintColor:(UIColor *)tintColor; 55 | 56 | @end 57 | 58 | 59 | @interface FXBlurView : UIView 60 | 61 | + (void)setBlurEnabled:(BOOL)blurEnabled; 62 | + (void)setUpdatesEnabled; 63 | + (void)setUpdatesDisabled; 64 | 65 | @property (nonatomic, getter = isBlurEnabled) BOOL blurEnabled; 66 | @property (nonatomic, getter = isDynamic) BOOL dynamic; 67 | @property (nonatomic, assign) NSUInteger iterations; 68 | @property (nonatomic, assign) NSTimeInterval updateInterval; 69 | @property (nonatomic, assign) CGFloat blurRadius; 70 | @property (nonatomic, strong) UIColor *tintColor; 71 | @property (nonatomic, weak_ref) IBOutlet UIView *underlyingView; 72 | 73 | - (void)updateAsynchronously:(BOOL)async completion:(void (^)())completion; 74 | 75 | - (void)clearImage; 76 | 77 | @end 78 | 79 | 80 | #pragma GCC diagnostic pop 81 | 82 | -------------------------------------------------------------------------------- /TransitionAnimation/FXBlurView.m: -------------------------------------------------------------------------------- 1 | // 2 | // FXBlurView.m 3 | // 4 | // Version 1.6.4 5 | // 6 | // Created by Nick Lockwood on 25/08/2013. 7 | // Copyright (c) 2013 Charcoal Design 8 | // 9 | // Distributed under the permissive zlib License 10 | // Get the latest version from here: 11 | // 12 | // https://github.com/nicklockwood/FXBlurView 13 | // 14 | // This software is provided 'as-is', without any express or implied 15 | // warranty. In no event will the authors be held liable for any damages 16 | // arising from the use of this software. 17 | // 18 | // Permission is granted to anyone to use this software for any purpose, 19 | // including commercial applications, and to alter it and redistribute it 20 | // freely, subject to the following restrictions: 21 | // 22 | // 1. The origin of this software must not be misrepresented; you must not 23 | // claim that you wrote the original software. If you use this software 24 | // in a product, an acknowledgment in the product documentation would be 25 | // appreciated but is not required. 26 | // 27 | // 2. Altered source versions must be plainly marked as such, and must not be 28 | // misrepresented as being the original software. 29 | // 30 | // 3. This notice may not be removed or altered from any source distribution. 31 | // 32 | 33 | 34 | #import "FXBlurView.h" 35 | #import 36 | 37 | 38 | #pragma GCC diagnostic ignored "-Wobjc-missing-property-synthesis" 39 | #pragma GCC diagnostic ignored "-Wdirect-ivar-access" 40 | #pragma GCC diagnostic ignored "-Wgnu" 41 | 42 | 43 | #import 44 | #if !__has_feature(objc_arc) 45 | #error This class requires automatic reference counting 46 | #endif 47 | 48 | 49 | @implementation UIImage (FXBlurView) 50 | 51 | - (UIImage *)blurredImageWithRadius:(CGFloat)radius iterations:(NSUInteger)iterations tintColor:(UIColor *)tintColor 52 | { 53 | //image must be nonzero size 54 | if (floorf(self.size.width) * floorf(self.size.height) <= 0.0f) return self; 55 | 56 | //boxsize must be an odd integer 57 | uint32_t boxSize = (uint32_t)(radius * self.scale); 58 | if (boxSize % 2 == 0) boxSize ++; 59 | 60 | //create image buffers 61 | CGImageRef imageRef = self.CGImage; 62 | 63 | //convert to ARGB if it isn't 64 | if (CGImageGetBitsPerPixel(imageRef) != 32 || 65 | CGImageGetBitsPerComponent(imageRef) != 8 || 66 | !((CGImageGetBitmapInfo(imageRef) & kCGBitmapAlphaInfoMask))) 67 | { 68 | UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale); 69 | [self drawAtPoint:CGPointZero]; 70 | imageRef = UIGraphicsGetImageFromCurrentImageContext().CGImage; 71 | UIGraphicsEndImageContext(); 72 | } 73 | 74 | vImage_Buffer buffer1, buffer2; 75 | buffer1.width = buffer2.width = CGImageGetWidth(imageRef); 76 | buffer1.height = buffer2.height = CGImageGetHeight(imageRef); 77 | buffer1.rowBytes = buffer2.rowBytes = CGImageGetBytesPerRow(imageRef); 78 | size_t bytes = buffer1.rowBytes * buffer1.height; 79 | buffer1.data = malloc(bytes); 80 | buffer2.data = malloc(bytes); 81 | 82 | //create temp buffer 83 | void *tempBuffer = malloc((size_t)vImageBoxConvolve_ARGB8888(&buffer1, &buffer2, NULL, 0, 0, boxSize, boxSize, 84 | NULL, kvImageEdgeExtend + kvImageGetTempBufferSize)); 85 | 86 | //copy image data 87 | CFDataRef dataSource = CGDataProviderCopyData(CGImageGetDataProvider(imageRef)); 88 | memcpy(buffer1.data, CFDataGetBytePtr(dataSource), bytes); 89 | CFRelease(dataSource); 90 | 91 | for (NSUInteger i = 0; i < iterations; i++) 92 | { 93 | //perform blur 94 | vImageBoxConvolve_ARGB8888(&buffer1, &buffer2, tempBuffer, 0, 0, boxSize, boxSize, NULL, kvImageEdgeExtend); 95 | 96 | //swap buffers 97 | void *temp = buffer1.data; 98 | buffer1.data = buffer2.data; 99 | buffer2.data = temp; 100 | } 101 | 102 | //free buffers 103 | free(buffer2.data); 104 | free(tempBuffer); 105 | 106 | //create image context from buffer 107 | CGContextRef ctx = CGBitmapContextCreate(buffer1.data, buffer1.width, buffer1.height, 108 | 8, buffer1.rowBytes, CGImageGetColorSpace(imageRef), 109 | CGImageGetBitmapInfo(imageRef)); 110 | 111 | //apply tint 112 | if (tintColor && CGColorGetAlpha(tintColor.CGColor) > 0.0f) 113 | { 114 | CGContextSetFillColorWithColor(ctx, [tintColor colorWithAlphaComponent:0.25].CGColor); 115 | CGContextSetBlendMode(ctx, kCGBlendModePlusLighter); 116 | CGContextFillRect(ctx, CGRectMake(0, 0, buffer1.width, buffer1.height)); 117 | } 118 | 119 | //create image from context 120 | imageRef = CGBitmapContextCreateImage(ctx); 121 | UIImage *image = [UIImage imageWithCGImage:imageRef scale:self.scale orientation:self.imageOrientation]; 122 | CGImageRelease(imageRef); 123 | CGContextRelease(ctx); 124 | free(buffer1.data); 125 | return image; 126 | } 127 | 128 | @end 129 | 130 | 131 | @interface FXBlurScheduler : NSObject 132 | 133 | @property (nonatomic, strong) NSMutableArray *views; 134 | @property (nonatomic, assign) NSUInteger viewIndex; 135 | @property (nonatomic, assign) NSUInteger updatesEnabled; 136 | @property (nonatomic, assign) BOOL blurEnabled; 137 | @property (nonatomic, assign) BOOL updating; 138 | 139 | @end 140 | 141 | 142 | @interface FXBlurLayer: CALayer 143 | 144 | @property (nonatomic, assign) CGFloat blurRadius; 145 | 146 | @end 147 | 148 | 149 | @implementation FXBlurLayer 150 | 151 | @dynamic blurRadius; 152 | 153 | + (BOOL)needsDisplayForKey:(NSString *)key 154 | { 155 | if ([@[@"blurRadius", @"bounds", @"position"] containsObject:key]) 156 | { 157 | return YES; 158 | } 159 | return [super needsDisplayForKey:key]; 160 | } 161 | 162 | @end 163 | 164 | 165 | @interface FXBlurView () 166 | 167 | @property (nonatomic, assign) BOOL iterationsSet; 168 | @property (nonatomic, assign) BOOL blurRadiusSet; 169 | @property (nonatomic, assign) BOOL dynamicSet; 170 | @property (nonatomic, assign) BOOL blurEnabledSet; 171 | @property (nonatomic, strong) NSDate *lastUpdate; 172 | @property (nonatomic, assign) BOOL needsDrawViewHierarchy; 173 | 174 | - (UIImage *)snapshotOfUnderlyingView; 175 | - (BOOL)shouldUpdate; 176 | 177 | @end 178 | 179 | 180 | @implementation FXBlurScheduler 181 | 182 | + (instancetype)sharedInstance 183 | { 184 | static FXBlurScheduler *sharedInstance = nil; 185 | if (!sharedInstance) 186 | { 187 | sharedInstance = [[FXBlurScheduler alloc] init]; 188 | } 189 | return sharedInstance; 190 | } 191 | 192 | - (instancetype)init 193 | { 194 | if ((self = [super init])) 195 | { 196 | _updatesEnabled = 1; 197 | _blurEnabled = YES; 198 | _views = [[NSMutableArray alloc] init]; 199 | } 200 | return self; 201 | } 202 | 203 | - (void)setBlurEnabled:(BOOL)blurEnabled 204 | { 205 | _blurEnabled = blurEnabled; 206 | if (blurEnabled) 207 | { 208 | for (FXBlurView *view in self.views) 209 | { 210 | [view setNeedsDisplay]; 211 | } 212 | [self updateAsynchronously]; 213 | } 214 | } 215 | 216 | - (void)setUpdatesEnabled 217 | { 218 | _updatesEnabled ++; 219 | [self updateAsynchronously]; 220 | } 221 | 222 | - (void)setUpdatesDisabled 223 | { 224 | _updatesEnabled --; 225 | } 226 | 227 | - (void)addView:(FXBlurView *)view 228 | { 229 | if (![self.views containsObject:view]) 230 | { 231 | [self.views addObject:view]; 232 | [self updateAsynchronously]; 233 | } 234 | } 235 | 236 | - (void)removeView:(FXBlurView *)view 237 | { 238 | NSUInteger index = [self.views indexOfObject:view]; 239 | if (index != NSNotFound) 240 | { 241 | if (index <= self.viewIndex) 242 | { 243 | self.viewIndex --; 244 | } 245 | [self.views removeObjectAtIndex:index]; 246 | } 247 | } 248 | 249 | - (void)updateAsynchronously 250 | { 251 | if (self.blurEnabled && !self.updating && self.updatesEnabled > 0 && [self.views count]) 252 | { 253 | NSTimeInterval timeUntilNextUpdate = 1.0 / 60; 254 | 255 | //loop through until we find a view that's ready to be drawn 256 | self.viewIndex = self.viewIndex % [self.views count]; 257 | for (NSUInteger i = self.viewIndex; i < [self.views count]; i++) 258 | { 259 | FXBlurView *view = self.views[i]; 260 | if (view.dynamic && !view.hidden && view.window && [view shouldUpdate]) 261 | { 262 | NSTimeInterval nextUpdate = [view.lastUpdate timeIntervalSinceNow] + view.updateInterval; 263 | if (!view.lastUpdate || nextUpdate <= 0) 264 | { 265 | self.updating = YES; 266 | [view updateAsynchronously:YES completion:^{ 267 | 268 | //render next view 269 | self.updating = NO; 270 | self.viewIndex = i + 1; 271 | [self updateAsynchronously]; 272 | }]; 273 | return; 274 | } 275 | else 276 | { 277 | timeUntilNextUpdate = MIN(timeUntilNextUpdate, nextUpdate); 278 | } 279 | } 280 | } 281 | 282 | //try again, delaying until the time when the next view needs an update. 283 | self.viewIndex = 0; 284 | [self performSelector:@selector(updateAsynchronously) 285 | withObject:nil 286 | afterDelay:timeUntilNextUpdate 287 | inModes:@[NSDefaultRunLoopMode, UITrackingRunLoopMode]]; 288 | } 289 | } 290 | 291 | @end 292 | 293 | 294 | @implementation FXBlurView 295 | 296 | @synthesize underlyingView = _underlyingView; 297 | 298 | + (void)setBlurEnabled:(BOOL)blurEnabled 299 | { 300 | [FXBlurScheduler sharedInstance].blurEnabled = blurEnabled; 301 | } 302 | 303 | + (void)setUpdatesEnabled 304 | { 305 | [[FXBlurScheduler sharedInstance] setUpdatesEnabled]; 306 | } 307 | 308 | + (void)setUpdatesDisabled 309 | { 310 | [[FXBlurScheduler sharedInstance] setUpdatesDisabled]; 311 | } 312 | 313 | + (Class)layerClass 314 | { 315 | return [FXBlurLayer class]; 316 | } 317 | 318 | - (void)setUp 319 | { 320 | if (!_iterationsSet) _iterations = 3; 321 | if (!_blurRadiusSet) [self blurLayer].blurRadius = 40; 322 | if (!_dynamicSet) _dynamic = YES; 323 | if (!_blurEnabledSet) _blurEnabled = YES; 324 | self.updateInterval = _updateInterval; 325 | self.layer.magnificationFilter = @"linear"; // kCAFilterLinear 326 | 327 | unsigned int numberOfMethods; 328 | Method *methods = class_copyMethodList([UIView class], &numberOfMethods); 329 | for (unsigned int i = 0; i < numberOfMethods; i++) 330 | { 331 | Method method = methods[i]; 332 | SEL selector = method_getName(method); 333 | if (selector == @selector(tintColor)) 334 | { 335 | _tintColor = ((id (*)(id,SEL))method_getImplementation(method))(self, selector); 336 | break; 337 | } 338 | } 339 | free(methods); 340 | 341 | } 342 | 343 | - (id)initWithFrame:(CGRect)frame 344 | { 345 | if ((self = [super initWithFrame:frame])) 346 | { 347 | [self setUp]; 348 | self.clipsToBounds = YES; 349 | } 350 | return self; 351 | } 352 | 353 | - (id)initWithCoder:(NSCoder *)aDecoder 354 | { 355 | if ((self = [super initWithCoder:aDecoder])) 356 | { 357 | [self setUp]; 358 | } 359 | return self; 360 | } 361 | 362 | - (void)dealloc 363 | { 364 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 365 | } 366 | 367 | 368 | - (BOOL)viewOrSubviewNeedsDrawViewHierarchy:(UIView *)view 369 | { 370 | if ([view isKindOfClass:NSClassFromString(@"SKView")] || 371 | [view.layer isKindOfClass:NSClassFromString(@"CAEAGLLayer")] || 372 | [view.layer isKindOfClass:NSClassFromString(@"AVPlayerLayer")] || 373 | ABS(view.layer.transform.m34) > 0) 374 | { 375 | return YES; 376 | } 377 | for (UIView *subview in view.subviews) 378 | { 379 | if ([self viewOrSubviewNeedsDrawViewHierarchy:subview]) 380 | { 381 | return YES; 382 | } 383 | } 384 | return NO; 385 | } 386 | 387 | - (void)willMoveToSuperview:(UIView *)newSuperview 388 | { 389 | [super willMoveToSuperview:newSuperview]; 390 | if (!_underlyingView) 391 | { 392 | _needsDrawViewHierarchy = [self viewOrSubviewNeedsDrawViewHierarchy:newSuperview]; 393 | } 394 | } 395 | 396 | - (void)setIterations:(NSUInteger)iterations 397 | { 398 | _iterationsSet = YES; 399 | _iterations = iterations; 400 | [self setNeedsDisplay]; 401 | } 402 | 403 | - (void)setBlurRadius:(CGFloat)blurRadius 404 | { 405 | _blurRadiusSet = YES; 406 | [self blurLayer].blurRadius = blurRadius; 407 | } 408 | 409 | - (CGFloat)blurRadius 410 | { 411 | return [self blurLayer].blurRadius; 412 | } 413 | 414 | - (void)setBlurEnabled:(BOOL)blurEnabled 415 | { 416 | _blurEnabledSet = YES; 417 | if (_blurEnabled != blurEnabled) 418 | { 419 | _blurEnabled = blurEnabled; 420 | [self schedule]; 421 | if (_blurEnabled) 422 | { 423 | [self setNeedsDisplay]; 424 | } 425 | } 426 | } 427 | 428 | - (void)setDynamic:(BOOL)dynamic 429 | { 430 | _dynamicSet = YES; 431 | if (_dynamic != dynamic) 432 | { 433 | _dynamic = dynamic; 434 | [self schedule]; 435 | if (!dynamic) 436 | { 437 | [self setNeedsDisplay]; 438 | } 439 | } 440 | } 441 | 442 | - (UIView *)underlyingView 443 | { 444 | return _underlyingView ?: self.superview; 445 | } 446 | 447 | - (void)setUnderlyingView:(UIView *)underlyingView 448 | { 449 | _underlyingView = underlyingView; 450 | _needsDrawViewHierarchy = [self viewOrSubviewNeedsDrawViewHierarchy:self.underlyingView]; 451 | [self setNeedsDisplay]; 452 | } 453 | 454 | - (CALayer *)underlyingLayer 455 | { 456 | return self.underlyingView.layer; 457 | } 458 | 459 | - (FXBlurLayer *)blurLayer 460 | { 461 | return (FXBlurLayer *)self.layer; 462 | } 463 | 464 | - (FXBlurLayer *)blurPresentationLayer 465 | { 466 | FXBlurLayer *blurLayer = [self blurLayer]; 467 | return (FXBlurLayer *)blurLayer.presentationLayer ?: blurLayer; 468 | } 469 | 470 | - (void)setUpdateInterval:(NSTimeInterval)updateInterval 471 | { 472 | _updateInterval = updateInterval; 473 | if (_updateInterval <= 0) _updateInterval = 1.0/60; 474 | } 475 | 476 | - (void)setTintColor:(UIColor *)tintColor 477 | { 478 | _tintColor = tintColor; 479 | [self setNeedsDisplay]; 480 | } 481 | 482 | - (void)clearImage { 483 | self.layer.contents = nil; 484 | [self setNeedsDisplay]; 485 | } 486 | 487 | - (void)didMoveToSuperview 488 | { 489 | [super didMoveToSuperview]; 490 | [self.layer setNeedsDisplay]; 491 | } 492 | 493 | - (void)didMoveToWindow 494 | { 495 | [super didMoveToWindow]; 496 | [self schedule]; 497 | } 498 | 499 | - (void)schedule 500 | { 501 | if (self.window && self.dynamic && self.blurEnabled) 502 | { 503 | [[FXBlurScheduler sharedInstance] addView:self]; 504 | } 505 | else 506 | { 507 | [[FXBlurScheduler sharedInstance] removeView:self]; 508 | } 509 | } 510 | 511 | - (void)setNeedsDisplay 512 | { 513 | [super setNeedsDisplay]; 514 | [self.layer setNeedsDisplay]; 515 | } 516 | 517 | - (BOOL)shouldUpdate 518 | { 519 | __strong CALayer *underlyingLayer = [self underlyingLayer]; 520 | 521 | return 522 | underlyingLayer && !underlyingLayer.hidden && 523 | self.blurEnabled && [FXBlurScheduler sharedInstance].blurEnabled && 524 | !CGRectIsEmpty([self.layer.presentationLayer ?: self.layer bounds]) && !CGRectIsEmpty(underlyingLayer.bounds); 525 | } 526 | 527 | - (void)displayLayer:(__unused CALayer *)layer 528 | { 529 | [self updateAsynchronously:NO completion:NULL]; 530 | } 531 | 532 | - (id)actionForLayer:(CALayer *)layer forKey:(NSString *)key 533 | { 534 | if ([key isEqualToString:@"blurRadius"]) 535 | { 536 | //animations are enabled 537 | CAAnimation *action = (CAAnimation *)[super actionForLayer:layer forKey:@"backgroundColor"]; 538 | if ((NSNull *)action != [NSNull null]) 539 | { 540 | CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:key]; 541 | animation.fromValue = [layer.presentationLayer valueForKey:key]; 542 | 543 | //CAMediatiming attributes 544 | animation.beginTime = action.beginTime; 545 | animation.duration = action.duration; 546 | animation.speed = action.speed; 547 | animation.timeOffset = action.timeOffset; 548 | animation.repeatCount = action.repeatCount; 549 | animation.repeatDuration = action.repeatDuration; 550 | animation.autoreverses = action.autoreverses; 551 | animation.fillMode = action.fillMode; 552 | 553 | //CAAnimation attributes 554 | animation.timingFunction = action.timingFunction; 555 | animation.delegate = action.delegate; 556 | 557 | return animation; 558 | } 559 | } 560 | return [super actionForLayer:layer forKey:key]; 561 | } 562 | 563 | - (UIImage *)snapshotOfUnderlyingView 564 | { 565 | __strong FXBlurLayer *blurLayer = [self blurPresentationLayer]; 566 | __strong CALayer *underlyingLayer = [self underlyingLayer]; 567 | CGRect bounds = [blurLayer convertRect:blurLayer.bounds toLayer:underlyingLayer]; 568 | 569 | self.lastUpdate = [NSDate date]; 570 | CGFloat scale = 0.5; 571 | if (self.iterations) 572 | { 573 | CGFloat blockSize = 12.0/self.iterations; 574 | scale = blockSize/MAX(blockSize * 2, blurLayer.blurRadius); 575 | scale = 1.0/floor(1.0/scale); 576 | } 577 | CGSize size = bounds.size; 578 | if (self.contentMode == UIViewContentModeScaleToFill || 579 | self.contentMode == UIViewContentModeScaleAspectFill || 580 | self.contentMode == UIViewContentModeScaleAspectFit || 581 | self.contentMode == UIViewContentModeRedraw) 582 | { 583 | //prevents edge artefacts 584 | size.width = floor(size.width * scale) / scale; 585 | size.height = floor(size.height * scale) / scale; 586 | } 587 | else if ([[UIDevice currentDevice].systemVersion floatValue] < 7.0 && [UIScreen mainScreen].scale == 1.0) 588 | { 589 | //prevents pixelation on old devices 590 | scale = 1.0; 591 | } 592 | UIGraphicsBeginImageContextWithOptions(size, NO, scale); 593 | CGContextRef context = UIGraphicsGetCurrentContext(); 594 | if (context) 595 | { 596 | CGContextTranslateCTM(context, -bounds.origin.x, -bounds.origin.y); 597 | 598 | NSArray *hiddenViews = [self prepareUnderlyingViewForSnapshot]; 599 | if (self.needsDrawViewHierarchy) 600 | { 601 | __strong UIView *underlyingView = self.underlyingView; 602 | [underlyingView drawViewHierarchyInRect:underlyingView.bounds afterScreenUpdates:YES]; 603 | } 604 | else 605 | { 606 | [underlyingLayer renderInContext:context]; 607 | } 608 | [self restoreSuperviewAfterSnapshot:hiddenViews]; 609 | UIImage *snapshot = UIGraphicsGetImageFromCurrentImageContext(); 610 | UIGraphicsEndImageContext(); 611 | return snapshot; 612 | } 613 | return nil; 614 | } 615 | 616 | - (NSArray *)hideEmptyLayers:(CALayer *)layer 617 | { 618 | NSMutableArray *layers = [NSMutableArray array]; 619 | if (CGRectIsEmpty(layer.bounds)) 620 | { 621 | layer.hidden = YES; 622 | [layers addObject:layer]; 623 | } 624 | for (CALayer *sublayer in layer.sublayers) 625 | { 626 | [layers addObjectsFromArray:[self hideEmptyLayers:sublayer]]; 627 | } 628 | return layers; 629 | } 630 | 631 | - (NSArray *)prepareUnderlyingViewForSnapshot 632 | { 633 | __strong CALayer *blurlayer = [self blurLayer]; 634 | __strong CALayer *underlyingLayer = [self underlyingLayer]; 635 | while (blurlayer.superlayer && blurlayer.superlayer != underlyingLayer) 636 | { 637 | blurlayer = blurlayer.superlayer; 638 | } 639 | NSMutableArray *layers = [NSMutableArray array]; 640 | NSUInteger index = [underlyingLayer.sublayers indexOfObject:blurlayer]; 641 | if (index != NSNotFound) 642 | { 643 | for (NSUInteger i = index; i < [underlyingLayer.sublayers count]; i++) 644 | { 645 | CALayer *layer = underlyingLayer.sublayers[i]; 646 | if (!layer.hidden) 647 | { 648 | layer.hidden = YES; 649 | [layers addObject:layer]; 650 | } 651 | } 652 | } 653 | 654 | //also hide any sublayers with empty bounds to prevent a crash on iOS 8 655 | [layers addObjectsFromArray:[self hideEmptyLayers:underlyingLayer]]; 656 | 657 | return layers; 658 | } 659 | 660 | - (void)restoreSuperviewAfterSnapshot:(NSArray *)hiddenLayers 661 | { 662 | for (CALayer *layer in hiddenLayers) 663 | { 664 | layer.hidden = NO; 665 | } 666 | } 667 | 668 | - (UIImage *)blurredSnapshot:(UIImage *)snapshot radius:(CGFloat)blurRadius 669 | { 670 | return [snapshot blurredImageWithRadius:blurRadius 671 | iterations:self.iterations 672 | tintColor:self.tintColor]; 673 | } 674 | 675 | - (void)setLayerContents:(UIImage *)image 676 | { 677 | self.layer.contents = (id)image.CGImage; 678 | self.layer.contentsScale = image.scale; 679 | } 680 | 681 | - (void)updateAsynchronously:(BOOL)async completion:(void (^)())completion 682 | { 683 | if ([self shouldUpdate]) 684 | { 685 | UIImage *snapshot = [self snapshotOfUnderlyingView]; 686 | if (async) 687 | { 688 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 689 | 690 | UIImage *blurredImage = [self blurredSnapshot:snapshot radius:self.blurRadius]; 691 | dispatch_sync(dispatch_get_main_queue(), ^{ 692 | 693 | [self setLayerContents:blurredImage]; 694 | if (completion) completion(); 695 | }); 696 | }); 697 | } 698 | else 699 | { 700 | [self setLayerContents:[self blurredSnapshot:snapshot radius:[self blurPresentationLayer].blurRadius]]; 701 | if (completion) completion(); 702 | } 703 | } 704 | else if (completion) 705 | { 706 | completion(); 707 | } 708 | } 709 | 710 | @end 711 | -------------------------------------------------------------------------------- /TransitionAnimation/HomeViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // HomeViewController.h 3 | // TransitionAnimation 4 | // 5 | // Created by jashion on 16/5/5. 6 | // Copyright © 2016年 BMu. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface HomeViewController : UIViewController 12 | 13 | @property (nonatomic, strong) UITableView *myTable; 14 | 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /TransitionAnimation/HomeViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // HomeViewController.m 3 | // TransitionAnimation 4 | // 5 | // Created by jashion on 16/5/5. 6 | // Copyright © 2016年 BMu. All rights reserved. 7 | // 8 | 9 | #import "HomeViewController.h" 10 | #import "DetailController.h" 11 | #import "MyTableViewCell.h" 12 | #import "ColorUtils.h" 13 | #import "BMAnimateTransition.h" 14 | #import "BMInteractiveTransition.h" 15 | #import "FXBlurView.h" 16 | #import "MenuViewController.h" 17 | 18 | @interface HomeViewController () 19 | 20 | @property (nonatomic, strong) BMAnimateTransition *transition; 21 | @property (nonatomic, strong) BMInteractiveTransition *interactive; 22 | 23 | @end 24 | 25 | @implementation HomeViewController 26 | { 27 | NSArray *items; 28 | MyTableViewCell *selectedCell; 29 | UIView *snapView; 30 | CGRect snapFrame; 31 | } 32 | 33 | - (instancetype)init { 34 | if(self = [super init]) { 35 | items = @[@"Castle", @"Web", @"Sun", @"Chart", @"Signal"]; 36 | self.navigationItem.title = @"Home"; 37 | _transition = [BMAnimateTransition new]; 38 | _interactive = [BMInteractiveTransition new]; 39 | } 40 | return self; 41 | } 42 | 43 | - (void)loadView { 44 | [super loadView]; 45 | 46 | self.myTable = [[UITableView alloc] initWithFrame: [UIScreen mainScreen].bounds style: UITableViewStylePlain]; 47 | self.myTable.dataSource = self; 48 | self.myTable.delegate = self; 49 | self.myTable.separatorStyle = UITableViewCellSeparatorStyleNone; 50 | [self.myTable registerClass: [MyTableViewCell class] forCellReuseIdentifier: NSStringFromClass([MyTableViewCell class])]; 51 | [self.view addSubview: self.myTable]; 52 | } 53 | 54 | - (void)viewDidLoad { 55 | [super viewDidLoad]; 56 | 57 | self.navigationController.delegate = self; 58 | 59 | UIButton *leftButton = [UIButton buttonWithType: UIButtonTypeCustom]; 60 | leftButton.frame = CGRectMake(0, 0, 40, 44); 61 | [leftButton setImage: [UIImage imageNamed:@"HomeMenu"] forState: UIControlStateNormal]; 62 | [leftButton addTarget: self action: @selector(showMenuController) forControlEvents: UIControlEventTouchUpInside]; 63 | 64 | UIBarButtonItem *spaceItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem: UIBarButtonSystemItemFixedSpace target: nil action: nil]; 65 | spaceItem.width = - 8; 66 | UIBarButtonItem *leftItem = [[UIBarButtonItem alloc] initWithCustomView: leftButton]; 67 | 68 | self.navigationItem.leftBarButtonItems = @[spaceItem, leftItem]; 69 | } 70 | 71 | #pragma mark - UITableViewDataSource 72 | 73 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 74 | return items.count; 75 | } 76 | 77 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 78 | MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: NSStringFromClass([MyTableViewCell class])]; 79 | [cell setCellImage: [UIImage imageNamed: items[indexPath.row]]]; 80 | return cell; 81 | } 82 | 83 | #pragma mark - UITableViewDelegate 84 | 85 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 86 | return CGRectGetWidth(self.view.frame) * 3 /4; 87 | } 88 | 89 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 90 | selectedCell = [tableView cellForRowAtIndexPath: indexPath]; 91 | snapView = [selectedCell snapshotViewAfterScreenUpdates: NO]; 92 | snapFrame = [selectedCell convertRect: selectedCell.contentView.frame toView: self.view]; 93 | DetailController *detail = [[DetailController alloc] initWithTitle: items[indexPath.row] image: [UIImage imageNamed: items[indexPath.row]]]; 94 | [self.interactive wireToViewController: detail operation: BMInteractiveTransitionSnapViewTransform]; 95 | [self.navigationController pushViewController: detail animated: YES]; 96 | } 97 | 98 | #pragma mark - UINavigationControllerDelegate 99 | 100 | - (nullable id )navigationController:(UINavigationController *)navigationController 101 | animationControllerForOperation:(UINavigationControllerOperation)operation 102 | fromViewController:(UIViewController *)fromVC 103 | toViewController:(UIViewController *)toVC { 104 | 105 | if (operation == UINavigationControllerOperationPush) { 106 | DetailController *detail = (DetailController *)toVC; 107 | self.transition.operation = BMAnimateTransitionSnapViewTransformPush; 108 | self.transition.duration = 0.6; 109 | self.transition.snapView = snapView; 110 | self.transition.initalView = selectedCell; 111 | self.transition.initalFrame = snapFrame; 112 | self.transition.finalView = detail.topImageView; 113 | self.transition.finalFrame = CGRectMake(0, 64, snapFrame.size.width, snapFrame.size.height); 114 | return self.transition; 115 | } else if (operation == UINavigationControllerOperationPop) { 116 | DetailController *detail = (DetailController *)fromVC; 117 | self.transition.operation = BMAnimateTransitionSnapViewTransformPop; 118 | self.transition.duration = 0.6; 119 | self.transition.snapView = [detail.topImageView snapshotViewAfterScreenUpdates: NO]; 120 | self.transition.initalView = detail.topImageView; 121 | self.transition.initalFrame = [detail.topImageView convertRect: detail.topImageView.bounds toView: detail.view]; 122 | self.transition.finalView = selectedCell; 123 | self.transition.finalFrame = snapFrame; 124 | return self.transition; 125 | } else { 126 | return nil; 127 | } 128 | } 129 | 130 | - (nullable id )navigationController:(UINavigationController *)navigationController 131 | interactionControllerForAnimationController:(id ) animationController { 132 | 133 | 134 | return self.interactive.interacting ? self.interactive : nil; 135 | } 136 | 137 | #pragma mark - UIViewControllerTransitioningDelegate 138 | 139 | - (nullable id )animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source { 140 | self.transition.operation = BMAnimateTransitionPresentFadeIn; 141 | self.transition.duration = 0.4; 142 | return self.transition; 143 | } 144 | 145 | - (nullable id )animationControllerForDismissedController:(UIViewController *)dismissed { 146 | self.transition.operation = BMAnimateTransitionPresentFadeOut; 147 | self.transition.duration = 0.4; 148 | return self.transition; 149 | } 150 | 151 | #pragma mark - HandleDismissMenuVC 152 | 153 | - (void)dismissWithMenuVC:(MenuViewController *)menuVC { 154 | [menuVC dismissViewControllerAnimated: YES completion: nil]; 155 | } 156 | 157 | #pragma mark - Event Respose 158 | 159 | - (void)showMenuController { 160 | UIGraphicsBeginImageContextWithOptions([UIScreen mainScreen].bounds.size, NO, [UIScreen mainScreen].scale); 161 | [[UIApplication sharedApplication].keyWindow drawViewHierarchyInRect: [UIScreen mainScreen].bounds afterScreenUpdates: YES]; 162 | UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 163 | UIGraphicsEndImageContext(); 164 | 165 | MenuViewController *menuVC = [[MenuViewController alloc] initWithBackgroundImage: [image blurredImageWithRadius: 10 iterations: 20 tintColor: [UIColor blackColor]]]; 166 | menuVC.delegate = self; 167 | menuVC.transitioningDelegate = self; 168 | [self presentViewController: menuVC animated: YES completion: nil]; 169 | } 170 | 171 | @end 172 | -------------------------------------------------------------------------------- /TransitionAnimation/MenuViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MenuViewController.h 3 | // TransitionAnimation 4 | // 5 | // Created by jashion on 16/5/25. 6 | // Copyright © 2016年 BMu. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class MenuViewController; 12 | 13 | @protocol HandleDismissMenuVC 14 | 15 | - (void)dismissWithMenuVC: (MenuViewController *)menuVC; 16 | 17 | @end 18 | 19 | @interface MenuViewController : UIViewController 20 | 21 | @property (nonatomic, weak) id delegate; 22 | 23 | - (instancetype)initWithBackgroundImage: (UIImage *)backgroundImage; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /TransitionAnimation/MenuViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // MenuViewController.m 3 | // TransitionAnimation 4 | // 5 | // Created by jashion on 16/5/25. 6 | // Copyright © 2016年 BMu. All rights reserved. 7 | // 8 | 9 | #import "MenuViewController.h" 10 | 11 | @interface MenuViewController () 12 | 13 | @property (nonatomic, strong) UIImage *backgroundImage; 14 | 15 | @end 16 | 17 | @implementation MenuViewController 18 | { 19 | NSArray *titles; 20 | NSMutableArray *titleLabels; 21 | UIButton *deleteButton; 22 | } 23 | 24 | - (instancetype)initWithBackgroundImage: (UIImage *)backgroundImage { 25 | if (self = [super init]) { 26 | _backgroundImage = backgroundImage; 27 | titles = @[@"Popular", @"Debuts", @"Playoffs", @"Animated", @"Rebounds", @"Sign in"]; 28 | } 29 | return self; 30 | } 31 | 32 | - (void)viewDidLoad { 33 | [super viewDidLoad]; 34 | 35 | self.view.backgroundColor = [UIColor colorWithPatternImage: _backgroundImage]; 36 | } 37 | 38 | - (void)viewWillAppear:(BOOL)animated { 39 | [super viewWillAppear: animated]; 40 | 41 | if (titleLabels && titleLabels.count > 0) { 42 | return; 43 | } 44 | 45 | deleteButton = [UIButton buttonWithType: UIButtonTypeCustom]; 46 | deleteButton.frame = CGRectMake(20, 30, 23, 23); 47 | deleteButton.contentMode = UIViewContentModeScaleAspectFill; 48 | deleteButton.clipsToBounds = YES; 49 | // deleteButton.transform = CGAffineTransformMakeScale(0, 0); 50 | [deleteButton setImage: [UIImage imageNamed:@"DeleteButtonIcon"] forState: UIControlStateNormal]; 51 | [deleteButton addTarget: self action: @selector(back) forControlEvents: UIControlEventTouchUpInside]; 52 | [self.view addSubview: deleteButton]; 53 | 54 | // [UIView animateWithDuration: 0.6 delay: 0 usingSpringWithDamping: 0.5 initialSpringVelocity: 1.0 options: UIViewAnimationOptionCurveEaseInOut animations:^{ 55 | // deleteButton.transform = CGAffineTransformIdentity; 56 | // } completion:^(BOOL finished) { 57 | // 58 | // }]; 59 | // 60 | CGRect rect = self.view.bounds; 61 | titleLabels = @[].mutableCopy; 62 | for (NSInteger index = 0; index < titles.count; index++) { 63 | UILabel *titleLabel = [[UILabel alloc] init]; 64 | titleLabel.bounds = CGRectMake(0, 0, 150, 30); 65 | titleLabel.center = CGPointMake(rect.size.width / 2, 160 + index * 60); 66 | titleLabel.text = titles[index]; 67 | titleLabel.textColor = [UIColor blackColor]; 68 | titleLabel.font = [UIFont systemFontOfSize: 22]; 69 | titleLabel.textAlignment = NSTextAlignmentCenter; 70 | titleLabel.userInteractionEnabled = YES; 71 | titleLabel.transform = CGAffineTransformMakeScale(0, 0); 72 | [self.view addSubview: titleLabel]; 73 | [titleLabels addObject: titleLabel]; 74 | 75 | UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget: self action: @selector(back)]; 76 | [titleLabel addGestureRecognizer: tap]; 77 | 78 | [UIView animateWithDuration: 0.6 delay: index * 0.05 usingSpringWithDamping: 0.5 initialSpringVelocity: 1.0 options: UIViewAnimationOptionCurveEaseInOut animations:^{ 79 | titleLabel.transform = CGAffineTransformIdentity; 80 | } completion:^(BOOL finished) { 81 | 82 | }]; 83 | } 84 | } 85 | 86 | - (void)back { 87 | if (self.delegate && [self.delegate respondsToSelector: @selector(dismissWithMenuVC:)]) { 88 | for (NSInteger index = 0; index < titleLabels.count; index++) { 89 | UILabel *titleLabel = titleLabels[index]; 90 | [UIView animateWithDuration: 0.3 delay: index * 0.1 usingSpringWithDamping: 0.7 initialSpringVelocity: 1.0 options: UIViewAnimationOptionCurveEaseInOut animations:^{ 91 | titleLabel.transform = CGAffineTransformMakeScale(0.1, 0.1); 92 | } completion:^(BOOL finished) { 93 | titleLabel.hidden = YES; 94 | }]; 95 | } 96 | 97 | dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)); 98 | dispatch_after(time, dispatch_get_main_queue(), ^{ 99 | [self.delegate dismissWithMenuVC: self]; 100 | }); 101 | } 102 | } 103 | 104 | @end 105 | -------------------------------------------------------------------------------- /TransitionAnimation/MessageViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MessageViewController.h 3 | // TransitionAnimation 4 | // 5 | // Created by jashion on 16/5/5. 6 | // Copyright © 2016年 BMu. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MessageViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /TransitionAnimation/MessageViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // MessageViewController.m 3 | // TransitionAnimation 4 | // 5 | // Created by jashion on 16/5/5. 6 | // Copyright © 2016年 BMu. All rights reserved. 7 | // 8 | 9 | #import "MessageViewController.h" 10 | 11 | @implementation MessageViewController 12 | 13 | - (void)loadView { 14 | [super loadView]; 15 | 16 | self.view.backgroundColor = [UIColor colorWithRed:0.600 green:1.000 blue:0.600 alpha:1.000]; 17 | } 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /TransitionAnimation/MyTableViewCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // MyTableViewCell.h 3 | // TransitionAnimation 4 | // 5 | // Created by jashion on 16/5/4. 6 | // Copyright © 2016年 BMu. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface MyTableViewCell : UITableViewCell 13 | 14 | - (void)setCellImage:(UIImage *)image; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /TransitionAnimation/MyTableViewCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // MyTableViewCell.m 3 | // TransitionAnimation 4 | // 5 | // Created by jashion on 16/5/4. 6 | // Copyright © 2016年 BMu. All rights reserved. 7 | // 8 | 9 | #import "MyTableViewCell.h" 10 | #import "FXBlurView.h" 11 | 12 | @implementation MyTableViewCell 13 | { 14 | UIImageView *cellImageView; 15 | } 16 | 17 | - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { 18 | if (self = [super initWithStyle: style reuseIdentifier: reuseIdentifier]) { 19 | self.selectionStyle = UITableViewCellSelectionStyleNone; 20 | [self buildView]; 21 | } 22 | return self; 23 | } 24 | 25 | - (void)buildView { 26 | cellImageView = [[UIImageView alloc] initWithFrame: CGRectMake(0, 0, CGRectGetWidth([UIScreen mainScreen].bounds), CGRectGetWidth([UIScreen mainScreen].bounds) * 3 /4)]; 27 | UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget: self action: @selector(handleLongPressGesture:)]; 28 | [cellImageView addGestureRecognizer: longPress]; 29 | cellImageView.userInteractionEnabled = YES; 30 | [self.contentView addSubview: cellImageView]; 31 | } 32 | 33 | - (void)setCellImage:(UIImage *)image { 34 | cellImageView.image = image; 35 | } 36 | 37 | - (void)handleLongPressGesture: (UILongPressGestureRecognizer *)longPress { 38 | switch (longPress.state) { 39 | case UIGestureRecognizerStateBegan: 40 | { 41 | cellImageView.transform = CGAffineTransformMakeScale(0.9, 0.9); 42 | cellImageView.image = [cellImageView.image blurredImageWithRadius: 5 iterations: 10 tintColor: [UIColor blackColor]]; 43 | break; 44 | } 45 | 46 | case UIGestureRecognizerStateChanged: 47 | { 48 | break; 49 | } 50 | 51 | case UIGestureRecognizerStateCancelled: 52 | case UIGestureRecognizerStateEnded: 53 | { 54 | cellImageView.transform = CGAffineTransformIdentity; 55 | break; 56 | } 57 | 58 | default: 59 | break; 60 | } 61 | } 62 | 63 | @end 64 | -------------------------------------------------------------------------------- /TransitionAnimation/PersonProfileViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // PersonProfileViewController.h 3 | // TransitionAnimation 4 | // 5 | // Created by jashion on 16/5/8. 6 | // Copyright © 2016年 BMu. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface PersonProfileViewController : UIViewController 12 | 13 | - (instancetype)initWithName: (NSString *)name title: (NSString *)title image: (UIImage *)image; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /TransitionAnimation/PersonProfileViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // PersonProfileViewController.m 3 | // TransitionAnimation 4 | // 5 | // Created by jashion on 16/5/8. 6 | // Copyright © 2016年 BMu. All rights reserved. 7 | // 8 | 9 | #import "PersonProfileViewController.h" 10 | #import "PhotoCircleController.h" 11 | #import "MyTableViewCell.h" 12 | #import "ColorUtils.h" 13 | #import "FXBlurView.h" 14 | 15 | #define kScreenWidth CGRectGetWidth([UIScreen mainScreen].bounds) 16 | #define topImageViewHeight kScreenWidth * 3 / 4 17 | #define topHeight (topImageViewHeight - 96) 18 | 19 | @interface PersonProfileViewController () 20 | 21 | @end 22 | 23 | @implementation PersonProfileViewController 24 | { 25 | NSString *personName; 26 | NSString *personTitle; 27 | UIImage *personImage; 28 | UITableView *personTableView; 29 | NSArray *photos; 30 | UIView *topImageContainer; 31 | UIImageView *topImageView; 32 | UIImageView *effectView; 33 | UIView *desContentView; 34 | } 35 | 36 | - (instancetype)initWithName: (NSString *)name title: (NSString *)title image: (UIImage *)image{ 37 | if (self = [super init]) { 38 | personName = name; 39 | personTitle = title; 40 | personImage = image; 41 | self.navigationItem.title = name; 42 | photos = @[@"Castle", @"PeaceMidNight", @"Signal", @"Web", @"Sun", @"Chart", @"Animal"]; 43 | } 44 | return self; 45 | } 46 | 47 | - (void)loadView { 48 | [super loadView]; 49 | 50 | self.view.backgroundColor = [UIColor colorWithWhite: 0.8 alpha: 1]; 51 | 52 | UIButton *backButton = [UIButton buttonWithType: UIButtonTypeSystem]; 53 | backButton.frame = CGRectMake(0, 0, 40, 44); 54 | [backButton setImage: [UIImage imageNamed:@"BackIcon"] forState: UIControlStateNormal]; 55 | [backButton setImageEdgeInsets: UIEdgeInsetsMake(0, - 30, 0, 0)]; 56 | [backButton addTarget: self action: @selector(back) forControlEvents: UIControlEventTouchUpInside]; 57 | self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView: backButton]; 58 | 59 | personTableView = [[UITableView alloc] initWithFrame: [UIScreen mainScreen].bounds style: UITableViewStyleGrouped]; 60 | personTableView.dataSource = self; 61 | personTableView.delegate = self; 62 | [personTableView registerClass: [MyTableViewCell class] forCellReuseIdentifier: NSStringFromClass([MyTableViewCell class])]; 63 | personTableView.separatorStyle = UITableViewCellSeparatorStyleNone; 64 | personTableView.contentInset = UIEdgeInsetsMake(topHeight, 0, 0, 0); 65 | [self.view addSubview: personTableView]; 66 | 67 | topImageContainer = [[UIView alloc] initWithFrame: CGRectMake(0, - topHeight, kScreenWidth, topHeight)]; 68 | topImageContainer.clipsToBounds = YES; 69 | [personTableView addSubview: topImageContainer]; 70 | 71 | topImageView = [[UIImageView alloc] initWithImage: personImage]; 72 | topImageView.frame = CGRectMake(0, - 64, kScreenWidth, topImageViewHeight); 73 | [topImageContainer addSubview: topImageView]; 74 | 75 | effectView = [[UIImageView alloc] initWithImage: [personImage blurredImageWithRadius: 5 iterations: 10 tintColor: [UIColor blackColor]]]; 76 | effectView.frame = CGRectMake(0, 0, kScreenWidth, topImageViewHeight); 77 | [topImageView addSubview: effectView]; 78 | 79 | desContentView = [[UIView alloc] initWithFrame: topImageContainer.frame]; 80 | [personTableView addSubview: desContentView]; 81 | 82 | UILabel *title = [[UILabel alloc] init]; 83 | title.font = [UIFont systemFontOfSize: 32]; 84 | title.textColor = [UIColor whiteColor]; 85 | title.textAlignment = NSTextAlignmentCenter; 86 | title.text = personTitle; 87 | title.frame = CGRectMake(0, 20, kScreenWidth, 50); 88 | [desContentView addSubview: title]; 89 | 90 | UILabel *author = [[UILabel alloc] init]; 91 | author.font = [UIFont systemFontOfSize: 16]; 92 | author.textColor = [UIColor whiteColor]; 93 | author.textAlignment = NSTextAlignmentCenter; 94 | author.text = personName; 95 | author.frame = CGRectMake(0, 70, kScreenWidth, 30); 96 | [desContentView addSubview: author]; 97 | 98 | UILabel *follow = [[UILabel alloc] init]; 99 | follow.frame = CGRectMake((kScreenWidth - 130) / 2, 110, 130, 30); 100 | follow.font = [UIFont boldSystemFontOfSize: 14]; 101 | follow.textColor = [UIColor whiteColor]; 102 | follow.layer.cornerRadius = 15; 103 | follow.layer.borderColor = [UIColor whiteColor].CGColor; 104 | follow.layer.borderWidth = 2; 105 | follow.textAlignment = NSTextAlignmentCenter; 106 | follow.text = @"Follow"; 107 | [desContentView addSubview: follow]; 108 | 109 | UIImageView *left = [[UIImageView alloc] initWithImage: [UIImage imageNamed:@"PersooLeft"]]; 110 | left.frame = CGRectMake(80, 110, 30, 30); 111 | [desContentView addSubview: left]; 112 | 113 | UIImageView *right = [[UIImageView alloc] initWithImage: [UIImage imageNamed:@"PersonRight"]]; 114 | right.frame = CGRectMake(kScreenWidth - 110, 110, 30, 30); 115 | [desContentView addSubview: right]; 116 | } 117 | 118 | #pragma mark - UITableViewDataSource 119 | 120 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 121 | return photos.count; 122 | } 123 | 124 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 125 | MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: NSStringFromClass([MyTableViewCell class])]; 126 | [cell setCellImage: [UIImage imageNamed: photos[indexPath.row]]]; 127 | return cell; 128 | } 129 | 130 | #pragma mark - UITableViewDelegate 131 | 132 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 133 | return topImageViewHeight; 134 | } 135 | 136 | - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { 137 | return 120; 138 | } 139 | 140 | - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { 141 | return 0.1; 142 | } 143 | 144 | - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { 145 | UIView *buttonsContainer = [[UIView alloc] initWithFrame: CGRectMake(0, 0, kScreenWidth, 120)]; 146 | buttonsContainer.backgroundColor = [UIColor colorWithWhite: 0.8 alpha: 1]; 147 | CGFloat buttonWidth = (kScreenWidth - 0.5) / 2; 148 | CGFloat buttonHeight = (120 - 0.5) / 2; 149 | UIButton *followerButton = [self createButtonWithTopTitle: @"7785" topTitleColor: [UIColor blackColor] bottomTitle: @"Followers" bottomTitleColor: [ColorUtils mainColor] buttonBgColor: [UIColor whiteColor] frame: CGRectMake(0, 0, buttonWidth, buttonHeight)]; 150 | followerButton.tag = 0; 151 | UIButton *followingButton = [self createButtonWithTopTitle: @"652" topTitleColor: [UIColor blackColor] bottomTitle: @"Following" bottomTitleColor: [ColorUtils mainColor] buttonBgColor: [UIColor whiteColor] frame: CGRectMake(buttonWidth + 0.5, 0, buttonWidth, buttonHeight)]; 152 | followingButton.tag = 1; 153 | UIButton *shotsButton = [self createButtonWithTopTitle: @"Shots" topTitleColor: [UIColor whiteColor] bottomTitle: @"122" bottomTitleColor: [UIColor whiteColor] buttonBgColor: [ColorUtils mainColor] frame: CGRectMake(0, buttonHeight + 0.5, buttonWidth, buttonHeight)]; 154 | shotsButton.tag = 2; 155 | UIButton *likesButton = [self createButtonWithTopTitle: @"Likes" topTitleColor: [UIColor whiteColor] bottomTitle: @"1253" bottomTitleColor: [UIColor whiteColor] buttonBgColor: [ColorUtils mainColor] frame: CGRectMake(buttonWidth + 0.5, buttonHeight + 0.5, buttonWidth, buttonHeight)]; 156 | likesButton.tag = 3; 157 | [buttonsContainer addSubview: followerButton]; 158 | [buttonsContainer addSubview: followingButton]; 159 | [buttonsContainer addSubview: shotsButton]; 160 | [buttonsContainer addSubview: likesButton]; 161 | 162 | UIImageView *avatarImageView = [[UIImageView alloc] initWithImage: [UIImage imageNamed: personName]]; 163 | avatarImageView.bounds = CGRectMake(0, 0, 64, 64); 164 | avatarImageView.center = CGPointMake(kScreenWidth / 2, 0); 165 | avatarImageView.backgroundColor = [UIColor whiteColor]; 166 | avatarImageView.layer.cornerRadius = 32; 167 | avatarImageView.layer.masksToBounds = YES; 168 | avatarImageView.layer.borderColor = [UIColor whiteColor].CGColor; 169 | avatarImageView.layer.borderWidth = 3; 170 | [buttonsContainer addSubview: avatarImageView]; 171 | return buttonsContainer; 172 | } 173 | 174 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 175 | PhotoCircleController *photoCircleController = [[PhotoCircleController alloc] initWithImages: photos currentImageIndex: indexPath.row]; 176 | photoCircleController.delegate = self; 177 | photoCircleController.transitioningDelegate = self; 178 | photoCircleController.modalTransitionStyle = UIModalTransitionStyleCoverVertical; 179 | [self presentViewController: photoCircleController animated: YES completion: nil]; 180 | } 181 | 182 | #pragma mark - handleDismissControllerDelegate 183 | 184 | - (void)dismissController:(PhotoCircleController *)controller { 185 | [controller dismissViewControllerAnimated: YES completion: nil]; 186 | } 187 | 188 | #pragma mark - UIViewControllerTransitioningDelegate 189 | 190 | - (nullable id )animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source { 191 | return nil; 192 | } 193 | 194 | #pragma mark - UIScrollViewDelegate 195 | 196 | - (void)scrollViewDidScroll:(UIScrollView *)scrollView { 197 | CGFloat offset = scrollView.contentOffset.y + topHeight + 64; 198 | if (offset <= 0 && offset >= - 96) { 199 | topImageContainer.frame = CGRectMake(0, - topHeight + offset, kScreenWidth, topHeight - offset); 200 | topImageView.frame = CGRectMake(0, - 64 - offset * 2 / 3, kScreenWidth, topImageViewHeight); 201 | desContentView.alpha = 1 + offset / 96; 202 | effectView.alpha = 1 + offset / 96; 203 | } else if(offset < - 96){ 204 | CGFloat offsetY = - offset - 96; 205 | topImageContainer.bounds = CGRectMake(0, 0, kScreenWidth + offsetY, topImageViewHeight + offsetY); 206 | topImageContainer.center = CGPointMake(kScreenWidth / 2, - topImageContainer.bounds.size.height / 2); 207 | topImageView.frame = CGRectMake(0, 0, topImageContainer.bounds.size.width, topImageContainer.bounds.size.height); 208 | desContentView.alpha = 0; 209 | effectView.alpha = 0; 210 | } else { 211 | desContentView.alpha = offset > 90 ? 0 : 1 - offset / 90; 212 | [UIView animateWithDuration: 0.1 animations:^{ 213 | topImageContainer.frame = CGRectMake(0, - topHeight, kScreenWidth, topHeight); 214 | topImageView.frame = CGRectMake(0, - 64, kScreenWidth, topImageViewHeight); 215 | effectView.alpha = 1; 216 | }]; 217 | } 218 | effectView.frame = topImageView.bounds; 219 | desContentView.center = CGPointMake(kScreenWidth / 2, - topHeight / 2 + offset); 220 | } 221 | 222 | #pragma mark - Event Response 223 | 224 | - (void)back { 225 | [self.navigationController popViewControllerAnimated: YES]; 226 | } 227 | 228 | #pragma mark - Private Method 229 | 230 | - (UIButton *)createButtonWithTopTitle: (NSString *)topTitle topTitleColor: (UIColor *)topTitleColor bottomTitle: (NSString *)bottomTitle bottomTitleColor: (UIColor *)bottomTitleColor buttonBgColor: (UIColor *)bgColor frame: (CGRect)frame { 231 | UIButton *button = [UIButton buttonWithType: UIButtonTypeCustom]; 232 | button.frame = frame; 233 | button.backgroundColor = bgColor; 234 | button.titleLabel.font = [UIFont boldSystemFontOfSize: 16]; 235 | button.titleEdgeInsets = UIEdgeInsetsMake(26, 0, 0, 0); 236 | [button setTitle: bottomTitle forState: UIControlStateNormal]; 237 | [button setTitleColor: bottomTitleColor forState: UIControlStateNormal]; 238 | [button addTarget: self action: @selector(buttonBgColorChange:) forControlEvents: UIControlEventTouchDown]; 239 | [button addTarget: self action: @selector(buttonBgColorReset:) forControlEvents: UIControlEventTouchDragOutside]; 240 | [button addTarget: self action: @selector(buttonClick:) forControlEvents: UIControlEventTouchUpInside]; 241 | UILabel *topLabel = [[UILabel alloc] init]; 242 | topLabel.textAlignment = NSTextAlignmentCenter; 243 | topLabel.bounds = CGRectMake(0, 0, frame.size.width, frame.size.height / 2); 244 | topLabel.center = CGPointMake(frame.size.width / 2, frame.size.height / 4); 245 | topLabel.font = [UIFont systemFontOfSize: 18]; 246 | topLabel.textColor = topTitleColor; 247 | topLabel.text = topTitle; 248 | [button addSubview: topLabel]; 249 | return button; 250 | } 251 | 252 | - (void)buttonBgColorChange: (id)sender { 253 | UIButton *button = (UIButton *)sender; 254 | button.backgroundColor = [UIColor colorWithWhite:0.800 alpha:1.000]; 255 | } 256 | 257 | - (void)buttonBgColorReset: (id)sender { 258 | UIButton *button = (UIButton *)sender; 259 | if (button.tag / 2 == 0) { 260 | button.backgroundColor = [UIColor whiteColor]; 261 | } else { 262 | button.backgroundColor = [ColorUtils mainColor]; 263 | } 264 | } 265 | 266 | - (void)buttonClick: (id)sender { 267 | UIButton *button = (UIButton *)sender; 268 | if (button.tag / 2 == 0) { 269 | button.backgroundColor = [UIColor whiteColor]; 270 | } else { 271 | button.backgroundColor = [ColorUtils mainColor]; 272 | } 273 | UIAlertController *alert = [UIAlertController alertControllerWithTitle: nil message: button.titleLabel.text preferredStyle: UIAlertControllerStyleAlert]; 274 | UIAlertAction *action = [UIAlertAction actionWithTitle: @"cancel" style: UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { 275 | [alert dismissViewControllerAnimated: YES completion: nil]; 276 | }]; 277 | [alert addAction: action]; 278 | [self presentViewController: alert animated: YES completion: nil]; 279 | } 280 | 281 | @end 282 | -------------------------------------------------------------------------------- /TransitionAnimation/PhotoCircleController.h: -------------------------------------------------------------------------------- 1 | // 2 | // PhotoCircleController.h 3 | // TransitionAnimation 4 | // 5 | // Created by jashion on 16/5/9. 6 | // Copyright © 2016年 BMu. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class PhotoCircleController; 12 | 13 | @protocol handleDismissControllerDelegate 14 | 15 | - (void)dismissController: (PhotoCircleController *)controller; 16 | 17 | @end 18 | 19 | @interface PhotoCircleController : UIViewController 20 | 21 | @property (nonatomic, weak) id delegate; 22 | 23 | - (instancetype)initWithImages: (NSArray *)images currentImageIndex: (NSInteger)index; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /TransitionAnimation/PhotoCircleController.m: -------------------------------------------------------------------------------- 1 | // 2 | // PhotoCircleController.m 3 | // TransitionAnimation 4 | // 5 | // Created by jashion on 16/5/9. 6 | // Copyright © 2016年 BMu. All rights reserved. 7 | // 8 | 9 | #import "PhotoCircleController.h" 10 | #import "FXBlurView.h" 11 | #import "ColorUtils.h" 12 | #import "UIImage+Tint.h" 13 | 14 | #define kScreenWidth CGRectGetWidth([UIScreen mainScreen].bounds) 15 | #define kScreenHeight CGRectGetHeight([UIScreen mainScreen].bounds) 16 | #define photoContentViewHeight (kScreenHeight - 260) 17 | #define photoContentViewWidth (kScreenWidth - 100) 18 | #define angle (M_PI_2 / 9) 19 | #define changeHeight 80 20 | #define frontCenter CGPointMake(kScreenWidth / 2, kScreenHeight / 2 + changeHeight) 21 | #define currentCenter CGPointMake(kScreenWidth * 3 / 2, kScreenHeight / 2) 22 | #define nextCenter CGPointMake(kScreenWidth * 5 / 2, kScreenHeight / 2 + changeHeight) 23 | 24 | @interface PhotoCircleController () 25 | 26 | @end 27 | 28 | @implementation PhotoCircleController 29 | { 30 | NSArray *imagesArray; 31 | NSInteger currentImageIndex; 32 | UIImageView *backgroundImageView; 33 | UIScrollView *myScrollView; 34 | UIButton *cancelButton; 35 | UIView *frontContentView; 36 | UIView *currentContentView; 37 | UIView *nextContentView; 38 | UIImageView *frontImageView; 39 | UIImageView *currentImageView; 40 | UIImageView *nextImageView; 41 | } 42 | 43 | - (instancetype)initWithImages: (NSArray *)images currentImageIndex: (NSInteger)index { 44 | if (self = [super init]) { 45 | imagesArray = images; 46 | currentImageIndex = index; 47 | } 48 | return self; 49 | } 50 | 51 | - (void)loadView { 52 | [super loadView]; 53 | 54 | UIImage *image = [UIImage imageNamed: imagesArray[currentImageIndex]]; 55 | image = [image blurredImageWithRadius: 5 iterations: 10 tintColor: [UIColor blackColor]]; 56 | backgroundImageView = [[UIImageView alloc] initWithImage: image]; 57 | backgroundImageView.frame = [UIScreen mainScreen].bounds; 58 | backgroundImageView.contentMode = UIViewContentModeScaleAspectFill; 59 | backgroundImageView.backgroundColor = [UIColor blackColor]; 60 | [self.view addSubview: backgroundImageView]; 61 | 62 | myScrollView = [[UIScrollView alloc] initWithFrame: [UIScreen mainScreen].bounds]; 63 | myScrollView.scrollEnabled = YES; 64 | myScrollView.contentSize = CGSizeMake(kScreenWidth * 3, 0); 65 | myScrollView.contentOffset = CGPointMake(kScreenWidth, 0); 66 | myScrollView.delegate = self; 67 | myScrollView.showsHorizontalScrollIndicator = NO; 68 | myScrollView.showsVerticalScrollIndicator = NO; 69 | myScrollView.pagingEnabled = YES; 70 | [self.view addSubview: myScrollView]; 71 | 72 | cancelButton = [UIButton buttonWithType: UIButtonTypeCustom]; 73 | cancelButton.bounds = CGRectMake(0, 0, 36, 36); 74 | cancelButton.center = CGPointMake(self.view.frame.size.width / 2, self.view.frame.size.height - 60); 75 | cancelButton.backgroundColor = [UIColor blackColor]; 76 | cancelButton.layer.cornerRadius = 18; 77 | cancelButton.layer.masksToBounds = YES; 78 | cancelButton.contentMode = UIViewContentModeScaleAspectFit; 79 | cancelButton.alpha = 0; 80 | cancelButton.transform = CGAffineTransformMakeScale(0.1, 0.1); 81 | [cancelButton setImage: [UIImage imageNamed:@"DeleteIcon"] forState: UIControlStateNormal]; 82 | [cancelButton addTarget: self action: @selector(back) forControlEvents: UIControlEventTouchUpInside]; 83 | [self.view addSubview: cancelButton]; 84 | 85 | UIBezierPath *path = [self createBezierPath]; 86 | 87 | CAShapeLayer *frontMaskLayer = [self createMaskLayerWithPath: path.CGPath]; 88 | CAShapeLayer *currentMaskLayer = [self createMaskLayerWithPath: path.CGPath]; 89 | CAShapeLayer *nextMaskLayer = [self createMaskLayerWithPath: path.CGPath]; 90 | 91 | frontContentView = [self buildPhotoViewWithCenter: frontCenter maskLayer: frontMaskLayer]; 92 | frontContentView.transform = CGAffineTransformRotate(CGAffineTransformIdentity, - angle); 93 | [myScrollView addSubview: frontContentView]; 94 | currentContentView = [self buildPhotoViewWithCenter: currentCenter maskLayer: currentMaskLayer]; 95 | [myScrollView addSubview: currentContentView]; 96 | nextContentView = [self buildPhotoViewWithCenter: nextCenter maskLayer: nextMaskLayer]; 97 | nextContentView.transform = CGAffineTransformRotate(CGAffineTransformIdentity, angle); 98 | [myScrollView addSubview: nextContentView]; 99 | 100 | frontImageView = [self buildImageView]; 101 | frontImageView.image = [self frontImageWithIndex: currentImageIndex]; 102 | [frontContentView addSubview: frontImageView]; 103 | currentImageView = [self buildImageView]; 104 | currentImageView.image = [self currentImageWithIndex: currentImageIndex]; 105 | [currentContentView addSubview: currentImageView]; 106 | nextImageView = [self buildImageView]; 107 | nextImageView.image = [self nextImageWithIndex: currentImageIndex]; 108 | [nextContentView addSubview: nextImageView]; 109 | } 110 | 111 | - (void)viewDidAppear:(BOOL)animated { 112 | [super viewDidAppear: animated]; 113 | 114 | [UIView animateWithDuration: 0.6 delay: 0.0 usingSpringWithDamping: 0.6 initialSpringVelocity: 1.f options: UIViewAnimationOptionCurveEaseIn animations:^{ 115 | cancelButton.alpha = 1; 116 | cancelButton.transform = CGAffineTransformIdentity; 117 | } completion:^(BOOL finished) { 118 | 119 | }]; 120 | } 121 | 122 | #pragma mark - UIScrollViewDelegate 123 | 124 | - (void)scrollViewDidScroll:(UIScrollView *)scrollView { 125 | CGFloat offsetX = scrollView.contentOffset.x; 126 | 127 | if (offsetX >= 0 && offsetX <= kScreenWidth) { 128 | CGFloat percent = 1 - offsetX / kScreenWidth; //offsetX = 0 ,percent = 1; offsetX = kScreenWidth ,percent = 0. 129 | frontContentView.transform = CGAffineTransformRotate(CGAffineTransformIdentity, (percent - 1 ) * angle); 130 | frontContentView.center = CGPointMake(kScreenWidth / 2, kScreenHeight / 2 + (1 - percent) * changeHeight); 131 | currentContentView.transform = CGAffineTransformMakeRotation(percent * angle); 132 | currentContentView.center = CGPointMake(kScreenWidth * 3 / 2, kScreenHeight / 2 + percent * changeHeight); 133 | } else if (offsetX > kScreenWidth && offsetX <= kScreenWidth * 2) { 134 | CGFloat percent = (offsetX - kScreenWidth) / kScreenWidth; //offsetX = kScreenWidth,percent = 0; offsetX = kScreenWidth * 2,percent = 1. 135 | nextContentView.transform = CGAffineTransformRotate(CGAffineTransformIdentity, (1 - percent) * angle); 136 | nextContentView.center = CGPointMake(kScreenWidth * 5 / 2, kScreenHeight / 2 + (1- percent) * changeHeight); 137 | currentContentView.transform = CGAffineTransformMakeRotation(- percent * angle); 138 | currentContentView.center = CGPointMake(kScreenWidth * 3 / 2, kScreenHeight / 2 + percent * changeHeight); 139 | } 140 | 141 | if (offsetX <= 0) { 142 | currentImageIndex = currentImageIndex == 0 ? imagesArray.count - 1: currentImageIndex - 1; 143 | frontImageView.image = [self frontImageWithIndex: currentImageIndex]; 144 | currentImageView.image = [self currentImageWithIndex: currentImageIndex]; 145 | nextImageView.image = [self nextImageWithIndex: currentImageIndex]; 146 | [myScrollView setContentOffset: CGPointMake(kScreenWidth, 0)]; 147 | } else if (offsetX >= kScreenWidth * 2) { 148 | currentImageIndex = currentImageIndex == (imagesArray.count - 1) ? 0: currentImageIndex + 1; 149 | frontImageView.image = [self frontImageWithIndex: currentImageIndex]; 150 | currentImageView.image = [self currentImageWithIndex: currentImageIndex]; 151 | nextImageView.image = [self nextImageWithIndex: currentImageIndex]; 152 | [myScrollView setContentOffset: CGPointMake(kScreenWidth, 0)]; 153 | } 154 | 155 | backgroundImageView.image = [[UIImage imageNamed: imagesArray[currentImageIndex]] blurredImageWithRadius: 5 iterations: 10 tintColor: [UIColor blackColor]]; 156 | } 157 | 158 | #pragma mark - Event Response 159 | 160 | - (void)back { 161 | if (self.delegate && [self.delegate respondsToSelector: @selector(dismissController:)]) { 162 | [self.delegate dismissController: self]; 163 | } 164 | } 165 | 166 | #pragma mark - Private Method 167 | 168 | - (UIView *)buildPhotoViewWithCenter: (CGPoint)center maskLayer: (CAShapeLayer *)maskLayer { 169 | UIView *photoView = [[UIView alloc] init]; 170 | photoView.bounds = CGRectMake(0, 0, photoContentViewWidth, photoContentViewHeight); 171 | photoView.backgroundColor = [UIColor whiteColor]; 172 | photoView.center = center; 173 | photoView.layer.mask = maskLayer; 174 | photoView.layer.cornerRadius = 80; 175 | photoView.clipsToBounds = YES; 176 | 177 | UILabel *title = [[UILabel alloc] initWithFrame: CGRectMake(10, photoContentViewWidth * 3 / 4 + 30, photoContentViewWidth - 20, 50)]; 178 | title.font = [UIFont systemFontOfSize: 20]; 179 | title.textColor = [UIColor colorWithWhite:0.200 alpha:1.000]; 180 | title.numberOfLines = 0; 181 | title.textAlignment = NSTextAlignmentCenter; 182 | title.text = @"每把枪,都印刻着一段记忆难以释怀!"; 183 | [photoView addSubview: title]; 184 | 185 | UIButton *likeButton = [self createButtonWithImage: [[UIImage imageNamed:@"LikeIcon"] imageWithTintColor: [ColorUtils mainColor] blendMode: kCGBlendModeDestinationIn] title: @"4553" frame: CGRectMake(50, photoContentViewHeight - 100, 50, 50)]; 186 | [photoView addSubview: likeButton]; 187 | UIButton *commentButton = [self createButtonWithImage: [[UIImage imageNamed:@"CommentIcon"] imageWithTintColor: [ColorUtils mainColor] blendMode: kCGBlendModeDestinationIn] title: @"1033" frame: CGRectMake(photoContentViewWidth / 2 - 25, photoContentViewHeight - 100, 50, 50)]; 188 | [photoView addSubview: commentButton]; 189 | UIButton *focusButton = [self createButtonWithImage: [[UIImage imageNamed:@"FollowIcon"] imageWithTintColor: [ColorUtils mainColor] blendMode: kCGBlendModeDestinationIn] title: @"120" frame: CGRectMake(photoContentViewWidth - 100, photoContentViewHeight - 100, 50, 50)]; 190 | [photoView addSubview: focusButton]; 191 | 192 | return photoView; 193 | } 194 | 195 | - (UIButton *)createButtonWithImage: (UIImage *)image title: (NSString *)title frame: (CGRect)frame { 196 | UIButton *button = [UIButton buttonWithType: UIButtonTypeCustom]; 197 | button.frame = frame; 198 | button.backgroundColor = [UIColor whiteColor]; 199 | button.titleLabel.font = [UIFont boldSystemFontOfSize: 16]; 200 | button.titleEdgeInsets = UIEdgeInsetsMake(26, 0, 0, 0); 201 | [button setTitle: title forState: UIControlStateNormal]; 202 | [button setTitleColor: [UIColor colorWithWhite:0.200 alpha:1.000] forState: UIControlStateNormal]; 203 | UIImageView *imageView = [[UIImageView alloc] initWithImage: image]; 204 | imageView.contentMode = UIViewContentModeCenter; 205 | imageView.bounds = CGRectMake(0, 0, frame.size.height / 2, frame.size.height / 2); 206 | imageView.center = CGPointMake(frame.size.width / 2, frame.size.height / 4); 207 | [button addSubview: imageView]; 208 | return button; 209 | } 210 | 211 | - (UIImageView *)buildImageView { 212 | UIImageView *topImageView = [[UIImageView alloc] initWithFrame: CGRectMake(0, 0, photoContentViewWidth, photoContentViewWidth * 3 / 4)]; 213 | topImageView.clipsToBounds = YES; 214 | return topImageView; 215 | } 216 | 217 | - (UIBezierPath *)createBezierPath { 218 | UIBezierPath *path = [UIBezierPath bezierPath]; 219 | [path moveToPoint: CGPointMake(10, 40)]; 220 | [path addQuadCurveToPoint: CGPointMake(photoContentViewWidth - 10, 40) controlPoint: CGPointMake(photoContentViewWidth / 2, 0)]; 221 | [path addQuadCurveToPoint: CGPointMake(photoContentViewWidth - 10, photoContentViewHeight - 40) controlPoint: CGPointMake(photoContentViewWidth, photoContentViewHeight / 2)]; 222 | [path addQuadCurveToPoint: CGPointMake(10, photoContentViewHeight - 40) controlPoint: CGPointMake(photoContentViewWidth / 2, photoContentViewHeight)]; 223 | [path addQuadCurveToPoint: CGPointMake(10, 40) controlPoint: CGPointMake(0, photoContentViewHeight / 2)]; 224 | [path closePath]; 225 | return path; 226 | } 227 | 228 | - (CAShapeLayer *)createMaskLayerWithPath: (CGPathRef)path { 229 | CAShapeLayer *maskLayer = [CAShapeLayer layer]; 230 | maskLayer.frame = CGRectMake(0, 0, photoContentViewWidth, photoContentViewHeight); 231 | maskLayer.path = path; 232 | return maskLayer; 233 | } 234 | 235 | - (UIImage *)frontImageWithIndex: (NSInteger)index { 236 | if (index == 0) { 237 | return [UIImage imageNamed: imagesArray[imagesArray.count - 1]]; 238 | } else if (index == (imagesArray.count - 1)) { 239 | return [UIImage imageNamed: imagesArray[imagesArray.count - 2]]; 240 | } else { 241 | return [UIImage imageNamed: imagesArray[currentImageIndex - 1]]; 242 | } 243 | } 244 | 245 | - (UIImage *)currentImageWithIndex: (NSInteger)index { 246 | if (index == 0) { 247 | return [UIImage imageNamed: imagesArray[0]]; 248 | } else if (index == (imagesArray.count - 1)) { 249 | return [UIImage imageNamed: imagesArray[imagesArray.count - 1]]; 250 | } else { 251 | return [UIImage imageNamed: imagesArray[currentImageIndex]]; 252 | } 253 | } 254 | 255 | - (UIImage *)nextImageWithIndex: (NSInteger)index { 256 | if (index == 0) { 257 | return [UIImage imageNamed: imagesArray[1]]; 258 | } else if (index == (imagesArray.count - 1)) { 259 | return [UIImage imageNamed: imagesArray[0]]; 260 | } else { 261 | return [UIImage imageNamed: imagesArray[currentImageIndex + 1]]; 262 | } 263 | } 264 | 265 | @end 266 | -------------------------------------------------------------------------------- /TransitionAnimation/SettingViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SettingViewController.h 3 | // TransitionAnimation 4 | // 5 | // Created by jashion on 16/5/5. 6 | // Copyright © 2016年 BMu. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SettingViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /TransitionAnimation/SettingViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SettingViewController.m 3 | // TransitionAnimation 4 | // 5 | // Created by jashion on 16/5/5. 6 | // Copyright © 2016年 BMu. All rights reserved. 7 | // 8 | 9 | #import "SettingViewController.h" 10 | 11 | @implementation SettingViewController 12 | 13 | - (instancetype)init { 14 | if (self = [super init]) { 15 | self.navigationItem.title = @"Setting"; 16 | } 17 | return self; 18 | } 19 | 20 | - (void)loadView { 21 | [super loadView]; 22 | self.view.backgroundColor = [UIColor colorWithRed:1.000 green:0.800 blue:0.400 alpha:1.000]; 23 | } 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1D0675E61CF5F90F00EA3FCC /* MenuViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D0675E51CF5F90F00EA3FCC /* MenuViewController.m */; }; 11 | 1D1EE3EC1CDA0CD700896447 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D1EE3EB1CDA0CD700896447 /* main.m */; }; 12 | 1D1EE3EF1CDA0CD700896447 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D1EE3EE1CDA0CD700896447 /* AppDelegate.m */; }; 13 | 1D1EE3F71CDA0CD700896447 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1D1EE3F61CDA0CD700896447 /* Assets.xcassets */; }; 14 | 1D1EE40E1CDA264B00896447 /* MyTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D1EE40D1CDA264B00896447 /* MyTableViewCell.m */; }; 15 | 1D1EE41B1CDA3F8800896447 /* DetailController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D1EE41A1CDA3F8800896447 /* DetailController.m */; }; 16 | 1D1EE4241CDAB9DE00896447 /* HomeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D1EE4231CDAB9DE00896447 /* HomeViewController.m */; }; 17 | 1D1EE4271CDAB9F200896447 /* MessageViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D1EE4261CDAB9F200896447 /* MessageViewController.m */; }; 18 | 1D1EE42A1CDABA0E00896447 /* SettingViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D1EE4291CDABA0E00896447 /* SettingViewController.m */; }; 19 | 1D299F701CDEC594003E4AAA /* PersonProfileViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D299F6F1CDEC594003E4AAA /* PersonProfileViewController.m */; }; 20 | 1D299F751CDF8D21003E4AAA /* FXBlurView.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D299F731CDF8D21003E4AAA /* FXBlurView.m */; }; 21 | 1D299F781CE022CB003E4AAA /* PhotoCircleController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D299F771CE022CB003E4AAA /* PhotoCircleController.m */; }; 22 | 1D30FC681CE3769300AF6B26 /* BMInteractiveTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D30FC671CE3769300AF6B26 /* BMInteractiveTransition.m */; }; 23 | 1D5FCED01CE21C0C00D5B723 /* BMAnimateTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D5FCECF1CE21C0C00D5B723 /* BMAnimateTransition.m */; }; 24 | 1D66BE131CDDE9CD00D6B038 /* DetailTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D66BE121CDDE9CD00D6B038 /* DetailTableViewCell.m */; }; 25 | 1D66BE181CDE046200D6B038 /* ColorUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D66BE171CDE046200D6B038 /* ColorUtils.m */; }; 26 | 1D7CF2D61CE7176100F188AC /* BMTabBarController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D7CF2D51CE7176100F188AC /* BMTabBarController.m */; }; 27 | 1D7CF2DD1CE77D9200F188AC /* UIImage+Tint.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D7CF2DC1CE77D9100F188AC /* UIImage+Tint.m */; }; 28 | /* End PBXBuildFile section */ 29 | 30 | /* Begin PBXFileReference section */ 31 | 1D0675E41CF5F90F00EA3FCC /* MenuViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MenuViewController.h; sourceTree = ""; }; 32 | 1D0675E51CF5F90F00EA3FCC /* MenuViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MenuViewController.m; sourceTree = ""; }; 33 | 1D1EE3E71CDA0CD700896447 /* TransitionAnimation.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TransitionAnimation.app; sourceTree = BUILT_PRODUCTS_DIR; }; 34 | 1D1EE3EB1CDA0CD700896447 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 35 | 1D1EE3ED1CDA0CD700896447 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 36 | 1D1EE3EE1CDA0CD700896447 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 37 | 1D1EE3F61CDA0CD700896447 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 38 | 1D1EE3FB1CDA0CD700896447 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 39 | 1D1EE40C1CDA264B00896447 /* MyTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MyTableViewCell.h; sourceTree = ""; }; 40 | 1D1EE40D1CDA264B00896447 /* MyTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MyTableViewCell.m; sourceTree = ""; }; 41 | 1D1EE4191CDA3F8800896447 /* DetailController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DetailController.h; sourceTree = ""; }; 42 | 1D1EE41A1CDA3F8800896447 /* DetailController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DetailController.m; sourceTree = ""; }; 43 | 1D1EE4221CDAB9DE00896447 /* HomeViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HomeViewController.h; sourceTree = ""; }; 44 | 1D1EE4231CDAB9DE00896447 /* HomeViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HomeViewController.m; sourceTree = ""; }; 45 | 1D1EE4251CDAB9F200896447 /* MessageViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MessageViewController.h; sourceTree = ""; }; 46 | 1D1EE4261CDAB9F200896447 /* MessageViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MessageViewController.m; sourceTree = ""; }; 47 | 1D1EE4281CDABA0E00896447 /* SettingViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SettingViewController.h; sourceTree = ""; }; 48 | 1D1EE4291CDABA0E00896447 /* SettingViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SettingViewController.m; sourceTree = ""; }; 49 | 1D299F6E1CDEC594003E4AAA /* PersonProfileViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PersonProfileViewController.h; sourceTree = ""; }; 50 | 1D299F6F1CDEC594003E4AAA /* PersonProfileViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PersonProfileViewController.m; sourceTree = ""; }; 51 | 1D299F731CDF8D21003E4AAA /* FXBlurView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FXBlurView.m; sourceTree = ""; }; 52 | 1D299F741CDF8D21003E4AAA /* FXBlurView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FXBlurView.h; sourceTree = ""; }; 53 | 1D299F761CE022CB003E4AAA /* PhotoCircleController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PhotoCircleController.h; sourceTree = ""; }; 54 | 1D299F771CE022CB003E4AAA /* PhotoCircleController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PhotoCircleController.m; sourceTree = ""; }; 55 | 1D30FC661CE3769300AF6B26 /* BMInteractiveTransition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BMInteractiveTransition.h; sourceTree = ""; }; 56 | 1D30FC671CE3769300AF6B26 /* BMInteractiveTransition.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BMInteractiveTransition.m; sourceTree = ""; }; 57 | 1D5FCECE1CE21C0C00D5B723 /* BMAnimateTransition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BMAnimateTransition.h; sourceTree = ""; }; 58 | 1D5FCECF1CE21C0C00D5B723 /* BMAnimateTransition.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BMAnimateTransition.m; sourceTree = ""; }; 59 | 1D66BE111CDDE9CD00D6B038 /* DetailTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DetailTableViewCell.h; sourceTree = ""; }; 60 | 1D66BE121CDDE9CD00D6B038 /* DetailTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DetailTableViewCell.m; sourceTree = ""; }; 61 | 1D66BE161CDE046200D6B038 /* ColorUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ColorUtils.h; sourceTree = ""; }; 62 | 1D66BE171CDE046200D6B038 /* ColorUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ColorUtils.m; sourceTree = ""; }; 63 | 1D7CF2D41CE7176100F188AC /* BMTabBarController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BMTabBarController.h; sourceTree = ""; }; 64 | 1D7CF2D51CE7176100F188AC /* BMTabBarController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BMTabBarController.m; sourceTree = ""; }; 65 | 1D7CF2DB1CE77D9100F188AC /* UIImage+Tint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+Tint.h"; sourceTree = ""; }; 66 | 1D7CF2DC1CE77D9100F188AC /* UIImage+Tint.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+Tint.m"; sourceTree = ""; }; 67 | /* End PBXFileReference section */ 68 | 69 | /* Begin PBXFrameworksBuildPhase section */ 70 | 1D1EE3E41CDA0CD700896447 /* Frameworks */ = { 71 | isa = PBXFrameworksBuildPhase; 72 | buildActionMask = 2147483647; 73 | files = ( 74 | ); 75 | runOnlyForDeploymentPostprocessing = 0; 76 | }; 77 | /* End PBXFrameworksBuildPhase section */ 78 | 79 | /* Begin PBXGroup section */ 80 | 1D0675BA1CF5AA2E00EA3FCC /* Blur */ = { 81 | isa = PBXGroup; 82 | children = ( 83 | 1D299F741CDF8D21003E4AAA /* FXBlurView.h */, 84 | 1D299F731CDF8D21003E4AAA /* FXBlurView.m */, 85 | ); 86 | name = Blur; 87 | sourceTree = ""; 88 | }; 89 | 1D1EE3DE1CDA0CD700896447 = { 90 | isa = PBXGroup; 91 | children = ( 92 | 1DB7ECA21CF19A9600D361D4 /* Widgets */, 93 | 1D7CF2DA1CE77D7500F188AC /* Categories */, 94 | 1D299F721CDF8CFB003E4AAA /* 3rd */, 95 | 1D299F711CDF2589003E4AAA /* BgImages */, 96 | 1D66BE151CDE044D00D6B038 /* Utils */, 97 | 1D66BE141CDDFCA100D6B038 /* Button */, 98 | 1D1EE4091CDA256100896447 /* Table */, 99 | 1D1EE4181CDA3F6900896447 /* Controllers */, 100 | 1D1EE4011CDA1B2100896447 /* TabControllers */, 101 | 1D1EE40B1CDA257000896447 /* View */, 102 | 1D1EE40A1CDA256800896447 /* Collection */, 103 | 1D1EE4081CDA254E00896447 /* Transition */, 104 | 1D1EE3E91CDA0CD700896447 /* TransitionAnimation */, 105 | 1D1EE3E81CDA0CD700896447 /* Products */, 106 | ); 107 | sourceTree = ""; 108 | }; 109 | 1D1EE3E81CDA0CD700896447 /* Products */ = { 110 | isa = PBXGroup; 111 | children = ( 112 | 1D1EE3E71CDA0CD700896447 /* TransitionAnimation.app */, 113 | ); 114 | name = Products; 115 | sourceTree = ""; 116 | }; 117 | 1D1EE3E91CDA0CD700896447 /* TransitionAnimation */ = { 118 | isa = PBXGroup; 119 | children = ( 120 | 1D1EE3ED1CDA0CD700896447 /* AppDelegate.h */, 121 | 1D1EE3EE1CDA0CD700896447 /* AppDelegate.m */, 122 | 1D1EE3F61CDA0CD700896447 /* Assets.xcassets */, 123 | 1D1EE3FB1CDA0CD700896447 /* Info.plist */, 124 | 1D1EE3EA1CDA0CD700896447 /* Supporting Files */, 125 | ); 126 | path = TransitionAnimation; 127 | sourceTree = ""; 128 | }; 129 | 1D1EE3EA1CDA0CD700896447 /* Supporting Files */ = { 130 | isa = PBXGroup; 131 | children = ( 132 | 1D1EE3EB1CDA0CD700896447 /* main.m */, 133 | ); 134 | name = "Supporting Files"; 135 | sourceTree = ""; 136 | }; 137 | 1D1EE4011CDA1B2100896447 /* TabControllers */ = { 138 | isa = PBXGroup; 139 | children = ( 140 | 1D1EE4221CDAB9DE00896447 /* HomeViewController.h */, 141 | 1D1EE4231CDAB9DE00896447 /* HomeViewController.m */, 142 | 1D1EE4251CDAB9F200896447 /* MessageViewController.h */, 143 | 1D1EE4261CDAB9F200896447 /* MessageViewController.m */, 144 | 1D1EE4281CDABA0E00896447 /* SettingViewController.h */, 145 | 1D1EE4291CDABA0E00896447 /* SettingViewController.m */, 146 | 1D7CF2D41CE7176100F188AC /* BMTabBarController.h */, 147 | 1D7CF2D51CE7176100F188AC /* BMTabBarController.m */, 148 | ); 149 | name = TabControllers; 150 | sourceTree = ""; 151 | }; 152 | 1D1EE4081CDA254E00896447 /* Transition */ = { 153 | isa = PBXGroup; 154 | children = ( 155 | 1D5FCECE1CE21C0C00D5B723 /* BMAnimateTransition.h */, 156 | 1D5FCECF1CE21C0C00D5B723 /* BMAnimateTransition.m */, 157 | 1D30FC661CE3769300AF6B26 /* BMInteractiveTransition.h */, 158 | 1D30FC671CE3769300AF6B26 /* BMInteractiveTransition.m */, 159 | ); 160 | name = Transition; 161 | sourceTree = ""; 162 | }; 163 | 1D1EE4091CDA256100896447 /* Table */ = { 164 | isa = PBXGroup; 165 | children = ( 166 | 1D1EE40C1CDA264B00896447 /* MyTableViewCell.h */, 167 | 1D1EE40D1CDA264B00896447 /* MyTableViewCell.m */, 168 | 1D66BE111CDDE9CD00D6B038 /* DetailTableViewCell.h */, 169 | 1D66BE121CDDE9CD00D6B038 /* DetailTableViewCell.m */, 170 | ); 171 | name = Table; 172 | sourceTree = ""; 173 | }; 174 | 1D1EE40A1CDA256800896447 /* Collection */ = { 175 | isa = PBXGroup; 176 | children = ( 177 | ); 178 | name = Collection; 179 | sourceTree = ""; 180 | }; 181 | 1D1EE40B1CDA257000896447 /* View */ = { 182 | isa = PBXGroup; 183 | children = ( 184 | ); 185 | name = View; 186 | sourceTree = ""; 187 | }; 188 | 1D1EE4181CDA3F6900896447 /* Controllers */ = { 189 | isa = PBXGroup; 190 | children = ( 191 | 1D1EE4191CDA3F8800896447 /* DetailController.h */, 192 | 1D1EE41A1CDA3F8800896447 /* DetailController.m */, 193 | 1D299F6E1CDEC594003E4AAA /* PersonProfileViewController.h */, 194 | 1D299F6F1CDEC594003E4AAA /* PersonProfileViewController.m */, 195 | 1D299F761CE022CB003E4AAA /* PhotoCircleController.h */, 196 | 1D299F771CE022CB003E4AAA /* PhotoCircleController.m */, 197 | 1D0675E41CF5F90F00EA3FCC /* MenuViewController.h */, 198 | 1D0675E51CF5F90F00EA3FCC /* MenuViewController.m */, 199 | ); 200 | name = Controllers; 201 | sourceTree = ""; 202 | }; 203 | 1D299F711CDF2589003E4AAA /* BgImages */ = { 204 | isa = PBXGroup; 205 | children = ( 206 | ); 207 | name = BgImages; 208 | sourceTree = ""; 209 | }; 210 | 1D299F721CDF8CFB003E4AAA /* 3rd */ = { 211 | isa = PBXGroup; 212 | children = ( 213 | 1D0675BA1CF5AA2E00EA3FCC /* Blur */, 214 | ); 215 | name = 3rd; 216 | sourceTree = ""; 217 | }; 218 | 1D66BE141CDDFCA100D6B038 /* Button */ = { 219 | isa = PBXGroup; 220 | children = ( 221 | ); 222 | name = Button; 223 | sourceTree = ""; 224 | }; 225 | 1D66BE151CDE044D00D6B038 /* Utils */ = { 226 | isa = PBXGroup; 227 | children = ( 228 | 1D66BE161CDE046200D6B038 /* ColorUtils.h */, 229 | 1D66BE171CDE046200D6B038 /* ColorUtils.m */, 230 | ); 231 | name = Utils; 232 | sourceTree = ""; 233 | }; 234 | 1D7CF2DA1CE77D7500F188AC /* Categories */ = { 235 | isa = PBXGroup; 236 | children = ( 237 | 1D7CF2DB1CE77D9100F188AC /* UIImage+Tint.h */, 238 | 1D7CF2DC1CE77D9100F188AC /* UIImage+Tint.m */, 239 | ); 240 | name = Categories; 241 | sourceTree = ""; 242 | }; 243 | 1DB7ECA21CF19A9600D361D4 /* Widgets */ = { 244 | isa = PBXGroup; 245 | children = ( 246 | ); 247 | name = Widgets; 248 | sourceTree = ""; 249 | }; 250 | /* End PBXGroup section */ 251 | 252 | /* Begin PBXNativeTarget section */ 253 | 1D1EE3E61CDA0CD700896447 /* TransitionAnimation */ = { 254 | isa = PBXNativeTarget; 255 | buildConfigurationList = 1D1EE3FE1CDA0CD700896447 /* Build configuration list for PBXNativeTarget "TransitionAnimation" */; 256 | buildPhases = ( 257 | 1D1EE3E31CDA0CD700896447 /* Sources */, 258 | 1D1EE3E41CDA0CD700896447 /* Frameworks */, 259 | 1D1EE3E51CDA0CD700896447 /* Resources */, 260 | ); 261 | buildRules = ( 262 | ); 263 | dependencies = ( 264 | ); 265 | name = TransitionAnimation; 266 | productName = TransitionAnimation; 267 | productReference = 1D1EE3E71CDA0CD700896447 /* TransitionAnimation.app */; 268 | productType = "com.apple.product-type.application"; 269 | }; 270 | /* End PBXNativeTarget section */ 271 | 272 | /* Begin PBXProject section */ 273 | 1D1EE3DF1CDA0CD700896447 /* Project object */ = { 274 | isa = PBXProject; 275 | attributes = { 276 | LastUpgradeCheck = 0820; 277 | ORGANIZATIONNAME = BMu; 278 | TargetAttributes = { 279 | 1D1EE3E61CDA0CD700896447 = { 280 | CreatedOnToolsVersion = 7.3; 281 | }; 282 | }; 283 | }; 284 | buildConfigurationList = 1D1EE3E21CDA0CD700896447 /* Build configuration list for PBXProject "TransitionAnimation" */; 285 | compatibilityVersion = "Xcode 3.2"; 286 | developmentRegion = English; 287 | hasScannedForEncodings = 0; 288 | knownRegions = ( 289 | en, 290 | Base, 291 | ); 292 | mainGroup = 1D1EE3DE1CDA0CD700896447; 293 | productRefGroup = 1D1EE3E81CDA0CD700896447 /* Products */; 294 | projectDirPath = ""; 295 | projectRoot = ""; 296 | targets = ( 297 | 1D1EE3E61CDA0CD700896447 /* TransitionAnimation */, 298 | ); 299 | }; 300 | /* End PBXProject section */ 301 | 302 | /* Begin PBXResourcesBuildPhase section */ 303 | 1D1EE3E51CDA0CD700896447 /* Resources */ = { 304 | isa = PBXResourcesBuildPhase; 305 | buildActionMask = 2147483647; 306 | files = ( 307 | 1D1EE3F71CDA0CD700896447 /* Assets.xcassets in Resources */, 308 | ); 309 | runOnlyForDeploymentPostprocessing = 0; 310 | }; 311 | /* End PBXResourcesBuildPhase section */ 312 | 313 | /* Begin PBXSourcesBuildPhase section */ 314 | 1D1EE3E31CDA0CD700896447 /* Sources */ = { 315 | isa = PBXSourcesBuildPhase; 316 | buildActionMask = 2147483647; 317 | files = ( 318 | 1D299F701CDEC594003E4AAA /* PersonProfileViewController.m in Sources */, 319 | 1D0675E61CF5F90F00EA3FCC /* MenuViewController.m in Sources */, 320 | 1D1EE41B1CDA3F8800896447 /* DetailController.m in Sources */, 321 | 1D1EE3EF1CDA0CD700896447 /* AppDelegate.m in Sources */, 322 | 1D5FCED01CE21C0C00D5B723 /* BMAnimateTransition.m in Sources */, 323 | 1D7CF2DD1CE77D9200F188AC /* UIImage+Tint.m in Sources */, 324 | 1D66BE181CDE046200D6B038 /* ColorUtils.m in Sources */, 325 | 1D66BE131CDDE9CD00D6B038 /* DetailTableViewCell.m in Sources */, 326 | 1D7CF2D61CE7176100F188AC /* BMTabBarController.m in Sources */, 327 | 1D30FC681CE3769300AF6B26 /* BMInteractiveTransition.m in Sources */, 328 | 1D1EE40E1CDA264B00896447 /* MyTableViewCell.m in Sources */, 329 | 1D299F751CDF8D21003E4AAA /* FXBlurView.m in Sources */, 330 | 1D1EE42A1CDABA0E00896447 /* SettingViewController.m in Sources */, 331 | 1D1EE4241CDAB9DE00896447 /* HomeViewController.m in Sources */, 332 | 1D299F781CE022CB003E4AAA /* PhotoCircleController.m in Sources */, 333 | 1D1EE4271CDAB9F200896447 /* MessageViewController.m in Sources */, 334 | 1D1EE3EC1CDA0CD700896447 /* main.m in Sources */, 335 | ); 336 | runOnlyForDeploymentPostprocessing = 0; 337 | }; 338 | /* End PBXSourcesBuildPhase section */ 339 | 340 | /* Begin XCBuildConfiguration section */ 341 | 1D1EE3FC1CDA0CD700896447 /* Debug */ = { 342 | isa = XCBuildConfiguration; 343 | buildSettings = { 344 | ALWAYS_SEARCH_USER_PATHS = NO; 345 | CLANG_ANALYZER_NONNULL = YES; 346 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 347 | CLANG_CXX_LIBRARY = "libc++"; 348 | CLANG_ENABLE_MODULES = YES; 349 | CLANG_ENABLE_OBJC_ARC = YES; 350 | CLANG_WARN_BOOL_CONVERSION = YES; 351 | CLANG_WARN_CONSTANT_CONVERSION = YES; 352 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 353 | CLANG_WARN_EMPTY_BODY = YES; 354 | CLANG_WARN_ENUM_CONVERSION = YES; 355 | CLANG_WARN_INFINITE_RECURSION = YES; 356 | CLANG_WARN_INT_CONVERSION = YES; 357 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 358 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 359 | CLANG_WARN_UNREACHABLE_CODE = YES; 360 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 361 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 362 | COPY_PHASE_STRIP = NO; 363 | DEBUG_INFORMATION_FORMAT = dwarf; 364 | ENABLE_STRICT_OBJC_MSGSEND = YES; 365 | ENABLE_TESTABILITY = YES; 366 | GCC_C_LANGUAGE_STANDARD = gnu99; 367 | GCC_DYNAMIC_NO_PIC = NO; 368 | GCC_NO_COMMON_BLOCKS = YES; 369 | GCC_OPTIMIZATION_LEVEL = 0; 370 | GCC_PREPROCESSOR_DEFINITIONS = ( 371 | "DEBUG=1", 372 | "$(inherited)", 373 | ); 374 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 375 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 376 | GCC_WARN_UNDECLARED_SELECTOR = YES; 377 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 378 | GCC_WARN_UNUSED_FUNCTION = YES; 379 | GCC_WARN_UNUSED_VARIABLE = YES; 380 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 381 | MTL_ENABLE_DEBUG_INFO = YES; 382 | ONLY_ACTIVE_ARCH = YES; 383 | SDKROOT = iphoneos; 384 | }; 385 | name = Debug; 386 | }; 387 | 1D1EE3FD1CDA0CD700896447 /* Release */ = { 388 | isa = XCBuildConfiguration; 389 | buildSettings = { 390 | ALWAYS_SEARCH_USER_PATHS = NO; 391 | CLANG_ANALYZER_NONNULL = YES; 392 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 393 | CLANG_CXX_LIBRARY = "libc++"; 394 | CLANG_ENABLE_MODULES = YES; 395 | CLANG_ENABLE_OBJC_ARC = YES; 396 | CLANG_WARN_BOOL_CONVERSION = YES; 397 | CLANG_WARN_CONSTANT_CONVERSION = YES; 398 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 399 | CLANG_WARN_EMPTY_BODY = YES; 400 | CLANG_WARN_ENUM_CONVERSION = YES; 401 | CLANG_WARN_INFINITE_RECURSION = YES; 402 | CLANG_WARN_INT_CONVERSION = YES; 403 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 404 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 405 | CLANG_WARN_UNREACHABLE_CODE = YES; 406 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 407 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 408 | COPY_PHASE_STRIP = NO; 409 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 410 | ENABLE_NS_ASSERTIONS = NO; 411 | ENABLE_STRICT_OBJC_MSGSEND = YES; 412 | GCC_C_LANGUAGE_STANDARD = gnu99; 413 | GCC_NO_COMMON_BLOCKS = YES; 414 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 415 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 416 | GCC_WARN_UNDECLARED_SELECTOR = YES; 417 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 418 | GCC_WARN_UNUSED_FUNCTION = YES; 419 | GCC_WARN_UNUSED_VARIABLE = YES; 420 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 421 | MTL_ENABLE_DEBUG_INFO = NO; 422 | SDKROOT = iphoneos; 423 | VALIDATE_PRODUCT = YES; 424 | }; 425 | name = Release; 426 | }; 427 | 1D1EE3FF1CDA0CD700896447 /* Debug */ = { 428 | isa = XCBuildConfiguration; 429 | buildSettings = { 430 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 431 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 432 | CODE_SIGN_IDENTITY = "iPhone Developer"; 433 | INFOPLIST_FILE = TransitionAnimation/Info.plist; 434 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 435 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 436 | PRODUCT_BUNDLE_IDENTIFIER = com.bmu.TransitionAnimation; 437 | PRODUCT_NAME = "$(TARGET_NAME)"; 438 | }; 439 | name = Debug; 440 | }; 441 | 1D1EE4001CDA0CD700896447 /* Release */ = { 442 | isa = XCBuildConfiguration; 443 | buildSettings = { 444 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 445 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 446 | CODE_SIGN_IDENTITY = "iPhone Developer"; 447 | INFOPLIST_FILE = TransitionAnimation/Info.plist; 448 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 449 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 450 | PRODUCT_BUNDLE_IDENTIFIER = com.bmu.TransitionAnimation; 451 | PRODUCT_NAME = "$(TARGET_NAME)"; 452 | }; 453 | name = Release; 454 | }; 455 | /* End XCBuildConfiguration section */ 456 | 457 | /* Begin XCConfigurationList section */ 458 | 1D1EE3E21CDA0CD700896447 /* Build configuration list for PBXProject "TransitionAnimation" */ = { 459 | isa = XCConfigurationList; 460 | buildConfigurations = ( 461 | 1D1EE3FC1CDA0CD700896447 /* Debug */, 462 | 1D1EE3FD1CDA0CD700896447 /* Release */, 463 | ); 464 | defaultConfigurationIsVisible = 0; 465 | defaultConfigurationName = Release; 466 | }; 467 | 1D1EE3FE1CDA0CD700896447 /* Build configuration list for PBXNativeTarget "TransitionAnimation" */ = { 468 | isa = XCConfigurationList; 469 | buildConfigurations = ( 470 | 1D1EE3FF1CDA0CD700896447 /* Debug */, 471 | 1D1EE4001CDA0CD700896447 /* Release */, 472 | ); 473 | defaultConfigurationIsVisible = 0; 474 | defaultConfigurationName = Release; 475 | }; 476 | /* End XCConfigurationList section */ 477 | }; 478 | rootObject = 1D1EE3DF1CDA0CD700896447 /* Project object */; 479 | } 480 | -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // TransitionAnimation 4 | // 5 | // Created by jashion on 16/5/4. 6 | // Copyright © 2016年 BMu. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // TransitionAnimation 4 | // 5 | // Created by jashion on 16/5/4. 6 | // Copyright © 2016年 BMu. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "HomeViewController.h" 11 | #import "MessageViewController.h" 12 | #import "SettingViewController.h" 13 | #import "objc/runtime.h" 14 | #import "ColorUtils.h" 15 | #import "BMAnimateTransition.h" 16 | #import "BMInteractiveTransition.h" 17 | #import "UIImage+Tint.h" 18 | 19 | #define kRect [UIScreen mainScreen].bounds 20 | 21 | @interface AppDelegate () 22 | 23 | @property (nonatomic, assign) CGPoint tapPoint; 24 | @property (nonatomic, strong) BMAnimateTransition *transition; 25 | @property (nonatomic, strong) BMInteractiveTransition *interactive; 26 | @property (nonatomic, strong) UIImageView *maskView; 27 | @property (nonatomic, strong) UIImageView *splashView; 28 | @property (nonatomic, strong) UIView *container; 29 | @property (nonatomic, strong) UIBezierPath *path; 30 | @property (nonatomic, strong) UITabBarController *tabVC; 31 | 32 | @end 33 | 34 | @implementation AppDelegate 35 | 36 | 37 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 38 | self.window = [[UIWindow alloc] initWithFrame: [UIScreen mainScreen].bounds]; 39 | self.window.backgroundColor = [UIColor whiteColor]; 40 | self.tabVC = [self createTabController]; 41 | self.window.rootViewController = self.tabVC; 42 | [self.window makeKeyAndVisible]; 43 | self.transition = [BMAnimateTransition new]; 44 | self.transition.operation = BMAnimateTransitionTabBarCircleLayer; 45 | [self lanuchSplashAnimation]; 46 | return YES; 47 | } 48 | 49 | #pragma mark - Private Method 50 | 51 | - (UITabBarController *)createTabController { 52 | HomeViewController *home = [[HomeViewController alloc] init]; 53 | UINavigationController *homeNav = [[UINavigationController alloc] initWithRootViewController: home]; 54 | homeNav.navigationBar.tintColor = [ColorUtils mainColor]; 55 | homeNav.tabBarItem.title = @"Home"; 56 | homeNav.tabBarItem.image = [UIImage imageNamed:@"HomeUnSelect"]; 57 | homeNav.tabBarItem.selectedImage = [[[UIImage imageNamed:@"HomeSelect"] imageWithTintColor: [ColorUtils mainColor] blendMode: kCGBlendModeDestinationIn] imageWithRenderingMode: UIImageRenderingModeAlwaysOriginal]; 58 | 59 | MessageViewController *message = [[MessageViewController alloc] init]; 60 | UINavigationController *messageNav = [[UINavigationController alloc] initWithRootViewController: message]; 61 | messageNav.navigationBar.tintColor = [ColorUtils mainColor]; 62 | messageNav.tabBarItem.title = @"Message"; 63 | messageNav.tabBarItem.image = [UIImage imageNamed:@"MessageUnSelect"]; 64 | messageNav.tabBarItem.selectedImage = [[[UIImage imageNamed:@"MessageSelect"] imageWithTintColor: [ColorUtils mainColor] blendMode: kCGBlendModeDestinationIn] imageWithRenderingMode: UIImageRenderingModeAlwaysOriginal]; 65 | 66 | SettingViewController *setting = [[SettingViewController alloc] init]; 67 | UINavigationController *settingNav = [[UINavigationController alloc] initWithRootViewController: setting]; 68 | settingNav.navigationBar.tintColor = [ColorUtils mainColor]; 69 | settingNav.tabBarItem.title = @"Setting"; 70 | settingNav.tabBarItem.image = [UIImage imageNamed:@"SettingUnSelect"]; 71 | settingNav.tabBarItem.selectedImage = [[[UIImage imageNamed:@"SettingSelect"] imageWithTintColor: [ColorUtils mainColor] blendMode: kCGBlendModeDestinationIn] imageWithRenderingMode: UIImageRenderingModeAlwaysOriginal]; 72 | 73 | UITabBarController *tabBarController = [[UITabBarController alloc] init]; 74 | tabBarController.viewControllers = @[homeNav, messageNav, settingNav]; 75 | tabBarController.tabBar.tintColor = [ColorUtils mainColor]; 76 | tabBarController.delegate = self; 77 | return tabBarController; 78 | } 79 | 80 | - (void)lanuchSplashAnimation { 81 | CGRect rect = [UIScreen mainScreen].bounds; 82 | self.container = [[UIView alloc] initWithFrame: rect]; 83 | self.container.backgroundColor = [UIColor whiteColor]; 84 | [self.window addSubview: self.container]; 85 | 86 | self.splashView = [[UIImageView alloc] initWithFrame: self.container.bounds]; 87 | self.splashView.image = [UIImage imageNamed:@"LauncgSplashImage"]; 88 | self.splashView.alpha = 0; 89 | [self.container addSubview: self.splashView]; 90 | 91 | self.maskView = [[UIImageView alloc] initWithImage: [[UIImage imageNamed:@"WhiteCircleImage"] imageWithTintColor: [UIColor colorWithRed:1.000 green:0.800 blue:0.000 alpha:1.000] blendMode: kCGBlendModeDestinationIn]]; 92 | self.maskView.bounds = CGRectMake(0, 0, 60, 60); 93 | self.maskView.center = CGPointMake(0, kRect.size.height / 2 + 100); 94 | self.maskView.backgroundColor = [UIColor clearColor]; 95 | [self.window addSubview: self.maskView]; 96 | 97 | UIBezierPath *path = [UIBezierPath bezierPath]; 98 | [path moveToPoint: CGPointMake(0, kRect.size.height / 2 + 100)]; 99 | [path addQuadCurveToPoint: CGPointMake(kRect.size.width / 6, kRect.size.height - 60) controlPoint: CGPointMake(kRect.size.width / 6 - 20, kRect.size.height / 2 + 100)]; 100 | 101 | CAKeyframeAnimation *keyAnimation = [CAKeyframeAnimation animationWithKeyPath: @"position"]; 102 | keyAnimation.path = path.CGPath; 103 | 104 | CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath: @"transform.scale"]; 105 | basicAnimation.toValue = [NSValue valueWithCGSize: CGSizeMake(0.8, 0.8)]; 106 | 107 | CAAnimationGroup *group = [CAAnimationGroup animation]; 108 | group.duration = 0.5; 109 | group.fillMode = kCAFillModeForwards; 110 | group.removedOnCompletion = NO; 111 | group.timingFunction = [CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaseInEaseOut]; 112 | group.animations = @[keyAnimation, basicAnimation]; 113 | group.delegate = self; 114 | [group setValue: @"firstStep" forKey: @"animationName"]; 115 | 116 | [self.maskView.layer addAnimation: group forKey: @"firstStep"]; 117 | } 118 | 119 | #pragma mark - CAAnimationDelegate 120 | 121 | - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag { 122 | CGRect rect = self.maskView.frame; 123 | if ([[anim valueForKey: @"animationName"] isEqualToString: @"firstStep"]) { 124 | [UIView animateWithDuration: 0.1 delay: 0 options: UIViewAnimationOptionCurveEaseOut animations:^{ 125 | self.maskView.bounds = CGRectMake(0, 0, rect.size.width * 1.2, rect.size.height * 0.8); 126 | } completion:^(BOOL finished) { 127 | [UIView animateWithDuration: 0.1 animations:^{ 128 | self.maskView.bounds = rect; 129 | }]; 130 | 131 | UIBezierPath *path = [UIBezierPath bezierPath]; 132 | [path moveToPoint: CGPointMake(kRect.size.width / 6, kRect.size.height - 60)]; 133 | [path addQuadCurveToPoint: CGPointMake(kRect.size.width / 2, kRect.size.height * 3 / 4) controlPoint: CGPointMake(kRect.size.width / 2 - 50, kRect.size.height * 3 / 4 - 50)]; 134 | 135 | CAKeyframeAnimation *keyAnimation = [CAKeyframeAnimation animationWithKeyPath: @"position"]; 136 | keyAnimation.path = path.CGPath; 137 | 138 | CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath: @"transform.scale"]; 139 | basicAnimation.toValue = [NSValue valueWithCGSize: CGSizeMake(0.5, 0.5)]; 140 | 141 | CAAnimationGroup *group = [CAAnimationGroup animation]; 142 | group.duration = 0.6; 143 | group.fillMode = kCAFillModeForwards; 144 | group.removedOnCompletion = NO; 145 | group.timingFunction = [CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaseInEaseOut]; 146 | group.animations = @[keyAnimation, basicAnimation]; 147 | group.delegate = self; 148 | [group setValue: @"secondStep" forKey: @"animationName"]; 149 | 150 | [self.maskView.layer addAnimation: group forKey: @"secondStep"]; 151 | }]; 152 | } else if ([[anim valueForKey: @"animationName"] isEqualToString: @"secondStep"]) { 153 | [UIView animateWithDuration: 0.1 delay: 0 options: UIViewAnimationOptionCurveEaseOut animations:^{ 154 | self.maskView.bounds = CGRectMake(0, 0, rect.size.width * 1.2, rect.size.height * 0.8); 155 | } completion:^(BOOL finished) { 156 | [UIView animateWithDuration: 0.1 animations:^{ 157 | self.maskView.bounds = rect; 158 | }]; 159 | 160 | UIBezierPath *path = [UIBezierPath bezierPath]; 161 | [path moveToPoint: CGPointMake(kRect.size.width / 2, kRect.size.height * 3 / 4)]; 162 | [path addLineToPoint: CGPointMake(kRect.size.width / 2, kRect.size.height / 2)]; 163 | 164 | CAKeyframeAnimation *keyAnimation = [CAKeyframeAnimation animationWithKeyPath: @"position"]; 165 | keyAnimation.path = path.CGPath; 166 | 167 | CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath: @"transform.scale"]; 168 | basicAnimation.toValue = [NSValue valueWithCGSize: CGSizeMake(0.7, 0.7)]; 169 | 170 | CAAnimationGroup *group = [CAAnimationGroup animation]; 171 | group.duration = 0.3; 172 | group.fillMode = kCAFillModeForwards; 173 | group.removedOnCompletion = NO; 174 | group.timingFunction = [CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaseInEaseOut]; 175 | group.animations = @[keyAnimation, basicAnimation]; 176 | group.delegate = self; 177 | [group setValue: @"finalStep" forKey: @"animationName"]; 178 | 179 | [self.maskView.layer addAnimation: group forKey: @"finalStep"]; 180 | }]; 181 | } else if ([[anim valueForKey: @"animationName"] isEqualToString: @"finalStep"]) { 182 | CGFloat radius = sqrtf(powf(kRect.size.width, 2) + powf(kRect.size.height, 2)); 183 | 184 | UIView *maskContentView = [[UIView alloc] init]; 185 | maskContentView.bounds = CGRectMake(0, 0, 42, 42); 186 | maskContentView.center = CGPointMake(kRect.size.width / 2, kRect.size.height / 2); 187 | maskContentView.backgroundColor = [UIColor colorWithRed:1.000 green:0.800 blue:0.000 alpha:1.000]; 188 | maskContentView.layer.cornerRadius = 21; 189 | maskContentView.layer.masksToBounds = YES; 190 | [self.window addSubview: maskContentView]; 191 | 192 | [self.maskView removeFromSuperview]; 193 | self.splashView.layer.mask = maskContentView.layer; 194 | [UIView animateWithDuration: 0.4 animations:^{ 195 | self.splashView.alpha = 1; 196 | maskContentView.transform = CGAffineTransformMakeScale(radius / 42, radius / 42); 197 | } completion:^(BOOL finished) { 198 | [UIView transitionFromView: self.container toView: self.tabVC.view duration: 0.6 options: UIViewAnimationOptionTransitionFlipFromLeft completion:^(BOOL finished) { 199 | [self.container removeFromSuperview]; 200 | }]; 201 | }]; 202 | 203 | } 204 | } 205 | 206 | #pragma mark - UITabBarControllerDelegate 207 | 208 | - (nullable id )tabBarController:(UITabBarController *)tabBarController 209 | animationControllerForTransitionFromViewController:(UIViewController *)fromVC 210 | toViewController:(UIViewController *)toVC { 211 | return self.transition; 212 | } 213 | 214 | @end 215 | -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/AppIcon.appiconset/AppIcon29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/AppIcon.appiconset/AppIcon29@2x.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/AppIcon.appiconset/AppIcon29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/AppIcon.appiconset/AppIcon29@3x.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/AppIcon.appiconset/AppIcon40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/AppIcon.appiconset/AppIcon40@2x.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/AppIcon.appiconset/AppIcon40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/AppIcon.appiconset/AppIcon40@3x.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/AppIcon.appiconset/AppIcon60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/AppIcon.appiconset/AppIcon60@2x.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/AppIcon.appiconset/AppIcon60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/AppIcon.appiconset/AppIcon60@3x.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "29x29", 5 | "idiom" : "iphone", 6 | "filename" : "AppIcon29@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "29x29", 11 | "idiom" : "iphone", 12 | "filename" : "AppIcon29@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "40x40", 17 | "idiom" : "iphone", 18 | "filename" : "AppIcon40@2x.png", 19 | "scale" : "2x" 20 | }, 21 | { 22 | "size" : "40x40", 23 | "idiom" : "iphone", 24 | "filename" : "AppIcon40@3x.png", 25 | "scale" : "3x" 26 | }, 27 | { 28 | "size" : "60x60", 29 | "idiom" : "iphone", 30 | "filename" : "AppIcon60@2x.png", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "size" : "60x60", 35 | "idiom" : "iphone", 36 | "filename" : "AppIcon60@3x.png", 37 | "scale" : "3x" 38 | } 39 | ], 40 | "info" : { 41 | "version" : 1, 42 | "author" : "xcode" 43 | } 44 | } -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/BackIcon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "back.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/BackIcon.imageset/back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/BackIcon.imageset/back.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/CellAvatars/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/CellAvatars/Jashion.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "FE508EFC-24DD-4040-8852-AF6E172F5670.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/CellAvatars/Jashion.imageset/FE508EFC-24DD-4040-8852-AF6E172F5670.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/CellAvatars/Jashion.imageset/FE508EFC-24DD-4040-8852-AF6E172F5670.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/CellAvatars/Kevin Burr.imageset/7BBCD252-759F-48D4-960E-DC17CC0DC01D.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/CellAvatars/Kevin Burr.imageset/7BBCD252-759F-48D4-960E-DC17CC0DC01D.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/CellAvatars/Kevin Burr.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "7BBCD252-759F-48D4-960E-DC17CC0DC01D.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/CellAvatars/Marry.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "DAF7267A-1436-4938-B7F5-640264EB2D4E.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/CellAvatars/Marry.imageset/DAF7267A-1436-4938-B7F5-640264EB2D4E.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/CellAvatars/Marry.imageset/DAF7267A-1436-4938-B7F5-640264EB2D4E.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/CellAvatars/Sean Furr.imageset/421DEE67-5968-40E3-AD5A-EF602A859755.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/CellAvatars/Sean Furr.imageset/421DEE67-5968-40E3-AD5A-EF602A859755.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/CellAvatars/Sean Furr.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "421DEE67-5968-40E3-AD5A-EF602A859755.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/CellAvatars/Sheet.imageset/9516CAED-3453-4F2D-9996-06E24EDBF612.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/CellAvatars/Sheet.imageset/9516CAED-3453-4F2D-9996-06E24EDBF612.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/CellAvatars/Sheet.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "9516CAED-3453-4F2D-9996-06E24EDBF612.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/CellAvatars/Stan.imageset/961BDD4A-6C6A-44A4-BE88-13B56FD03085.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/CellAvatars/Stan.imageset/961BDD4A-6C6A-44A4-BE88-13B56FD03085.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/CellAvatars/Stan.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "961BDD4A-6C6A-44A4-BE88-13B56FD03085.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/CellAvatars/Sulian.imageset/650C8C65-EE7C-45ED-B550-06760DF79A8F.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/CellAvatars/Sulian.imageset/650C8C65-EE7C-45ED-B550-06760DF79A8F.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/CellAvatars/Sulian.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "650C8C65-EE7C-45ED-B550-06760DF79A8F.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/CellAvatars/morgan.imageset/98C1386A-F0A7-4D1C-B56D-3FDBEBF0FD3E.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/CellAvatars/morgan.imageset/98C1386A-F0A7-4D1C-B56D-3FDBEBF0FD3E.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/CellAvatars/morgan.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "98C1386A-F0A7-4D1C-B56D-3FDBEBF0FD3E.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/DeleteButtonIcon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "delete.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/DeleteButtonIcon.imageset/delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/DeleteButtonIcon.imageset/delete.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/DetailGroup/CommentIcon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "comment-wap.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/DetailGroup/CommentIcon.imageset/comment-wap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/DetailGroup/CommentIcon.imageset/comment-wap.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/DetailGroup/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/DetailGroup/FollowIcon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "eye.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/DetailGroup/FollowIcon.imageset/eye.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/DetailGroup/FollowIcon.imageset/eye.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/DetailGroup/LikeIcon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "like.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/DetailGroup/LikeIcon.imageset/like.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/DetailGroup/LikeIcon.imageset/like.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/PersonGroup/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/PersonGroup/DeleteIcon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "delete.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/PersonGroup/DeleteIcon.imageset/delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/PersonGroup/DeleteIcon.imageset/delete.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/PersonGroup/PersonImages/Animal.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "E43536DC-9DCC-491D-A6A5-23920A5C4DBF.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/PersonGroup/PersonImages/Animal.imageset/E43536DC-9DCC-491D-A6A5-23920A5C4DBF.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/PersonGroup/PersonImages/Animal.imageset/E43536DC-9DCC-491D-A6A5-23920A5C4DBF.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/PersonGroup/PersonImages/Castle.imageset/BFC1FA51-B0CE-4F58-8A3B-AD16A76D9033.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/PersonGroup/PersonImages/Castle.imageset/BFC1FA51-B0CE-4F58-8A3B-AD16A76D9033.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/PersonGroup/PersonImages/Castle.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "BFC1FA51-B0CE-4F58-8A3B-AD16A76D9033.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/PersonGroup/PersonImages/Chart.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "DBB662FF-0EFA-4C0D-A319-5788C1D824DD.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/PersonGroup/PersonImages/Chart.imageset/DBB662FF-0EFA-4C0D-A319-5788C1D824DD.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/PersonGroup/PersonImages/Chart.imageset/DBB662FF-0EFA-4C0D-A319-5788C1D824DD.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/PersonGroup/PersonImages/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/PersonGroup/PersonImages/PeaceMidNight.imageset/1FD89134-812A-4895-B231-C884EFAE9CF1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/PersonGroup/PersonImages/PeaceMidNight.imageset/1FD89134-812A-4895-B231-C884EFAE9CF1.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/PersonGroup/PersonImages/PeaceMidNight.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "1FD89134-812A-4895-B231-C884EFAE9CF1.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/PersonGroup/PersonImages/Signal.imageset/0F17F868-DE1A-476F-92FD-6820A51636B6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/PersonGroup/PersonImages/Signal.imageset/0F17F868-DE1A-476F-92FD-6820A51636B6.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/PersonGroup/PersonImages/Signal.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "0F17F868-DE1A-476F-92FD-6820A51636B6.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/PersonGroup/PersonImages/Sun.imageset/953E9AAF-4ECC-4C99-9B4A-AFC9DF1674FC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/PersonGroup/PersonImages/Sun.imageset/953E9AAF-4ECC-4C99-9B4A-AFC9DF1674FC.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/PersonGroup/PersonImages/Sun.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "953E9AAF-4ECC-4C99-9B4A-AFC9DF1674FC.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/PersonGroup/PersonImages/Web.imageset/266CBAFD-484F-44E1-8312-E282482A781F.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/PersonGroup/PersonImages/Web.imageset/266CBAFD-484F-44E1-8312-E282482A781F.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/PersonGroup/PersonImages/Web.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "266CBAFD-484F-44E1-8312-E282482A781F.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/PersonGroup/PersonRight.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "动物.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/PersonGroup/PersonRight.imageset/动物.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/PersonGroup/PersonRight.imageset/动物.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/PersonGroup/PersooLeft.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "动漫.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/PersonGroup/PersooLeft.imageset/动漫.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeGroup/PersonGroup/PersooLeft.imageset/动漫.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeMenu.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "menu.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeMenu.imageset/menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/HomeMenu.imageset/menu.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/LauncgSplashImage.imageset/BgImage@960x1136.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/LauncgSplashImage.imageset/BgImage@960x1136.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/LauncgSplashImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "BgImage@960x1136.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "extent" : "full-screen", 5 | "idiom" : "iphone", 6 | "subtype" : "736h", 7 | "filename" : "transparent@1242x2208-1副本.png", 8 | "minimum-system-version" : "8.0", 9 | "orientation" : "portrait", 10 | "scale" : "3x" 11 | }, 12 | { 13 | "orientation" : "landscape", 14 | "idiom" : "iphone", 15 | "extent" : "full-screen", 16 | "minimum-system-version" : "8.0", 17 | "subtype" : "736h", 18 | "scale" : "3x" 19 | }, 20 | { 21 | "extent" : "full-screen", 22 | "idiom" : "iphone", 23 | "subtype" : "667h", 24 | "filename" : "transparent@750x1334副本.png", 25 | "minimum-system-version" : "8.0", 26 | "orientation" : "portrait", 27 | "scale" : "2x" 28 | }, 29 | { 30 | "orientation" : "portrait", 31 | "idiom" : "iphone", 32 | "filename" : "transparent@640x960副本.png", 33 | "extent" : "full-screen", 34 | "minimum-system-version" : "7.0", 35 | "scale" : "2x" 36 | }, 37 | { 38 | "extent" : "full-screen", 39 | "idiom" : "iphone", 40 | "subtype" : "retina4", 41 | "filename" : "transparent@640x1136副本.png", 42 | "minimum-system-version" : "7.0", 43 | "orientation" : "portrait", 44 | "scale" : "2x" 45 | }, 46 | { 47 | "orientation" : "portrait", 48 | "idiom" : "iphone", 49 | "extent" : "full-screen", 50 | "scale" : "1x" 51 | }, 52 | { 53 | "orientation" : "portrait", 54 | "idiom" : "iphone", 55 | "extent" : "full-screen", 56 | "scale" : "2x" 57 | }, 58 | { 59 | "orientation" : "portrait", 60 | "idiom" : "iphone", 61 | "extent" : "full-screen", 62 | "subtype" : "retina4", 63 | "scale" : "2x" 64 | } 65 | ], 66 | "info" : { 67 | "version" : 1, 68 | "author" : "xcode" 69 | } 70 | } -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/LaunchImage.launchimage/transparent@1242x2208-1副本.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/LaunchImage.launchimage/transparent@1242x2208-1副本.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/LaunchImage.launchimage/transparent@640x1136副本.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/LaunchImage.launchimage/transparent@640x1136副本.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/LaunchImage.launchimage/transparent@640x960副本.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/LaunchImage.launchimage/transparent@640x960副本.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/LaunchImage.launchimage/transparent@750x1334副本.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/LaunchImage.launchimage/transparent@750x1334副本.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/PhotoAddButton.imageset/2x副本.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/PhotoAddButton.imageset/2x副本.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/PhotoAddButton.imageset/3x副本.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/PhotoAddButton.imageset/3x副本.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/PhotoAddButton.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "2x副本.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "3x副本.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/TapGroup/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/TapGroup/HomeSelect.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "home.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/TapGroup/HomeSelect.imageset/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/TapGroup/HomeSelect.imageset/home.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/TapGroup/HomeUnSelect.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "home (1).png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/TapGroup/HomeUnSelect.imageset/home (1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/TapGroup/HomeUnSelect.imageset/home (1).png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/TapGroup/MessageSelect.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "message.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/TapGroup/MessageSelect.imageset/message.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/TapGroup/MessageSelect.imageset/message.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/TapGroup/MessageUnSelect.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "message.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/TapGroup/MessageUnSelect.imageset/message.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/TapGroup/MessageUnSelect.imageset/message.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/TapGroup/SettingSelect.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "setting.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/TapGroup/SettingSelect.imageset/setting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/TapGroup/SettingSelect.imageset/setting.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/TapGroup/SettingUnSelect.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "setting.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/TapGroup/SettingUnSelect.imageset/setting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/TapGroup/SettingUnSelect.imageset/setting.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/WhiteCircleImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "circle.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Assets.xcassets/WhiteCircleImage.imageset/circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jashion/UIViewControllerTransitioningAnimation/6f0e26e4440563fb2ca33abaef054b40b520ffbe/TransitionAnimation/TransitionAnimation/Assets.xcassets/WhiteCircleImage.imageset/circle.png -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | zh_CN 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UIRequiredDeviceCapabilities 26 | 27 | armv7 28 | 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | 33 | UIViewControllerBasedStatusBarAppearance 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /TransitionAnimation/TransitionAnimation/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // TransitionAnimation 4 | // 5 | // Created by jashion on 16/5/4. 6 | // Copyright © 2016年 BMu. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /TransitionAnimation/UIImage+Tint.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Tint.h 3 | // TransitionAnimation 4 | // 5 | // Created by jashion on 16/5/14. 6 | // Copyright © 2016年 BMu. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIImage (Tint) 12 | 13 | - (UIImage *)imageWithTintColor: (UIColor *)tintColor blendMode: (CGBlendMode)mode; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /TransitionAnimation/UIImage+Tint.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Tint.m 3 | // TransitionAnimation 4 | // 5 | // Created by jashion on 16/5/14. 6 | // Copyright © 2016年 BMu. All rights reserved. 7 | // 8 | 9 | #import "UIImage+Tint.h" 10 | 11 | @implementation UIImage (Tint) 12 | 13 | - (UIImage *)imageWithTintColor: (UIColor *)tintColor blendMode: (CGBlendMode)mode { 14 | UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale); 15 | 16 | [tintColor setFill]; 17 | CGRect bounds = CGRectMake(0, 0, self.size.width, self.size.height); 18 | UIRectFill(bounds); 19 | 20 | [self drawInRect: bounds blendMode: mode alpha: 1.0]; 21 | UIImage *result = UIGraphicsGetImageFromCurrentImageContext(); 22 | UIGraphicsEndImageContext(); 23 | return result; 24 | } 25 | 26 | @end 27 | --------------------------------------------------------------------------------