Commit e5339aea authored by Sandy's avatar Sandy

修改baseUrl/适配iOS11

parent 036be141
This diff is collapsed.
......@@ -55,7 +55,7 @@
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:self.contract.uuid, @"contract", [NSDictionary dictionaryWithObjectsAndKeys:startDate, @"beginDate", endDate, @"endDate", nil], @"dateRange", nil];
[MBProgressHUD j_loading];
WS(weakSelf);
[ZJHttpManager POST:@"hdmall/salesinput/getSalesTotal" parameters:params complete:^(id responseObject, NSError *error) {
[ZJHttpManager POST:@"salesinput/getSalesTotal" parameters:params complete:^(id responseObject, NSError *error) {
[MBProgressHUD j_hideLoadingView];
if (kIsResponse) {
[weakSelf configDataArray:responseObject[@"data"]];
......
......@@ -62,7 +62,7 @@
self.viewModel.query.pageSize = @(self.pageSize);
WS(weakSelf);
[MBProgressHUD j_loading];
[ZJHttpManager POST:@"hdmall/salesinput/query" parameters:self.viewModel.query.toDictionary complete:^(id responseObject, NSError *error) {
[ZJHttpManager POST:@"salesinput/query" parameters:self.viewModel.query.toDictionary complete:^(id responseObject, NSError *error) {
[MBProgressHUD j_hideLoadingView];
if (kIsResponse) {
if (weakSelf.page == 1) {
......
......@@ -16,7 +16,7 @@
@param callBack 获取到支付方式的回调(如果arrPayments = nil, 则代表请求失败)
*/
- (void)httpAllPayments:(blockCallBack)callBack {
[ZJHttpManager GET:@"hdmall/salesinput/getAllPayments" parameters:nil complete:^(id responseObject, NSError *error) {
[ZJHttpManager GET:@"salesinput/getAllPayments" parameters:nil complete:^(id responseObject, NSError *error) {
if (kIsResponse) {
NSMutableArray *arrData = [HMSaleInputDetail_payments_payment modelsFromArray:responseObject[@"data"]];
......@@ -65,7 +65,7 @@
[ZJHttpManager upLoadFiles:arrImage params:nil commplete:^(NSMutableArray *attachments) {
self.request.mediaFiles = attachments;
[MBProgressHUD j_loading:@"提交中…"];
[ZJHttpManager POST:@"hdmall/salesinput/save" parameters:self.request.toDictionary complete:^(id responseObject, NSError *error) {
[ZJHttpManager POST:@"salesinput/save" parameters:self.request.toDictionary complete:^(id responseObject, NSError *error) {
if (kIsResponse) {
[MBProgressHUD j_hideLoadingView];
callBack(true);
......@@ -78,7 +78,7 @@
}
- (void)httpDetailWithUuid:(NSString *)uuid callBack:(blockCallBack)callBack {
NSString *url = [@"hdmall/salesinput/" stringByAppendingString:uuid];
NSString *url = [@"salesinput/" stringByAppendingString:uuid];
[ZJHttpManager GET:url parameters:nil complete:^(id responseObject, NSError *error) {
if (kIsResponse) {
......@@ -89,7 +89,7 @@
//附件列表
[self.picVM.arrPics removeAllObjects];
for (NSString *name in self.detail.mediaFiles) {
NSString *url = [NSString stringWithFormat:@"%@/hdmall/media/download?moduleName=sale&num=%@&fileName=%@",REST_BASE_URL, self.detail.billNumber, name];
NSString *url = [NSString stringWithFormat:@"%@/media/download?moduleName=sale&num=%@&fileName=%@",REST_BASE_URL, self.detail.billNumber, name];
ZJBaseFileModel *file = [ZJBaseFileModel new];
file.fileUrl = url;
[self.picVM.arrPics addObject:file];
......
......@@ -84,7 +84,7 @@
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:self.contract.uuid, @"contract", [NSDictionary dictionaryWithObjectsAndKeys:[self.textFieldDate.text stringByAppendingString:@" 00:00:00"], @"beginDate", [self.textFieldDate.text stringByAppendingString:@" 23:59:59"], @"endDate", nil], @"dateRange", nil];
[MBProgressHUD j_loading];
WS(weakSelf);
[ZJHttpManager POST:@"hdmall/salesinput/getSalesTotal" parameters:params complete:^(id responseObject, NSError *error) {
[ZJHttpManager POST:@"salesinput/getSalesTotal" parameters:params complete:^(id responseObject, NSError *error) {
[MBProgressHUD j_hideLoadingView];
if (kIsResponse) {
NSArray *data = responseObject[@"data"];
......
......@@ -12,8 +12,7 @@
@implementation LoginViewModel
- (void)login:(void (^)(id responseObject, NSError *error))complete {
WS(weakSelf);
[ZJHttpManager POST:@"hdmall/authenticates/authen" parameters:self.loginRequest.toDictionary complete:^(id responseObject, NSError *error) {
[ZJHttpManager POST:@"authenticates/authen" parameters:self.loginRequest.toDictionary complete:^(id responseObject, NSError *error) {
if (kIsResponse) {
AppGlobal.user = [UserInfo modelWithDic:responseObject[@"data"]];
......
......@@ -23,16 +23,17 @@ static NSString *const PGYER_APPID = @"";
static NSString *const VERSION_NAME = @"颐堤港测试版";
static NSString *const BASE_IP = @"http://210.12.159.69:8280";
//蒲公英appid
static NSString *const PGYER_APPID = @"";
static NSString *const PGYER_APPID = @"de74015c5fe97b3e746d8e8b463f7a05";
#else
static NSString *const VERSION_NAME = @" ";
static NSString *const BASE_IP = @"http://gomoredev.natapp4.cc";
static NSString *const PGYER_APPID = @"de74015c5fe97b3e746d8e8b463f7a05";
#endif
#define REST_BASE_URL [NSString stringWithFormat:@"%@/palmmall-server/rest", BASE_IP]
#define REST_BASE_URL [NSString stringWithFormat:@"%@/palmmall-server/rest/hdmall", BASE_IP]
//天气api
......
......@@ -8,9 +8,6 @@
#import "BaseViewController.h"
#import "UINavigationController+XWTransition.h"
#import "UIViewController+XWTransition.h"
#import "XWCircleSpreadAnimator.h"
#import "UIScrollView+EmptyDataSet.h"
@interface BaseListViewController : BaseViewController<UITableViewDelegate, UITableViewDataSource, DZNEmptyDataSetSource, DZNEmptyDataSetDelegate>
@property (weak, nonatomic) IBOutlet UITableView *tableView;
......
......@@ -139,9 +139,7 @@
VC.commplete = ^{
[weakSelf.tableView.mj_header beginRefreshing];
};
CGPoint point = self.btnAdd.center;
XWCircleSpreadAnimator *animator = [XWCircleSpreadAnimator xw_animatorWithStartCenter:point radius:30];
[self.navigationController xw_pushViewController:VC withAnimator:animator];
[self.navigationController pushViewController:VC animated:YES];
}
- (void)listTableViewReloadData {
......
//
// UINavigationController+XWTransition.h
// XWTADemo
//
// Created by wazrx on 16/6/7.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import <UIKit/UIKit.h>
@class XWTransitionAnimator;
@interface UINavigationController (XWTransition)
/**
* 通过指定的转场animator来push控制器,达到不同的转场效果
*
* @param viewController 被push的控制器
* @param animator 转场Animator
*/
- (void)xw_pushViewController:(UIViewController *)viewController withAnimator:(XWTransitionAnimator *)animator;
@end
//
// UINavigationController+XWTransition.m
// XWTADemo
//
// Created by wazrx on 16/6/7.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "UINavigationController+XWTransition.h"
#import "UIViewController+XWTransition.h"
#import "XWTransitionAnimator.h"
#import <objc/runtime.h>
#import <objc/message.h>
@implementation UINavigationController (XWTransition)
+ (void)load{
method_exchangeImplementations(class_getInstanceMethod([self class], @selector(pushViewController:animated:)), class_getInstanceMethod([self class], @selector(_xw_pushViewController:animated:)));
}
- (void)xw_pushViewController:(UIViewController *)viewController withAnimator:(XWTransitionAnimator *)animator {
if (!viewController) return;
XWInteractiveTransition *toInteractive = objc_getAssociatedObject(self.topViewController, &kXWToInteractiveKey);
if (toInteractive) {
[animator setValue:toInteractive forKey:@"toInteractive"];
}
if (animator) {
objc_setAssociatedObject(viewController, &kXWAnimatorKey, animator, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
[self pushViewController:viewController animated:YES];
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[self _xw_swizzeViewControlelrDealloc];
});
}
- (void)_xw_swizzeViewControlelrDealloc{
Class swizzleClass = [UIViewController class];
@synchronized(swizzleClass) {
SEL deallocSelector = sel_registerName("dealloc");
__block void (*originalDealloc)(__unsafe_unretained id, SEL) = NULL;
__weak typeof(self)weakSelf = self;
id newDealloc = ^(__unsafe_unretained UIViewController *objSelf){
[weakSelf _xw_checkDelegate];
if (originalDealloc == NULL) {
struct objc_super superInfo = {
.receiver = objSelf,
.super_class = class_getSuperclass(swizzleClass)
};
void (*msgSend)(struct objc_super *, SEL) = (__typeof__(msgSend))objc_msgSendSuper;
msgSend(&superInfo, deallocSelector);
}else{
originalDealloc(objSelf, deallocSelector);
}
};
IMP newDeallocIMP = imp_implementationWithBlock(newDealloc);
if (!class_addMethod(swizzleClass, deallocSelector, newDeallocIMP, "v@:")) {
Method deallocMethod = class_getInstanceMethod(swizzleClass, deallocSelector);
originalDealloc = (void(*)(__unsafe_unretained id, SEL))method_getImplementation(deallocMethod);
originalDealloc = (void(*)(__unsafe_unretained id, SEL))method_setImplementation(deallocMethod, newDeallocIMP);
}
}
}
- (void)_xw_checkDelegate{
XWTransitionAnimator *animator = objc_getAssociatedObject(self.topViewController, &kXWAnimatorKey);
if (animator) {
self.delegate = animator;
}else{
self.delegate = nil;
}
}
- (void)_xw_pushViewController:(UIViewController *)viewController animated:(BOOL)animated{
XWTransitionAnimator *animator = objc_getAssociatedObject(viewController, &kXWAnimatorKey);
if (animator) {
self.delegate = animator;
}else if([self.delegate isKindOfClass:[XWTransitionAnimator class]]){
self.delegate = nil;
}
[self _xw_pushViewController:viewController animated:animated];
}
@end
//
// UIView+Snapshot.h
// XWTransitionDemo
//
// Created by 肖文 on 2016/12/16.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface UIView (Snapshot)
@property (nonatomic, readonly) UIImage *snapshotImage;
@property (nonatomic, strong) UIImage *contentImage;
@end
//
// UIView+Snapshot.m
// XWTransitionDemo
//
// Created by 肖文 on 2016/12/16.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "UIView+Snapshot.h"
@implementation UIView (Snapshot)
- (UIImage *)snapshotImage {
UIGraphicsBeginImageContextWithOptions(self.bounds.size, self.opaque, 0);
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *snap = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return snap;
}
- (UIImage *)contentImage{
return [UIImage imageWithCGImage:(__bridge CGImageRef)self.layer.contents];
}
- (void)setContentImage:(UIImage *)contentImage{
self.layer.contents = (__bridge id)contentImage.CGImage;;
}
@end
//
// UIViewController+XWTransition.h
// XWTADemo
//
// Created by wazrx on 16/6/7.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "XWTransitionAnimator.h"
NS_ASSUME_NONNULL_BEGIN
@interface UIViewController (XWTransition)
/**
* 通过指定的转场animator来present控制器
*
* @param viewController 被modal出的控制器
* @param animator 转场animator
*/
- (void)xw_presentViewController:(UIViewController *)viewController withAnimator:(XWTransitionAnimator *)animator;
#pragma mark - 神奇移动相关
/**
* 注册神奇移动起始视图
*
* @param group 神奇移动起始视图数组
*/
- (void)xw_addMagicMoveStartViewGroup:(NSArray<UIView *> *)group;
/**
* 注册神奇移动终止视图
*
* @param group 神奇移动终止视图数组,注意起始视图数组和终止视图数组的视图需要一一对应才能有正确的效果
*/
- (void)xw_addMagicMoveEndViewGroup:(NSArray<UIView *> *)group;
/**
* 改变神奇移动起始视图,因为在back的时候,有可能不需要再回到原来起始的位置,需要去一个新的视图位置,所以在back前需要调用该方法改变起始视图数组
*
* @param group 新的起始视图数组
*/
- (void)xw_changeMagicMoveStartViewGroup:(NSArray<UIView *> *)group;
#pragma mark - 手势相关
/**
* 注册to手势(push或者Present手势),block中的startPoint为手势开始时手指所在的点,在有些特殊需求的时候,你可能需要它
*
* @param direction 手势方向
* @param tansitionConfig 手势触发的block,block中需要包含你的push或者Present的逻辑代码,注意避免循环引用问题
* @param edgeSpacing 手势触发的边缘距离,该值为0,表示在整个控制器视图上都有效,否者这在边缘的edgeSpacing之类有效
*/
- (void)xw_registerToInteractiveTransitionWithDirection:(XWInteractiveTransitionGestureDirection)direction transitonBlock:(void(^)(CGPoint startPoint))tansitionConfig edgeSpacing:(CGFloat)edgeSpacing;
/**
* 注册back手势(pop或者dismiss手势)
*
* @param direction 手势方向
* @param tansitionConfig 手势触发的block,block中需要包含你的pop或者dismiss的逻辑代码,注意避免循环引用问题
* @param edgeSpacing 手势触发的边缘距离,该值为0,表示在整个控制器视图上都有效,否者这在边缘的edgeSpacing之类有效
*/
- (void)xw_registerBackInteractiveTransitionWithDirection:(XWInteractiveTransitionGestureDirection)direction transitonBlock:(void(^)(CGPoint startPoint))tansitionConfig edgeSpacing:(CGFloat)edgeSpacing;
@end
UIKIT_EXTERN NSString *const kXWToInteractiveKey;
UIKIT_EXTERN NSString *const kXWAnimatorKey;
NS_ASSUME_NONNULL_END
//
// UIViewController+XWTransition.m
// XWTADemo
//
// Created by wazrx on 16/6/7.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "UIViewController+XWTransition.h"
#import "XWMagicMoveAnimator.h"
#import <objc/runtime.h>
@implementation UIViewController (XWTransition)
- (void)xw_registerToInteractiveTransitionWithDirection:(XWInteractiveTransitionGestureDirection)direction transitonBlock:(void(^)(CGPoint startPoint))tansitionConfig edgeSpacing:(CGFloat)edgeSpacing{
if (!tansitionConfig) return;
XWInteractiveTransition *interactive = [XWInteractiveTransition xw_interactiveTransitionWithDirection:direction config:tansitionConfig edgeSpacing:edgeSpacing];
[interactive xw_addPanGestureForView:self.view to:YES];
objc_setAssociatedObject(self, &kXWToInteractiveKey, interactive, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (void)xw_registerBackInteractiveTransitionWithDirection:(XWInteractiveTransitionGestureDirection)direction transitonBlock:(void(^)(CGPoint startPoint))tansitionConfig edgeSpacing:(CGFloat)edgeSpacing{
if (!tansitionConfig) return;
XWInteractiveTransition *interactive = [XWInteractiveTransition xw_interactiveTransitionWithDirection:direction config:tansitionConfig edgeSpacing:edgeSpacing];
[interactive xw_addPanGestureForView:self.view to:NO];
XWTransitionAnimator *animator = objc_getAssociatedObject(self, &kXWAnimatorKey);if (animator) {
[animator setValue:interactive forKey:@"backInteractive"];
}
}
- (void)xw_presentViewController:(UIViewController *)viewController withAnimator:(XWTransitionAnimator *)animator {
if (!viewController) return;
if (!animator) animator = [XWTransitionAnimator new];
viewController.transitioningDelegate = animator;
XWInteractiveTransition *toInteractive = objc_getAssociatedObject(self, &kXWToInteractiveKey);
if (toInteractive) {
[animator setValue:toInteractive forKey:@"toInteractive"];
}
objc_setAssociatedObject(viewController, &kXWAnimatorKey, animator, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
[self presentViewController:viewController animated:YES completion:nil];
}
- (void)xw_addMagicMoveStartViewGroup:(NSArray<UIView *> *)group {
if (!group.count) return;
objc_setAssociatedObject(self, &kXWMagicMoveAnimatorStartViewVCKey, group, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (void)xw_addMagicMoveEndViewGroup:(NSArray<UIView *> *)group {
if (!group.count) return;
objc_setAssociatedObject(self, &kXWMagicMoveAnimatorEndViewVCKey, group, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (void)xw_changeMagicMoveStartViewGroup:(NSArray<UIView *> *)group {
[self xw_addMagicMoveStartViewGroup:group];
}
@end
NSString *const kXWToInteractiveKey = @"kXWToInteractiveKey";
NSString *const kXWAnimatorKey = @"kXWAnimatorKey";
//
// XWInteractiveTransition.h
// XWTransitionDemo
//
// Created by wazrx on 16/6/10.
// Copyright © 2016年 wazrx. All rights reserved.
// 手势转场管理者
// 注意:使用UIViewController+XWTransition相关API配合animator,通常情况下无需自己创建手势过渡管理者
#import <UIKit/UIKit.h>
@class XWInteractiveTransition;
NS_ASSUME_NONNULL_BEGIN
/**手势转场时的代理事件,animator默认为为其手势的代理,复写对应的代理事件可处理一些手势失败闪烁的情况*/
@protocol XWInteractiveTransitionDelegate <NSObject>
@optional
/**手势转场即将开始时调用*/
- (void)xw_interactiveTransitionWillBegin:(XWInteractiveTransition *)interactiveTransition;
/**手势转场中调用*/
- (void)xw_interactiveTransition:(XWInteractiveTransition *)interactiveTransition isUpdating:(CGFloat)percent;
/**如果开始了转场手势timer,会在松开手指,timer开始的时候调用*/
- (void)xw_interactiveTransitionWillBeginTimerAnimation:(XWInteractiveTransition *)interactiveTransition;
/**手势转场结束的时候调用*/
- (void)xw_interactiveTransition:(XWInteractiveTransition *)interactiveTransition willEndWithSuccessFlag:(BOOL)flag percent:(CGFloat)percent;
@end
/**手势转场方向*/
typedef NS_ENUM(NSUInteger, XWInteractiveTransitionGestureDirection) {
XWInteractiveTransitionGestureDirectionLeft = 0,
XWInteractiveTransitionGestureDirectionRight,
XWInteractiveTransitionGestureDirectionUp,
XWInteractiveTransitionGestureDirectionDown
};
@interface XWInteractiveTransition : UIPercentDrivenInteractiveTransition
@property (nonatomic, assign, readonly) BOOL interation;
@property (nonatomic, assign) BOOL timerEable;
@property (nonatomic, weak) id<XWInteractiveTransitionDelegate> delegate;
/**设置该值可改变计算手势百分比的基准,手势基准的原理:百分比 = 拖动距离 / panRatioBaseValue, 默认情况下水平方向panRatioBaseValue为手势所在view的宽度,垂直方向为手势所在view的高度,通常无需更改该值,在某些特殊情况下,如果想要调整手势的速率可以更改该值,比如让手势速率加倍,可以调整该值为view宽度高度的一半*/
@property (nonatomic, assign) CGFloat panRatioBaseValue;
+ (instancetype)xw_interactiveTransitionWithDirection:(XWInteractiveTransitionGestureDirection)direction config:(void(^)(CGPoint startPoint))config edgeSpacing:(CGFloat)edgeSpacing;
- (void)xw_addPanGestureForView:(UIView *)view to:(BOOL)flag;
@end
NS_ASSUME_NONNULL_END
\ No newline at end of file
//
// XWInteractiveTransition.m
// XWTransitionDemo
//
// Created by wazrx on 16/6/10.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "XWInteractiveTransition.h"
#import <objc/runtime.h>
typedef struct {
unsigned int willBegin : 1;
unsigned int isUpdating : 1;
unsigned int willBeginTimer : 1;
unsigned int willEnd : 1;
} delegateFlag;
@interface XWInteractiveTransition ()<UIGestureRecognizerDelegate>
@property (nonatomic, assign) XWInteractiveTransitionGestureDirection direction;
@property (nonatomic, copy) void(^config)(CGPoint startPoint);
@property (nonatomic, strong) CADisplayLink *timer;
@property (nonatomic, assign) CGFloat percent;
@property (nonatomic, assign) CGFloat timeDis;
@property (nonatomic, assign) delegateFlag delegateFlag;
@property (nonatomic, assign) BOOL vertical;
@property (nonatomic, assign) CGFloat edgeSpacing;
@end
@implementation XWInteractiveTransition
+ (instancetype)xw_interactiveTransitionWithDirection:(XWInteractiveTransitionGestureDirection)direction config:(void(^)(CGPoint startPoint))config edgeSpacing:(CGFloat)edgeSpacing{
return [[self alloc] _initInteractiveTransitionWithDirection:direction config:config edgeSpacing:edgeSpacing];
}
- (instancetype)_initInteractiveTransitionWithDirection:(XWInteractiveTransitionGestureDirection)direction config:(void(^)(CGPoint startPoint))config edgeSpacing:(CGFloat)edgeSpacing{
self = [super init];
if (self) {
_config = config;
_direction = direction;
_edgeSpacing = edgeSpacing;
_vertical = direction == XWInteractiveTransitionGestureDirectionDown || direction == XWInteractiveTransitionGestureDirectionUp;
}
return self;
}
- (void)setDelegate:(id<XWInteractiveTransitionDelegate>)delegate{
_delegate = delegate;
_delegateFlag.willBegin = _delegate && [_delegate respondsToSelector:@selector(xw_interactiveTransitionWillBegin:)];
_delegateFlag.isUpdating = _delegate && [_delegate respondsToSelector:@selector(xw_interactiveTransition:isUpdating:)];
_delegateFlag.willBeginTimer = _delegate && [_delegate respondsToSelector:@selector(xw_interactiveTransitionWillBeginTimerAnimation:)];
_delegateFlag.willEnd = _delegate && [_delegate respondsToSelector:@selector(xw_interactiveTransition:willEndWithSuccessFlag:percent:)];
}
- (void)xw_addPanGestureForView:(UIView *)view to:(BOOL)flag{
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(_xw_handleGesture:)];
//为drawerAnimator记录pan手势
pan.delegate = self;
NSString * panType = flag ? @"xw_interactiveToPan" : @"xw_interactiveBackPan";
objc_setAssociatedObject(pan, "xw_interactivePanKey", panType, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
[view addGestureRecognizer:pan];
}
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{
if (_edgeSpacing <= 0) {
return YES;
}
CGPoint point = [gestureRecognizer locationInView:gestureRecognizer.view];
BOOL should = NO;
switch (_direction) {
case XWInteractiveTransitionGestureDirectionLeft: {
should = point.x >= gestureRecognizer.view.frame.size.width - _edgeSpacing;
break;
}
case XWInteractiveTransitionGestureDirectionRight: {
should = point.x <= _edgeSpacing;
break;
}
case XWInteractiveTransitionGestureDirectionUp: {
should = point.y >= gestureRecognizer.view.frame.size.height - _edgeSpacing;
break;
}
case XWInteractiveTransitionGestureDirectionDown: {
should = point.y <= _edgeSpacing;
break;
}
}
return should;
}
/**
* 手势过渡的过程
*/
- (void)_xw_handleGesture:(UIPanGestureRecognizer *)panGesture{
switch (panGesture.state) {
case UIGestureRecognizerStateBegan:
if (_delegateFlag.willBegin) {
[_delegate xw_interactiveTransitionWillBegin:self];
}
CGPoint startPoint = [panGesture locationInView:panGesture.view];
_interation = YES;
if (_config) {
_config(startPoint);
}
[self _xw_caculateMovePercentForGesture:panGesture];
break;
case UIGestureRecognizerStateChanged:{
[self _xw_caculateMovePercentForGesture:panGesture];
[self _xw_updatingWithPercent:_percent];
break;
}
case UIGestureRecognizerStateEnded:{
//判断是否需要timer
if (!_timerEable) {
_percent >= 0.5 ? [self _xw_finish] : [self _xw_cancle];
return;
}
//判断此时是否已经转场完成,大于1或者小于0
BOOL canEnd = [self _xw_canEndInteractiveTransitionWithPercent:_percent];
if (canEnd) return;
//开启timer
[self _xw_setEndAnimationTimerWithPercent:_percent];
break;
}
default:
break;
}
}
- (BOOL)_xw_canEndInteractiveTransitionWithPercent:(CGFloat)percent{
BOOL can = NO;
if (percent >= 1) {
[self _xw_finish];
can = YES;
}
if (percent <= 0) {
[self _xw_cancle];
can = YES;
}
return can;
}
- (void)_xw_caculateMovePercentForGesture:(UIPanGestureRecognizer *)panGesture{
static CGFloat baseValue = 0.0f;
baseValue = _panRatioBaseValue > 0 ? _panRatioBaseValue : _vertical ? panGesture.view.frame.size.height : panGesture.view.frame.size.width;
//手势百分比
switch (_direction) {
case XWInteractiveTransitionGestureDirectionLeft:{
CGFloat transitionX = -[panGesture translationInView:panGesture.view].x;
_percent += transitionX / baseValue;
}
break;
case XWInteractiveTransitionGestureDirectionRight:{
CGFloat transitionX = [panGesture translationInView:panGesture.view].x;
_percent += transitionX / baseValue;
}
break;
case XWInteractiveTransitionGestureDirectionUp:{
CGFloat transitionY = -[panGesture translationInView:panGesture.view].y;
_percent += transitionY / baseValue;
}
break;
case XWInteractiveTransitionGestureDirectionDown:{
CGFloat transitionY = [panGesture translationInView:panGesture.view].y;
_percent += transitionY / baseValue;
}
break;
}
[panGesture setTranslation:CGPointZero inView:panGesture.view];
}
//设置开启timer
- (void)_xw_setEndAnimationTimerWithPercent:(CGFloat)percent{
_percent = percent;
//根据失败还是成功设置刷新间隔
if (percent > 0.5) {
_timeDis = (1 - percent) / ((1 - percent) * 60);
}else{
_timeDis = percent / (percent * 60);
}
if (_delegateFlag.willBeginTimer) {
[_delegate xw_interactiveTransitionWillBeginTimerAnimation:self];
}
//开启timer
[self _xw_startTimer];
}
- (void)_xw_finish{
if (_delegateFlag.willEnd) {
[_delegate xw_interactiveTransition:self willEndWithSuccessFlag:YES percent:_percent];
}
[self finishInteractiveTransition];
_percent = 0.0f;
_interation = NO;
}
- (void)_xw_cancle{
if (_delegateFlag.willEnd) {
[_delegate xw_interactiveTransition:self willEndWithSuccessFlag:NO percent:_percent];
}
[self cancelInteractiveTransition];
_percent = 0.0f;
_interation = NO;
}
- (void)_xw_updatingWithPercent:(CGFloat)percent{
[self updateInteractiveTransition:percent];
if (_delegateFlag.isUpdating) {
[_delegate xw_interactiveTransition:self isUpdating:_percent];
}
}
- (void)_xw_startTimer{
if (_timer) {
return;
}
_timer = [CADisplayLink displayLinkWithTarget:self selector:@selector(_xw_timerEvent)];
[_timer addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
}
- (void)_xw_stopTimer{
if (!_timer) {
return;
}
[_timer invalidate];
_timer = nil;
}
//timer 事件
- (void)_xw_timerEvent{
if (_percent > 0.5) {
_percent += _timeDis;
}else{
_percent -= _timeDis;
}
//通过timer不断刷新转场进度
[self _xw_updatingWithPercent:_percent];
BOOL canEnd = [self _xw_canEndInteractiveTransitionWithPercent:_percent];
if (canEnd) {
[self _xw_stopTimer];
}
}
@end
//
// XWTransitionAnimator.h
// XWTADemo
//
// Created by wazrx on 16/6/7.
// Copyright © 2016年 wazrx. All rights reserved.
// 所有转场效果器的基类,若要自定义请继承与该基类
#import <UIKit/UIKit.h>
#import "XWInteractiveTransition.h"
NS_ASSUME_NONNULL_BEGIN
@interface XWTransitionAnimator : NSObject<UIViewControllerTransitioningDelegate, UINavigationControllerDelegate, UITabBarControllerDelegate, XWInteractiveTransitionDelegate>
//to转场时间 默认0.5
@property (nonatomic, assign) NSTimeInterval toDuration;
//back转场时间 默认0.5
@property (nonatomic, assign) NSTimeInterval backDuration;
//是否需要开启手势timer,某些转场如果在转成过程中所开手指,不会有动画过渡,显得很生硬,开启timer后,松开手指,会用timer不断的刷新转场百分比,消除生硬的缺点
@property (nonatomic, assign) BOOL needInteractiveTimer;
/**
* 配置To过程动画(push, present),自定义转场动画应该复写该方法
*/
- (void)xw_setToAnimation:(id<UIViewControllerContextTransitioning>)transitionContext;
/**
* 配置back过程动画(pop, dismiss),自定义转场动画应该复写该方法
*/
- (void)xw_setBackAnimation:(id<UIViewControllerContextTransitioning>)transitionContext;
@end
NS_ASSUME_NONNULL_END
\ No newline at end of file
//
// XWTransitionAnimator.m
// XWTADemo
//
// Created by wazrx on 16/6/7.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "XWTransitionAnimator.h"
#import <objc/runtime.h>
#import <objc/message.h>
#pragma mark - 私有转场动画管理者
typedef void(^XWTransitionAnimationConfig)(id<UIViewControllerContextTransitioning> transitionContext);
@interface _XWTransitionObject : NSObject<UIViewControllerAnimatedTransitioning>
- (instancetype)_initObjectWithDuration:(NSTimeInterval)duration animationBlock:(void(^)(id<UIViewControllerContextTransitioning> transitionContext)) config;
@end
@implementation _XWTransitionObject{
NSTimeInterval _duration;
XWTransitionAnimationConfig _config;
}
- (instancetype)_initObjectWithDuration:(NSTimeInterval)duration animationBlock:(XWTransitionAnimationConfig)config{
self = [super init];
if (self) {
_duration = duration;
_config = config;
}
return self;
}
#pragma mark - <UIViewControllerAnimatedTransitioning>
- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext{
return _duration;
}
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext{
if (_config) {
_config(transitionContext);
}
}
@end
@interface XWTransitionAnimator ()
@property (nonatomic, strong) _XWTransitionObject *toTransition;
@property (nonatomic, strong) _XWTransitionObject *backTranstion;
@property (nonatomic, strong) XWInteractiveTransition *toInteractive;
@property (nonatomic, strong) XWInteractiveTransition *backInteractive;
@property (nonatomic, assign) UINavigationControllerOperation operation;
@property (nonatomic, assign) BOOL toType;
@end
@implementation XWTransitionAnimator
- (instancetype)init
{
self = [super init];
if (self) {
_toDuration = _backDuration = 0.5f;
}
return self;
}
- (_XWTransitionObject *)toTransition{
if (!_toTransition) {
__weak typeof(self)weakSelf = self;
_toTransition = [[_XWTransitionObject alloc] _initObjectWithDuration:_toDuration animationBlock:^(id<UIViewControllerContextTransitioning> transitionContext) {
[weakSelf xw_setToAnimation:transitionContext];
}];
}
return _toTransition;
}
- (_XWTransitionObject *)backTranstion{
if (!_backTranstion) {
__weak typeof(self)weakSelf = self;
_backTranstion = [[_XWTransitionObject alloc] _initObjectWithDuration:_backDuration animationBlock:^(id<UIViewControllerContextTransitioning> transitionContext) {
[weakSelf xw_setBackAnimation:transitionContext];
}];
}
return _backTranstion;
}
- (void)setToInteractive:(XWInteractiveTransition *)toInteractive{
_toInteractive = toInteractive;
toInteractive.delegate = self;
toInteractive.timerEable = _needInteractiveTimer;
}
- (void)setBackInteractive:(XWInteractiveTransition *)backInteractive{
_backInteractive = backInteractive;
backInteractive.delegate = self;
backInteractive.timerEable = _needInteractiveTimer;
}
- (void)xw_setToAnimation:(id<UIViewControllerContextTransitioning>)transitionContext{
//交给子类实现
}
- (void)xw_setBackAnimation:(id<UIViewControllerContextTransitioning>)transitionContext{
//交给子类实现
}
#pragma mark - <UIViewControllerTransitioningDelegate>
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source{
return self.toTransition;
}
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed{
return self.backTranstion;
}
- (id<UIViewControllerInteractiveTransitioning>)interactionControllerForDismissal:(id<UIViewControllerAnimatedTransitioning>)animator{
return self.backInteractive.interation ? self.backInteractive : nil;
}
- (id<UIViewControllerInteractiveTransitioning>)interactionControllerForPresentation:(id<UIViewControllerAnimatedTransitioning>)animator{
return self.toInteractive.interation ? self.toInteractive : nil;
}
#pragma mark - <UINavigationControllerDelegate>
- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC{
_operation = operation;
return operation == UINavigationControllerOperationPush ? self.toTransition : self.backTranstion;
}
- (id<UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController interactionControllerForAnimationController:(id<UIViewControllerAnimatedTransitioning>)animationController{
XWInteractiveTransition *inter = _operation == UINavigationControllerOperationPush ? self.toInteractive : self.backInteractive;
return inter.interation ? inter : nil;
}
@end
//
// XWCircleSpreadAnimator.h
// XWTADemo
//
// Created by wazrx on 16/6/7.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "XWTransitionAnimator.h"
NS_ASSUME_NONNULL_BEGIN
@interface XWCircleSpreadAnimator : XWTransitionAnimator
/**
* 返回一个小圆点扩散转场效果器
*
* @param point 扩散开始中心
* @param radius 扩散开始的半径
*
* @return 小圆点扩散转场效果器
*/
+ (instancetype)xw_animatorWithStartCenter:(CGPoint)point radius:(CGFloat)radius;
@end
NS_ASSUME_NONNULL_END
\ No newline at end of file
//
// XWCircleSpreadAnimator.m
// XWTADemo
//
// Created by wazrx on 16/6/7.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "XWCircleSpreadAnimator.h"
@interface XWCircleSpreadAnimator ()<CAAnimationDelegate>
@property (nonatomic, assign) CGPoint startPoint;
@property (nonatomic, assign) CGFloat startRadius;
@property (nonatomic, strong) UIBezierPath *startPath;
@property (nonatomic, strong) UIView *containerView;
@property (nonatomic, strong) CAShapeLayer *maskLayer;
@end
@implementation XWCircleSpreadAnimator
+ (instancetype)xw_animatorWithStartCenter:(CGPoint)point radius:(CGFloat)radius {
return [[self alloc] _initWithStartCenter:point radius:radius];
}
- (instancetype)_initWithStartCenter:(CGPoint)point radius:(CGFloat)radius
{
self = [super init];
if (self) {
_startPoint = point;
_startRadius = radius == 0 ? 0.01 : radius;
self.needInteractiveTimer = YES;
}
return self;
}
- (void)xw_setToAnimation:(id<UIViewControllerContextTransitioning>)transitionContext{
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIView *containerView = [transitionContext containerView];
toVC.view.top = 64;
toVC.view.height = toVC.view.height - 64;
[containerView addSubview:toVC.view];
UIBezierPath *startCycle = [UIBezierPath bezierPathWithArcCenter:self.startPoint radius:self.startRadius startAngle:0 endAngle:M_PI * 2 clockwise:YES];
CGFloat x = self.startPoint.x;
CGFloat y = self.startPoint.y;
CGFloat endX = MAX(x, containerView.frame.size.width - x);
CGFloat endY = MAX(y, containerView.frame.size.height - y);
CGFloat radius = sqrtf(pow(endX, 2) + pow(endY, 2));
UIBezierPath *endCycle = [UIBezierPath bezierPathWithArcCenter:self.startPoint radius:radius startAngle:0 endAngle:M_PI * 2 clockwise:YES];
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.path = endCycle.CGPath;
toVC.view.layer.mask = maskLayer;
self.startPath = startCycle;
self.maskLayer = maskLayer;
self.containerView = containerView;
CABasicAnimation *maskLayerAnimation = [CABasicAnimation animationWithKeyPath:@"path"];
maskLayerAnimation.fromValue = (__bridge id)(startCycle.CGPath);
maskLayerAnimation.toValue = (__bridge id)((endCycle.CGPath));
maskLayerAnimation.duration = self.toDuration;
maskLayerAnimation.delegate = self;
[maskLayerAnimation setValue:transitionContext forKey:@"transitionContext"];
[maskLayer addAnimation:maskLayerAnimation forKey:@"xw_path"];
}
- (void)xw_setBackAnimation:(id<UIViewControllerContextTransitioning>)transitionContext{
UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIView *containerView = [transitionContext containerView];
[containerView insertSubview:toVC.view atIndex:0];
UIBezierPath *endCycle = [UIBezierPath bezierPathWithArcCenter:self.startPoint radius:self.startRadius startAngle:0 endAngle:M_PI * 2 clockwise:YES];
CAShapeLayer *maskLayer = (CAShapeLayer *)fromVC.view.layer.mask;
CGPathRef startPath = maskLayer.path;
maskLayer.path = endCycle.CGPath;
self.maskLayer = maskLayer;
self.startPath = [UIBezierPath bezierPathWithCGPath:startPath];
self.containerView = containerView;
CABasicAnimation *maskLayerAnimation = [CABasicAnimation animationWithKeyPath:@"path"];
maskLayerAnimation.fromValue = (__bridge id)(startPath);
maskLayerAnimation.toValue = (__bridge id)(endCycle.CGPath);
maskLayerAnimation.duration = self.backDuration;
maskLayerAnimation.delegate = self;
[maskLayerAnimation setValue:transitionContext forKey:@"transitionContext"];
[maskLayer addAnimation:maskLayerAnimation forKey:@"xw_path"];
}
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
id<UIViewControllerContextTransitioning> transitionContext = [anim valueForKey:@"transitionContext"];
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}
- (void)xw_interactiveTransitionWillBeginTimerAnimation:(XWInteractiveTransition *)interactiveTransition{
_containerView.userInteractionEnabled = NO;
}
- (void)xw_interactiveTransition:(XWInteractiveTransition *)interactiveTransition willEndWithSuccessFlag:(BOOL)flag percent:(CGFloat)percent{
if (!flag) {
//防止失败后的闪烁
_maskLayer.path = _startPath.CGPath;
}
_containerView.userInteractionEnabled = YES;
}
@end
//
// XWCoolAnimator+XWExplode.h
// XWTransitionDemo
//
// Created by wazrx on 16/6/14.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "XWCoolAnimator.h"
@interface XWCoolAnimator (XWExplode)
- (void)xw_setExplodeToAnimation:(id<UIViewControllerContextTransitioning>)transitionContext;
- (void)xw_setExplodeBackAnimation:(id<UIViewControllerContextTransitioning>)transitionContext;
@end
//
// XWCoolAnimator+XWExplode.m
// XWTransitionDemo
//
// Created by wazrx on 16/6/14.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "XWCoolAnimator+XWExplode.h"
#import "UIView+Snapshot.h"
@implementation XWCoolAnimator (XWExplode)
- (void)xw_setExplodeToAnimation:(id<UIViewControllerContextTransitioning>)transitionContext {
[self _xw_animation:transitionContext duration:self.toDuration];
}
- (void)xw_setExplodeBackAnimation:(id<UIViewControllerContextTransitioning>)transitionContext {
[self _xw_animation:transitionContext duration:self.backDuration];
}
- (void)_xw_animation:(id<UIViewControllerContextTransitioning>)transitionContext duration:(NSTimeInterval)duration{
UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIView *toView = toVC.view;
UIView *fromView = fromVC.view;
UIView *containerView = [transitionContext containerView];
[containerView insertSubview:toView atIndex:0];
CGSize size = toView.frame.size;
NSMutableArray *snapshots = [NSMutableArray new];
CGFloat xNum = 10.0f;
CGFloat yNum = xNum * size.height / size.width;
UIView *fromViewSnapshot = [UIView new];
UIImage *fromImage = fromVC.view.snapshotImage;
fromViewSnapshot.contentImage = fromImage;
CGFloat fromWidth = fromVC.view.bounds.size.width;
CGFloat fromHeight = fromVC.view.bounds.size.height;
for (CGFloat x=0; x < size.width; x+= size.width / xNum) {
for (CGFloat y=0; y < size.height; y+= size.height / yNum) {
CGRect snapshotRegion = CGRectMake(x, y, size.width / xNum, size.height / yNum);
UIView *snapshot = [UIView new];
snapshot.contentImage = fromImage;
CGRect contentRect = CGRectMake(x / fromWidth, y / fromHeight, size.width / xNum / fromWidth, size.height / yNum / fromHeight);
snapshot.layer.contentsRect = contentRect;
snapshot.frame = snapshotRegion;
[containerView addSubview:snapshot];
[snapshots addObject:snapshot];
}
}
fromView.hidden = YES;
[UIView animateWithDuration:duration animations:^{
for (UIView *view in snapshots) {
CGFloat xOffset = [self _xw_randomFloatBetween:-100.0 and:100.0];
CGFloat yOffset = [self _xw_randomFloatBetween:-100.0 and:100.0];
view.frame = CGRectOffset(view.frame, xOffset, yOffset);
view.alpha = 0.0;
view.transform = CGAffineTransformScale(CGAffineTransformMakeRotation([self _xw_randomFloatBetween:-10.0 and:10.0]), 0.01, 0.01);
}
} completion:^(BOOL finished) {
for (UIView *view in snapshots) {
[view removeFromSuperview];
}
fromView.hidden = NO;
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}
- (float)_xw_randomFloatBetween:(float)smallNumber and:(float)bigNumber {
float diff = bigNumber - smallNumber;
return (((float) (arc4random() % ((unsigned)RAND_MAX + 1)) / RAND_MAX) * diff) + smallNumber;
}
@end
//
// XWCoolAnimator+XWFold.h
// XWTransitionDemo
//
// Created by wazrx on 16/6/13.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "XWCoolAnimator.h"
@interface XWCoolAnimator (XWFold)
- (void)xw_setFoldToAnimation:(id<UIViewControllerContextTransitioning>)transitionContext leftFlag:(BOOL)left;
- (void)xw_setFoldBackAnimation:(id<UIViewControllerContextTransitioning>)transitionContext leftFlag:(BOOL)left;
@end
//
// XWCoolAnimator+XWFold.m
// XWTransitionDemo
//
// Created by wazrx on 16/6/13.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "XWCoolAnimator+XWFold.h"
#import "UIView+Snapshot.h"
@implementation XWCoolAnimator (XWFold)
- (void)xw_setFoldToAnimation:(id<UIViewControllerContextTransitioning>)transitionContext leftFlag:(BOOL)left {
[self _xw_animation:transitionContext flag:left duration:self.toDuration];
}
- (void)xw_setFoldBackAnimation:(id<UIViewControllerContextTransitioning>)transitionContext leftFlag:(BOOL)left {
[self _xw_animation:transitionContext flag:left duration:self.backDuration];
}
- (void)_xw_animation:(id<UIViewControllerContextTransitioning>)transitionContext flag:(BOOL)flag duration:(NSTimeInterval)duration{
UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIView *toView = toVC.view;
UIView *fromView = fromVC.view;
UIView *containerView = [transitionContext containerView];
toView.frame = [transitionContext finalFrameForViewController:toVC];
toView.frame = CGRectOffset(toView.frame, toView.frame.size.width, 0);
[containerView addSubview:toView];
CATransform3D transform = CATransform3DIdentity;
transform.m34 = -0.005;
containerView.layer.sublayerTransform = transform;
CGSize size = toView.frame.size;
float foldWidth = size.width * 0.5 / (float)self.foldCount ;
NSMutableArray* fromViewFolds = [NSMutableArray new];
NSMutableArray* toViewFolds = [NSMutableArray new];
UIImage *fromImage = fromView.snapshotImage;
UIImage *toImage = toView.snapshotImage;
for (int i=0 ;i<self.foldCount; i++){
float offset = (float)i * foldWidth * 2;
UIView *leftFromViewFold = [self _xw_createSnapshotFromView:fromView location:offset left:YES image:fromImage];
leftFromViewFold.layer.position = CGPointMake(offset, size.height/2);
[fromViewFolds addObject:leftFromViewFold];
[leftFromViewFold.subviews[1] setAlpha:0.0];
UIView *rightFromViewFold = [self _xw_createSnapshotFromView:fromView location:offset + foldWidth left:NO image:fromImage];
rightFromViewFold.layer.position = CGPointMake(offset + foldWidth * 2, size.height/2);
[fromViewFolds addObject:rightFromViewFold];
[rightFromViewFold.subviews[1] setAlpha:0.0];
UIView *leftToViewFold = [self _xw_createSnapshotFromView:toView location:offset left:YES image:toImage];
leftToViewFold.layer.position = CGPointMake(!flag ? size.width : 0.0, size.height/2);
leftToViewFold.layer.transform = CATransform3DMakeRotation(M_PI_2, 0.0, 1.0, 0.0);
[toViewFolds addObject:leftToViewFold];
UIView *rightToViewFold = [self _xw_createSnapshotFromView:toView location:offset + foldWidth left:NO image:toImage];
rightToViewFold.layer.position = CGPointMake(!flag ? size.width : 0.0, size.height/2);
rightToViewFold.layer.transform = CATransform3DMakeRotation(-M_PI_2, 0.0, 1.0, 0.0);
[toViewFolds addObject:rightToViewFold];
}
fromView.frame = CGRectOffset(fromView.frame, fromView.frame.size.width, 0);
[UIView animateWithDuration:duration animations:^{
for (int i=0; i<self.foldCount; i++){
float offset = (float)i * foldWidth * 2;
UIView* leftFromView = fromViewFolds[i*2];
leftFromView.layer.position = CGPointMake(!flag ? 0.0 : size.width, size.height/2);
leftFromView.layer.transform = CATransform3DRotate(transform, M_PI_2, 0.0, 1.0, 0);
[leftFromView.subviews[1] setAlpha:1.0];
UIView* rightFromView = fromViewFolds[i*2+1];
rightFromView.layer.position = CGPointMake(!flag ? 0.0 : size.width, size.height/2);
rightFromView.layer.transform = CATransform3DRotate(transform, -M_PI_2, 0.0, 1.0, 0);
[rightFromView.subviews[1] setAlpha:1.0];
UIView* leftToView = toViewFolds[i*2];
leftToView.layer.position = CGPointMake(offset, size.height/2);
leftToView.layer.transform = CATransform3DIdentity;
[leftToView.subviews[1] setAlpha:0.0];
UIView* rightToView = toViewFolds[i*2+1];
rightToView.layer.position = CGPointMake(offset + foldWidth * 2, size.height/2);
rightToView.layer.transform = CATransform3DIdentity;
[rightToView.subviews[1] setAlpha:0.0];
}
} completion:^(BOOL finished) {
for (UIView *view in toViewFolds) {
[view removeFromSuperview];
}
for (UIView *view in fromViewFolds) {
[view removeFromSuperview];
}
BOOL transitionFinished = ![transitionContext transitionWasCancelled];
if (transitionFinished) {
toView.frame = containerView.bounds;
fromView.frame = containerView.bounds;
}
else {
fromView.frame = containerView.bounds;
}
[transitionContext completeTransition:transitionFinished];
}];
}
- (UIView *)_xw_createSnapshotFromView:(UIView *)view location:(CGFloat)offset left:(BOOL)left image:(UIImage *)image{
CGSize size = view.frame.size;
UIView *containerView = view.superview;
float foldWidth = size.width * 0.5 / (float)self.foldCount ;
UIView *snapshotView = [UIView new];
CGRect snapshotRegion = CGRectMake(offset, 0.0, foldWidth, size.height);
snapshotView.frame = snapshotRegion;
snapshotView.contentImage = image;
snapshotView.layer.contentsRect = CGRectMake(offset / size.width, 0.0, foldWidth / size.width, 1.0f);
UIView* snapshotWithShadowView = [self _xw_addShadowToView:snapshotView reverse:left];
[containerView addSubview:snapshotWithShadowView];
snapshotWithShadowView.layer.anchorPoint = CGPointMake( left ? 0.0 : 1.0, 0.5);
return snapshotWithShadowView;
}
- (UIView *)_xw_addShadowToView:(UIView*)view reverse:(BOOL)reverse {
UIView* viewWithShadow = [[UIView alloc] initWithFrame:view.frame];
UIView* shadowView = [[UIView alloc] initWithFrame:viewWithShadow.bounds];
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = shadowView.bounds;
gradient.colors = @[(id)[UIColor colorWithWhite:0.0 alpha:0.0].CGColor,
(id)[UIColor colorWithWhite:0.0 alpha:1.0].CGColor];
gradient.startPoint = CGPointMake(reverse ? 0.0 : 1.0, reverse ? 0.2 : 0.0);
gradient.endPoint = CGPointMake(reverse ? 1.0 : 0.0, reverse ? 0.0 : 1.0);
[shadowView.layer insertSublayer:gradient atIndex:1];
view.frame = view.bounds;
[viewWithShadow addSubview:view];
[viewWithShadow addSubview:shadowView];
return viewWithShadow;
}
@end
//
// XWCoolAnimator+XWVerticalLines.h
// XWTransitionDemo
//
// Created by wazrx on 16/6/14.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "XWCoolAnimator.h"
@interface XWCoolAnimator (XWLines)
- (void)xw_setLinesToAnimation:(id<UIViewControllerContextTransitioning>)transitionContext vertical:(BOOL)vertical;
- (void)xw_setLinesBackAnimation:(id<UIViewControllerContextTransitioning>)transitionContext vertical:(BOOL)vertical;
@end
//
// XWCoolAnimator+XWVerticalLines.m
// XWTransitionDemo
//
// Created by wazrx on 16/6/14.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "XWCoolAnimator+XWLines.h"
@implementation XWCoolAnimator (XWLines)
static inline float XWRandomFloat(float max, float min){
return ((float)arc4random() / 0x100000000) * (max - min) + min;
}
- (void)xw_setLinesToAnimation:(id<UIViewControllerContextTransitioning>)transitionContext vertical:(BOOL)vertical {
[self _xw_animateTransition:transitionContext duration:self.toDuration to:YES vertical:vertical];
}
- (void)xw_setLinesBackAnimation:(id<UIViewControllerContextTransitioning>)transitionContext vertical:(BOOL)vertical {
[self _xw_animateTransition:transitionContext duration:self.toDuration to:NO vertical:vertical];
}
#define HLINEHEIGHT 4.0
- (void)_xw_animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext duration:(NSTimeInterval)duration to:(BOOL)flag vertical:(BOOL)vertical{
UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIView *toView = toVC.view;
UIView *containerView = [transitionContext containerView];
[containerView insertSubview:toView atIndex:0];
NSArray *outgoingLineViews = [self _xw_lineViews:fromVC.view intoSlicesOfDis:HLINEHEIGHT Offset:fromVC.view.frame.origin.y containerView:containerView vertical:vertical];
NSArray *incomingLineViews = [self _xw_lineViews:toView intoSlicesOfDis:HLINEHEIGHT Offset:toView.frame.origin.y containerView:containerView vertical:vertical];
CGFloat toViewStart = vertical ? toView.frame.origin.y : toView.frame.origin.x;
BOOL presenting = flag;
vertical ? [self _xw_repositionViewSlices:incomingLineViews moveFirstFrameUp:NO]:[self _xw_repositionViewSlices:incomingLineViews moveLeft:!presenting];
fromVC.view.hidden = YES;
toView.hidden = YES;
[UIView animateWithDuration:duration - 0.01 delay:0 usingSpringWithDamping:0.8 initialSpringVelocity:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
vertical ? [self _xw_repositionViewSlices:outgoingLineViews moveFirstFrameUp:YES] : [self _xw_repositionViewSlices:outgoingLineViews moveLeft:presenting];
[self _xw_resetViewSlices:incomingLineViews toOrigin:toViewStart vertical:vertical];
} completion:^(BOOL finished) {
fromVC.view.hidden = NO;
toView.hidden = NO;
[toView setNeedsUpdateConstraints];
for (UIView *v in incomingLineViews) {
[v removeFromSuperview];
}
for (UIView *v in outgoingLineViews) {
[v removeFromSuperview];
}
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}
- (UIImage *)_xw_ImageFromsnapshotView:(UIView *)view{
CALayer *layer = view.layer;
UIGraphicsBeginImageContextWithOptions(layer.bounds.size, layer.opaque, 0);
CGContextRef context = UIGraphicsGetCurrentContext();
[layer renderInContext:context];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
//弃用了原作者的截取若干小图的方法,由于toView刚开始无法截图,原作者采用延迟0.001秒后来截图,但是这种方式不是对手势和转场失败的效果有很大的干扰,所以我转换思路换了一种方式实现了小图,采用的是contentsRect
- (NSArray<UIView *> *)_xw_lineViews:(UIView *)view intoSlicesOfDis:(float)dis Offset:(float)yOffset containerView:(UIView *)containerView vertical:(BOOL)vertical{
CGFloat width = vertical ? CGRectGetHeight(view.frame) : CGRectGetWidth(view.frame);
CGFloat height = !vertical ? CGRectGetHeight(view.frame) : CGRectGetWidth(view.frame);
UIImage *img = [self _xw_ImageFromsnapshotView:view];
NSMutableArray *lineViews = [NSMutableArray array];
for (int i = 0; i < height; i += dis) {
CGRect subrect = vertical ? CGRectMake(i, 0, dis, width) : CGRectMake(0, i, width, dis);
UIView *subsnapshot = [UIView new];
subsnapshot.layer.contents= (__bridge id)img.CGImage;
subsnapshot.layer.contentsRect = vertical ? CGRectMake((float)i / view.frame.size.width, 0.0, dis / view.frame.size.width, 1.0) : CGRectMake(0, (float)i / view.frame.size.height, 1.0, dis / view.frame.size.height);
subrect.origin.x += yOffset;
subsnapshot.frame = subrect;
[lineViews addObject:subsnapshot];
[containerView addSubview:subsnapshot];
}
return lineViews;
}
-(void)_xw_repositionViewSlices:(NSArray *)views moveLeft:(BOOL)left{
CGRect frame;
float width;
for (UIView *line in views) {
frame = line.frame;
width = CGRectGetWidth(frame) * XWRandomFloat(1.0, 8.0);
frame.origin.x += (left)?-width:width;
line.frame = frame;
}
}
-(void)_xw_repositionViewSlices:(NSArray *)views moveFirstFrameUp:(BOOL)startUp{
BOOL up = startUp;
CGRect frame;
float height;
for (UIView *line in views) {
frame = line.frame;
height = CGRectGetHeight(frame) * XWRandomFloat(1.0, 4.0);
frame.origin.y += (up)?-height:height;
line.frame = frame;
up = !up;
}
}
-(void)_xw_resetViewSlices:(NSArray *)views toOrigin:(CGFloat)o vertical:(BOOL)vertical{
CGRect frame;
for (UIView *line in views) {
frame = line.frame;
if (vertical) {
frame.origin.y = o;
}else{
frame.origin.x = o;
}
line.frame = frame;
}
}
@end
//
// XWCoolAnimator+XWMiddlePageFlip.h
// XWTransitionDemo
//
// Created by wazrx on 16/6/13.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "XWCoolAnimator.h"
typedef NS_ENUM(NSUInteger, XWMiddlePageFlipDirection) {
XWMiddlePageFlipDirectionLeft,
XWMiddlePageFlipDirectionRight,
XWMiddlePageFlipDirectionTop,
XWMiddlePageFlipDirectionBottom
};
@interface XWCoolAnimator (XWMiddlePageFlip)
- (void)xw_setMiddlePageFlipToAnimation:(id<UIViewControllerContextTransitioning>)transitionContext direction:(XWMiddlePageFlipDirection)direction;
- (void)xw_setMiddlePageFlipBackAnimation:(id<UIViewControllerContextTransitioning>)transitionContext direction:(XWMiddlePageFlipDirection)direction;
@end
//
// XWCoolAnimator+XWPageFlip.h
// XWTransitionDemo
//
// Created by wazrx on 16/6/13.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "XWCoolAnimator.h"
@interface XWCoolAnimator (XWPageFlip)
- (void)xw_setPageFlipToAnimation:(id<UIViewControllerContextTransitioning>)transitionContext;
- (void)xw_setPageFlipBackAnimation:(id<UIViewControllerContextTransitioning>)transitionContext;
@end
//
// XWCoolAnimator+XWPageFlip.m
// XWTransitionDemo
//
// Created by wazrx on 16/6/13.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "XWCoolAnimator+XWPageFlip.h"
#import "UIView+Snapshot.h"
#import <objc/runtime.h>
static NSString *const kPageFlipTempViewKey = @"kPageFlipTempViewKey";
@implementation XWCoolAnimator (XWPageFlip)
- (void)xw_setPageFlipToAnimation:(id<UIViewControllerContextTransitioning>)transitionContext {
UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIView *tempView = [UIView new];
tempView.contentImage = fromVC.view.snapshotImage;
tempView.frame = fromVC.view.frame;
UIView *containerView = [transitionContext containerView];
[containerView addSubview:toVC.view];
[containerView addSubview:tempView];
fromVC.view.hidden = YES;
[containerView insertSubview:toVC.view atIndex:0];
[self _xw_setAnchorPoint:CGPointMake(0, 0.5) forView:tempView];
CATransform3D transfrom3d = CATransform3DIdentity;
transfrom3d.m34 = -0.002;
containerView.layer.sublayerTransform = transfrom3d;
CAGradientLayer *fromGradient = [CAGradientLayer layer];
fromGradient.frame = fromVC.view.bounds;
fromGradient.colors = @[(id)[UIColor blackColor].CGColor,
(id)[UIColor blackColor].CGColor];
fromGradient.startPoint = CGPointMake(0.0, 0.5);
fromGradient.endPoint = CGPointMake(0.8, 0.5);
UIView *fromShadow = [[UIView alloc]initWithFrame:fromVC.view.bounds];
fromShadow.backgroundColor = [UIColor clearColor];
[fromShadow.layer insertSublayer:fromGradient atIndex:1];
fromShadow.alpha = 0.0;
[tempView addSubview:fromShadow];
CAGradientLayer *toGradient = [CAGradientLayer layer];
toGradient.frame = fromVC.view.bounds;
toGradient.colors = @[(id)[UIColor blackColor].CGColor,
(id)[UIColor blackColor].CGColor];
toGradient.startPoint = CGPointMake(0.0, 0.5);
toGradient.endPoint = CGPointMake(0.8, 0.5);
UIView *toShadow = [[UIView alloc]initWithFrame:fromVC.view.bounds];
toShadow.backgroundColor = [UIColor clearColor];
[toShadow.layer insertSublayer:toGradient atIndex:1];
toShadow.alpha = 1.0;
[toVC.view addSubview:toShadow];
objc_setAssociatedObject(self, &kPageFlipTempViewKey, tempView, OBJC_ASSOCIATION_ASSIGN);
[UIView animateWithDuration:self.toDuration animations:^{
tempView.layer.transform = CATransform3DMakeRotation(-M_PI_2, 0, 1, 0);
fromShadow.alpha = 1.0;
toShadow.alpha = 0.0;
} completion:^(BOOL finished) {
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
if ([transitionContext transitionWasCancelled]) {
[tempView removeFromSuperview];
fromVC.view.hidden = NO;
}
}];
}
- (void)xw_setPageFlipBackAnimation:(id<UIViewControllerContextTransitioning>)transitionContext {
UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIView *containerView = [transitionContext containerView];
UIView *tempView = objc_getAssociatedObject(self, &kPageFlipTempViewKey);
[containerView addSubview:toVC.view];
[UIView animateWithDuration:self.backDuration animations:^{
tempView.layer.transform = CATransform3DIdentity;
fromVC.view.subviews.lastObject.alpha = 1.0;
tempView.subviews.lastObject.alpha = 0.0;
} completion:^(BOOL finished) {
if ([transitionContext transitionWasCancelled]) {
[transitionContext completeTransition:NO];
}else{
[transitionContext completeTransition:YES];
[tempView removeFromSuperview];
toVC.view.hidden = NO;
}
}];
}
- (void)_xw_setAnchorPoint:(CGPoint)point forView:(UIView *)view{
view.frame = CGRectOffset(view.frame, (point.x - view.layer.anchorPoint.x) * view.frame.size.width, (point.y - view.layer.anchorPoint.y) * view.frame.size.height);
view.layer.anchorPoint = point;
}
@end
//
// XWCoolAnimator+XWPortal.h
// XWTransitionDemo
//
// Created by wazrx on 16/6/16.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "XWCoolAnimator.h"
@interface XWCoolAnimator (XWPortal)
- (void)xw_setPortalToAnimation:(id<UIViewControllerContextTransitioning>)transitionContext;
- (void)xw_setPortalBackAnimation:(id<UIViewControllerContextTransitioning>)transitionContext;
@end
//
// XWCoolAnimator+XWPortal.m
// XWTransitionDemo
//
// Created by wazrx on 16/6/16.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "XWCoolAnimator+XWPortal.h"
#import "UIView+Snapshot.h"
@implementation XWCoolAnimator (XWPortal)
- (void)xw_setPortalToAnimation:(id<UIViewControllerContextTransitioning>)transitionContext {
UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIView *toView = toVC.view;
UIView *fromView = fromVC.view;
UIView *containerView = [transitionContext containerView];
UIView *toViewSnapshot = [UIView new];
toViewSnapshot.contentImage = toView.snapshotImage;
toViewSnapshot.frame = containerView.bounds;
CATransform3D scale = CATransform3DIdentity;
toViewSnapshot.layer.transform = CATransform3DScale(scale, 0.8, 0.8, 1);
[containerView addSubview:toViewSnapshot];
[containerView sendSubviewToBack:toViewSnapshot];
CGRect leftSnapshotRegion = CGRectMake(0, 0, fromView.frame.size.width / 2, fromView.frame.size.height);
UIView *leftHandView = [UIView new];
leftHandView.contentImage = fromView.snapshotImage;
leftHandView.layer.contentsRect = CGRectMake(0, 0, 0.5, 1.0);
leftHandView.frame = leftSnapshotRegion;
[containerView addSubview:leftHandView];
CGRect rightSnapshotRegion = CGRectMake(fromView.frame.size.width / 2, 0, fromView.frame.size.width / 2, fromView.frame.size.height);
UIView *rightHandView = [UIView new];
rightHandView.contentImage = leftHandView.contentImage;
rightHandView.layer.contentsRect = CGRectMake(0.5, 0, 0.5, 1.0);
rightHandView.frame = rightSnapshotRegion;
[containerView addSubview:rightHandView];
fromView.hidden = YES;
[UIView animateWithDuration:self.toDuration
delay:0.0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
leftHandView.frame = CGRectOffset(leftHandView.frame, - leftHandView.frame.size.width, 0);
rightHandView.frame = CGRectOffset(rightHandView.frame, rightHandView.frame.size.width, 0);
toViewSnapshot.center = toView.center;
toViewSnapshot.frame = toView.frame;
} completion:^(BOOL finished) {
fromView.hidden = NO;
if ([transitionContext transitionWasCancelled]) {
[containerView addSubview:fromView];
[self _xw_removeOtherViews:fromView];
} else {
[containerView addSubview:toView];
[self _xw_removeOtherViews:toView];
}
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}
- (void)xw_setPortalBackAnimation:(id<UIViewControllerContextTransitioning>)transitionContext {
UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIView *toView = toVC.view;
UIView *fromView = fromVC.view;
UIView *containerView = [transitionContext containerView];
[containerView addSubview:fromView];
toView.frame = [transitionContext finalFrameForViewController:toVC];
toView.frame = CGRectOffset(toView.frame, toView.frame.size.width, 0);
[containerView addSubview:toView];
CGRect leftSnapshotRegion = CGRectMake(0, 0, toView.frame.size.width / 2, toView.frame.size.height);
UIView *leftHandView = [UIView new];
leftHandView.contentImage = toView.snapshotImage;
leftHandView.layer.contentsRect = CGRectMake(0, 0, 0.5, 1.0);
leftHandView.frame = leftSnapshotRegion;
leftHandView.frame = CGRectOffset(leftHandView.frame, - leftHandView.frame.size.width, 0);
[containerView addSubview:leftHandView];
CGRect rightSnapshotRegion = CGRectMake(toView.frame.size.width / 2, 0, toView.frame.size.width / 2, toView.frame.size.height);
UIView *rightHandView = [UIView new];
rightHandView.contentImage = leftHandView.contentImage;
rightHandView.layer.contentsRect = CGRectMake(0.5, 0, 0.5, 1.0);
rightHandView.frame = rightSnapshotRegion;
rightHandView.frame = CGRectOffset(rightHandView.frame, rightHandView.frame.size.width, 0);
[containerView addSubview:rightHandView];
[UIView animateWithDuration:self.backDuration
delay:0.0
options:UIViewAnimationOptionCurveEaseOut
animations:^{
leftHandView.frame = CGRectOffset(leftHandView.frame, leftHandView.frame.size.width, 0);
rightHandView.frame = CGRectOffset(rightHandView.frame, - rightHandView.frame.size.width, 0);
CATransform3D scale = CATransform3DIdentity;
fromView.layer.transform = CATransform3DScale(scale, 0.8, 0.8, 1);
} completion:^(BOOL finished) {
if ([transitionContext transitionWasCancelled]) {
[self _xw_removeOtherViews:fromView];
} else {
[self _xw_removeOtherViews:toView];
toView.frame = containerView.bounds;
}
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}
- (void)_xw_removeOtherViews:(UIView*)viewToKeep {
UIView *containerView = viewToKeep.superview;
for (UIView *view in containerView.subviews) {
if (view != viewToKeep) {
[view removeFromSuperview];
}
}
}
@end
//
// XWCoolAnimator+XWScanning.h
// XWTransitionDemo
//
// Created by wazrx on 16/6/14.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "XWCoolAnimator.h"
@interface XWCoolAnimator (XWScanning)
- (void)xw_setScanningToAnimation:(id<UIViewControllerContextTransitioning>)transitionContext direction:(NSUInteger)direction;
- (void)xw_setScanningBackAnimation:(id<UIViewControllerContextTransitioning>)transitionContext direction:(NSUInteger)direction;
@end
//
// XWCoolAnimator+XWScanning.m
// XWTransitionDemo
//
// Created by wazrx on 16/6/14.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "XWCoolAnimator+XWScanning.h"
@implementation XWCoolAnimator (XWScanning)
- (void)xw_setScanningToAnimation:(id<UIViewControllerContextTransitioning>)transitionContext direction:(NSUInteger)direction {
[self _xw_animateTransition:transitionContext duration:self.toDuration direction:direction];
}
- (void)xw_setScanningBackAnimation:(id<UIViewControllerContextTransitioning>)transitionContext direction:(NSUInteger)direction {
[self _xw_animateTransition:transitionContext duration:self.toDuration direction:direction];
}
- (void)_xw_animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext duration:(NSTimeInterval)duration direction:(NSInteger)direction{
UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIView *containerView = [transitionContext containerView];
[containerView insertSubview:toVC.view atIndex:0];
UIView *maskView = [UIView new];
maskView.backgroundColor = [UIColor whiteColor];
maskView.frame = containerView.bounds;
fromVC.view.maskView = maskView;
UIView *scanView = [UIView new];
scanView.layer.contents = (__bridge id)[UIImage imageNamed:@"line"].CGImage;
[containerView addSubview:scanView];
CGFloat width = containerView.frame.size.width;
CGFloat height = containerView.frame.size.height;
CGAffineTransform transfrom = CGAffineTransformIdentity;
if (direction == 0){
scanView.bounds = CGRectMake(0, 0, 18, height * 1.5);
scanView.center = CGPointMake(-4, containerView.center.y);
transfrom = CGAffineTransformMakeTranslation(width, 0);
}
if (direction == 1){
scanView.bounds = CGRectMake(0, 0, 18, height * 1.5);
scanView.center = CGPointMake(width + 4, containerView.center.y);
transfrom = CGAffineTransformMakeTranslation(-width, 0);
}
if (direction == 2){
scanView.bounds = CGRectMake(0, 0,width * 1.5, 18);
scanView.center = CGPointMake(containerView.center.x, -4);
transfrom = CGAffineTransformMakeTranslation(0, height);
}
if (direction == 3){
scanView.bounds = CGRectMake(0, 0, width * 1.5, 18);
scanView.center = CGPointMake(containerView.center.x, height + 4);
transfrom = CGAffineTransformMakeTranslation(0, -height);
}
[UIView animateKeyframesWithDuration:duration delay:0.0 options:0
animations:^{
[UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.7 animations:^{
maskView.transform = transfrom;
scanView.transform = transfrom;
}];
[UIView addKeyframeWithRelativeStartTime:0.7 relativeDuration:0.3 animations:^{
scanView.transform = CGAffineTransformIdentity;
}];
} completion:^(BOOL finished) {
fromVC.view.maskView = nil;
[scanView removeFromSuperview];
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}
@end
//
// XWCoolAnimator.h
// XWTransitionDemo
//
// Created by wazrx on 16/6/13.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "XWTransitionAnimator.h"
/**
cool转场效果中的Portal、Fold、Explode效果的部分代码逻辑来源于ColinEberhardt/VCTransitionsLibrary,地址:https://github.com/ColinEberhardt/VCTransitionsLibrary 非常感谢作者,我只是将其进行了部分改动,以便对手势的支持更加完善,里面还有许多其他效果,本人经历有限就没有再集成进来了,大家可以自行查看;
cool转场效果的Lines的想法来自于cinkster/HUAnimator,地址:https://github.com/cinkster/HUAnimator, 非常感谢作者,但是由于作者在对toVC截图采用了延迟的方式来处理,导致了闪烁和一些手势上的bug,对此我采用了另一种方式来解决截图的问题,使用了layer的contentRect属性,解决了闪烁问题和延迟截图的bug问题,相关代码请自行查看
*/
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSUInteger, XWCoolTransitionAnimatorType){
//全屏翻页
XWCoolTransitionAnimatorTypePageFlip,
//中间翻页
XWCoolTransitionAnimatorTypePageMiddleFlipFromLeft,
XWCoolTransitionAnimatorTypePageMiddleFlipFromRight,
XWCoolTransitionAnimatorTypePageMiddleFlipFromTop,
XWCoolTransitionAnimatorTypePageMiddleFlipFromBottom,
//开窗
XWCoolTransitionAnimatorTypePortal,
//折叠
XWCoolTransitionAnimatorTypeFoldFromLeft,
XWCoolTransitionAnimatorTypeFoldFromRight,
//爆炸
XWCoolTransitionAnimatorTypeExplode,
//酷炫线条效果
XWCoolTransitionAnimatorTypeHorizontalLines,
XWCoolTransitionAnimatorTypeVerticalLines,
//扫描效果
XWCoolTransitionAnimatorTypeScanningFromLeft,
XWCoolTransitionAnimatorTypeScanningFromRight,
XWCoolTransitionAnimatorTypeScanningFromTop,
XWCoolTransitionAnimatorTypeScanningFromBottom,
};
@interface XWCoolAnimator : XWTransitionAnimator
//flod效果的折叠数量, for XWCoolTransitionAnimatorTypeFoldFromLeft 和 XWCoolTransitionAnimatorTypeFoldFromRight
@property (nonatomic) NSUInteger foldCount;
+ (instancetype)xw_animatorWithType:(XWCoolTransitionAnimatorType)type;
@end
NS_ASSUME_NONNULL_END
\ No newline at end of file
//
// XWCoolAnimator.m
// XWTransitionDemo
//
// Created by wazrx on 16/6/13.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "XWCoolAnimator.h"
#import "XWCoolAnimator+XWPortal.h"
#import "XWCoolAnimator+XWPageFlip.h"
#import "XWCoolAnimator+XWFold.h"
#import "XWCoolAnimator+XWMiddlePageFlip.h"
#import "XWCoolAnimator+XWExplode.h"
#import "XWCoolAnimator+XWLines.h"
#import "XWCoolAnimator+XWScanning.h"
@interface XWCoolAnimator ()
@property (nonatomic, weak) UIView *pageFlipTempView;
@end
@implementation XWCoolAnimator{
XWCoolTransitionAnimatorType _type;
}
- (void)dealloc{
NSLog(@"coolAnimator销毁了");
}
+ (instancetype)xw_animatorWithType:(XWCoolTransitionAnimatorType)type {
return [[self alloc] _initWithTransitionType:type];
}
- (instancetype)_initWithTransitionType:(XWCoolTransitionAnimatorType)type{
self = [super init];
if (self) {
_type = type;
_foldCount = 4;
}
return self;
}
- (void)xw_setToAnimation:(id<UIViewControllerContextTransitioning>)transitionContext{
switch (_type) {
case XWCoolTransitionAnimatorTypePageFlip: {
[self xw_setPageFlipToAnimation:transitionContext];
break;
}
case XWCoolTransitionAnimatorTypePageMiddleFlipFromLeft: {
[self xw_setMiddlePageFlipToAnimation:transitionContext direction:XWMiddlePageFlipDirectionLeft];
break;
}
case XWCoolTransitionAnimatorTypePageMiddleFlipFromRight: {
[self xw_setMiddlePageFlipToAnimation:transitionContext direction:XWMiddlePageFlipDirectionRight];
break;
}
case XWCoolTransitionAnimatorTypePageMiddleFlipFromTop: {
[self xw_setMiddlePageFlipToAnimation:transitionContext direction:XWMiddlePageFlipDirectionTop];
break;
}
case XWCoolTransitionAnimatorTypePageMiddleFlipFromBottom: {
[self xw_setMiddlePageFlipToAnimation:transitionContext direction:XWMiddlePageFlipDirectionBottom];
break;
}
case XWCoolTransitionAnimatorTypePortal: {
[self xw_setPortalToAnimation:transitionContext];
break;
}
case XWCoolTransitionAnimatorTypeFoldFromLeft: {
[self xw_setFoldToAnimation:transitionContext leftFlag:YES];
break;
}
case XWCoolTransitionAnimatorTypeFoldFromRight: {
[self xw_setFoldToAnimation:transitionContext leftFlag:NO];
break;
}
case XWCoolTransitionAnimatorTypeExplode: {
[self xw_setExplodeToAnimation:transitionContext];
break;
}
case XWCoolTransitionAnimatorTypeHorizontalLines: {
[self xw_setLinesToAnimation:transitionContext vertical:NO];
break;
}
case XWCoolTransitionAnimatorTypeVerticalLines: {
[self xw_setLinesToAnimation:transitionContext vertical:YES];
break;
}
case XWCoolTransitionAnimatorTypeScanningFromLeft: {
[self xw_setScanningToAnimation:transitionContext direction:0];
break;
}
case XWCoolTransitionAnimatorTypeScanningFromRight: {
[self xw_setScanningToAnimation:transitionContext direction:1];
break;
}
case XWCoolTransitionAnimatorTypeScanningFromTop: {
[self xw_setScanningToAnimation:transitionContext direction:2];
break;
}
case XWCoolTransitionAnimatorTypeScanningFromBottom: {
[self xw_setScanningToAnimation:transitionContext direction:3];
break;
}
}
}
- (void)xw_setBackAnimation:(id<UIViewControllerContextTransitioning>)transitionContext{
switch (_type) {
case XWCoolTransitionAnimatorTypePageFlip: {
[self xw_setPageFlipBackAnimation:transitionContext];
break;
}
case XWCoolTransitionAnimatorTypePageMiddleFlipFromLeft: {
[self xw_setMiddlePageFlipBackAnimation:transitionContext direction:XWMiddlePageFlipDirectionRight];
break;
}
case XWCoolTransitionAnimatorTypePageMiddleFlipFromRight: {
[self xw_setMiddlePageFlipBackAnimation:transitionContext direction:XWMiddlePageFlipDirectionLeft];
break;
}
case XWCoolTransitionAnimatorTypePageMiddleFlipFromTop: {
[self xw_setMiddlePageFlipBackAnimation:transitionContext direction:XWMiddlePageFlipDirectionBottom];
break;
}
case XWCoolTransitionAnimatorTypePageMiddleFlipFromBottom: {
[self xw_setMiddlePageFlipBackAnimation:transitionContext direction:XWMiddlePageFlipDirectionTop];
break;
}
case XWCoolTransitionAnimatorTypePortal: {
[self xw_setPortalBackAnimation:transitionContext];
break;
}
case XWCoolTransitionAnimatorTypeFoldFromLeft: {
[self xw_setFoldBackAnimation:transitionContext leftFlag:NO];
break;
}
case XWCoolTransitionAnimatorTypeFoldFromRight: {
[self xw_setFoldBackAnimation:transitionContext leftFlag:YES];
break;
}
case XWCoolTransitionAnimatorTypeExplode: {
[self xw_setExplodeBackAnimation:transitionContext];
break;
}
case XWCoolTransitionAnimatorTypeHorizontalLines: {
[self xw_setLinesBackAnimation:transitionContext vertical:NO];
break;
}
case XWCoolTransitionAnimatorTypeVerticalLines: {
[self xw_setLinesBackAnimation:transitionContext vertical:YES];
break;
}
case XWCoolTransitionAnimatorTypeScanningFromLeft: {
[self xw_setScanningBackAnimation:transitionContext direction:1];
break;
}
case XWCoolTransitionAnimatorTypeScanningFromRight: {
[self xw_setScanningBackAnimation:transitionContext direction:0];
break;
}
case XWCoolTransitionAnimatorTypeScanningFromTop: {
[self xw_setScanningBackAnimation:transitionContext direction:3];
break;
}
case XWCoolTransitionAnimatorTypeScanningFromBottom: {
[self xw_setScanningBackAnimation:transitionContext direction:2];
break;
}
}
}
@end
//
// XWDrawerAnimator.h
// XWTransitionDemo
//
// Created by wazrx on 16/6/15.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "XWTransitionAnimator.h"
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSUInteger, XWDrawerAnimatorDirection) {
XWDrawerAnimatorDirectionLeft,
XWDrawerAnimatorDirectionRight,
XWDrawerAnimatorDirectionTop,
XWDrawerAnimatorDirectionBottom
};
@interface XWDrawerAnimator : XWTransitionAnimator
/**fromVC的缩放比例, 如果Flip效果,比例默认为0.8, 否者为1.0不缩放*/
@property (nonatomic, assign) CGFloat scaleRatio;
/**视差效果,类似于QQ的设置界面弹出效果, 和flipEnable只能选择其一,如果都设置为YES,后设置的生效*/
@property (nonatomic, assign) BOOL parallaxEnable;
/**翻转效果,类似于淘宝选择规格时,后面视图的动画效果*/
@property (nonatomic, assign) BOOL flipEnable;
/**
* 初始化一个转场抽屉效果器
*
* @param direction 抽屉效果触发方向
* @param distance 显示在屏幕中的宽度或者高度,如果传0,默认就是当前屏幕的高度或者宽度
*
* @return animator
*/
+ (instancetype)xw_animatorWithDirection:(XWDrawerAnimatorDirection)direction moveDistance:(CGFloat)distance;
/**
* 开启边缘(就是屏幕除开toView所占用的部分)back手势和边缘点击返回效果,类似于QQ设置界面的返回效果
*
* @param backConfig 返回操作,您的dismiss或者pop操作
*/
- (void)xw_enableEdgeGestureAndBackTapWithConfig:(dispatch_block_t)backConfig;
@end
NS_ASSUME_NONNULL_END
\ No newline at end of file
//
// XWFilterAnimator+XWBarSwipe.h
// XWTransitionDemo
//
// Created by wazrx on 16/6/19.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "XWFilterAnimator.h"
@interface XWFilterAnimator (XWBarSwipe)
- (void)xw_barSwipeAnimationFor:(XWFilterTransitionView *)filterView transitionContext:(id<UIViewControllerContextTransitioning>)transitionContext duration:(NSTimeInterval)duration toFlag:(BOOL)flag;
@end
//
// XWFilterAnimator+XWBarSwipe.m
// XWTransitionDemo
//
// Created by wazrx on 16/6/19.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "XWFilterAnimator+XWBarSwipe.h"
@implementation XWFilterAnimator (XWBarSwipe)
- (void)xw_barSwipeAnimationFor:(XWFilterTransitionView *)filterView transitionContext:(id<UIViewControllerContextTransitioning>)transitionContext duration:(NSTimeInterval)duration toFlag:(BOOL)flag {
CGFloat angle = self.revers && !flag ? self.startAngle + M_PI : self.startAngle;
CIFilter *filter = [CIFilter filterWithName:@"CIBarsSwipeTransition"
keysAndValues:
kCIInputAngleKey, @(angle),
nil];
filterView.filter = filter;
[XWFilterTransitionView xw_animationWith:filterView duration:duration completion:^(BOOL finished) {
[filterView removeFromSuperview];
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}
@end
//
// XWFilterAnimator+XWBoxBlur.h
// XWTransitionDemo
//
// Created by wazrx on 16/6/17.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "XWFilterAnimator.h"
@interface XWFilterAnimator (XWBoxBlur)
- (void)xw_boxBlurAnimationFor:(XWFilterTransitionView *)filterView transitionContext:(id<UIViewControllerContextTransitioning>)transitionContext duration:(NSTimeInterval)duration;
@end
//
// XWFilterAnimator+XWBoxBlur.m
// XWTransitionDemo
//
// Created by wazrx on 16/6/17.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "XWFilterAnimator+XWBoxBlur.h"
@implementation XWFilterAnimator (XWBoxBlur)
- (void)xw_boxBlurAnimationFor:(XWFilterTransitionView *)filterView transitionContext:(id<UIViewControllerContextTransitioning>)transitionContext duration:(NSTimeInterval)duration {
CIFilter *filter = [CIFilter filterWithName: @"CIBoxBlur"];
filterView.filter = filter;
filterView.blurType = YES;
[XWFilterTransitionView xw_animationWith:filterView duration:duration completion:^(BOOL finished) {
[filterView removeFromSuperview];
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}
@end
//
// XWFilterAnimator+XWCopyMachine.h
// XWTransitionDemo
//
// Created by wazrx on 16/6/19.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "XWFilterAnimator.h"
@interface XWFilterAnimator (XWCopyMachine)
- (void)xw_copyMachineAnimationFor:(XWFilterTransitionView *)filterView transitionContext:(id<UIViewControllerContextTransitioning>)transitionContext duration:(NSTimeInterval)duration toFlag:(BOOL)flag;
@end
//
// XWFilterAnimator+XWCopyMachine.m
// XWTransitionDemo
//
// Created by wazrx on 16/6/19.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "XWFilterAnimator+XWCopyMachine.h"
@implementation XWFilterAnimator (XWCopyMachine)
- (void)xw_copyMachineAnimationFor:(XWFilterTransitionView *)filterView transitionContext:(id<UIViewControllerContextTransitioning>)transitionContext duration:(NSTimeInterval)duration toFlag:(BOOL)flag{
CGFloat angle = self.revers && !flag ? self.startAngle + M_PI : self.startAngle;
CIVector *vector = [filterView xw_getInnerVector];
CIFilter *filter = [CIFilter filterWithName:@"CICopyMachineTransition"
keysAndValues:
kCIInputExtentKey, vector,
kCIInputColorKey, [CIColor colorWithRed:.6 green:1 blue:.8 alpha:1],
kCIInputAngleKey, @(angle),
kCIInputWidthKey, @50.0,
@"inputOpacity", @1.0,
nil];
filterView.filter = filter;
[XWFilterTransitionView xw_animationWith:filterView duration:duration completion:^(BOOL finished) {
[filterView removeFromSuperview];
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}
@end
//
// XWFilterAnimator+XWFlash.h
// XWTransitionDemo
//
// Created by wazrx on 16/6/19.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "XWFilterAnimator.h"
@interface XWFilterAnimator (XWFlash)
- (void)xw_flashAnimationFor:(XWFilterTransitionView *)filterView transitionContext:(id<UIViewControllerContextTransitioning>)transitionContext duration:(NSTimeInterval)duration;
@end
//
// XWFilterAnimator+XWFlash.m
// XWTransitionDemo
//
// Created by wazrx on 16/6/19.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "XWFilterAnimator+XWFlash.h"
@implementation XWFilterAnimator (XWFlash)
- (void)xw_flashAnimationFor:(XWFilterTransitionView *)filterView transitionContext:(id<UIViewControllerContextTransitioning>)transitionContext duration:(NSTimeInterval)duration{
CGSize size = filterView.frame.size;
CIFilter *filter = [CIFilter filterWithName:@"CIFlashTransition"
keysAndValues:
kCIInputCenterKey, [CIVector vectorWithCGPoint:CGPointMake(size.width, size.height)],
kCIInputColorKey, [CIColor colorWithRed:1.0 green:0.8 blue:0.6 alpha:1],
@"inputMaxStriationRadius", @2.5,
@"inputStriationStrength", @0.5,
@"inputStriationContrast", @1.37,
@"inputFadeThreshold", @0.5,
nil];
filterView.filter = filter;
[XWFilterTransitionView xw_animationWith:filterView duration:duration completion:^(BOOL finished) {
[filterView removeFromSuperview];
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}
@end
//
// XWFilterAnimator+XWMask.h
// XWTransitionDemo
//
// Created by wazrx on 16/6/17.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "XWFilterAnimator.h"
@interface XWFilterAnimator (XWMask)
- (void)xw_maskAnimationFor:(XWFilterTransitionView *)filterView transitionContext:(id<UIViewControllerContextTransitioning>)transitionContext duration:(NSTimeInterval)duration;
@end
//
// XWFilterAnimator+XWMask.m
// XWTransitionDemo
//
// Created by wazrx on 16/6/17.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "XWFilterAnimator+XWMask.h"
@implementation XWFilterAnimator (XWMask)
- (void)xw_maskAnimationFor:(XWFilterTransitionView *)filterView transitionContext:(id<UIViewControllerContextTransitioning>)transitionContext duration:(NSTimeInterval)duration {
CGFloat height = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey].view.frame.size.height;
CIImage *maskImg = self.maskImg ? [CIImage imageWithCGImage:self.maskImg.CGImage] : [CIImage imageWithCGImage:[UIImage imageNamed:@"mask.jpg"].CGImage];
CIFilter *filter = [CIFilter filterWithName: @"CIDisintegrateWithMaskTransition"
keysAndValues:
kCIInputMaskImageKey, maskImg,
@"inputShadowRadius", @10.0,
@"inputShadowDensity", @0.7,
@"inputShadowOffset", [CIVector vectorWithX:0.0 Y:-0.05 * height],
nil];
filterView.filter = filter;
[XWFilterTransitionView xw_animationWith:filterView duration:duration completion:^(BOOL finished) {
[filterView removeFromSuperview];
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}
@end
//
// XWFilterAnimator+XWMod.h
// XWTransitionDemo
//
// Created by wazrx on 16/6/19.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "XWFilterAnimator.h"
@interface XWFilterAnimator (XWMod)
- (void)xw_modAnimationFor:(XWFilterTransitionView *)filterView transitionContext:(id<UIViewControllerContextTransitioning>)transitionContext duration:(NSTimeInterval)duration toFlag:(BOOL)flag;
@end
//
// XWFilterAnimator+XWMod.m
// XWTransitionDemo
//
// Created by wazrx on 16/6/19.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "XWFilterAnimator+XWMod.h"
@implementation XWFilterAnimator (XWMod)
- (void)xw_modAnimationFor:(XWFilterTransitionView *)filterView transitionContext:(id<UIViewControllerContextTransitioning>)transitionContext duration:(NSTimeInterval)duration toFlag:(BOOL)flag{
CGFloat angle = self.revers && !flag ? self.startAngle + M_PI : self.startAngle;
CIVector *vector = [filterView xw_getInnerVector];
CIFilter *filter = [CIFilter filterWithName: @"CIModTransition"
keysAndValues:
kCIInputCenterKey,[CIVector vectorWithX:0.5 * vector.CGRectValue.size.width
Y:0.5 * vector.CGRectValue.size.height],
kCIInputAngleKey, @(angle),
kCIInputRadiusKey, @30.0,
@"inputCompression", @10.0,
nil];
filterView.filter = filter;
[XWFilterTransitionView xw_animationWith:filterView duration:duration completion:^(BOOL finished) {
[filterView removeFromSuperview];
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}
@end
//
// XWFilterAnimator+XWPageCurl.h
// XWTransitionDemo
//
// Created by wazrx on 16/6/19.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "XWFilterAnimator.h"
@interface XWFilterAnimator (XWPageCurl)
- (void)xw_pageCurlAnimationFor:(XWFilterTransitionView *)filterView transitionContext:(id<UIViewControllerContextTransitioning>)transitionContext duration:(NSTimeInterval)duration toFlag:(BOOL)flag;
@end
//
// XWFilterAnimator+XWPageCurl.m
// XWTransitionDemo
//
// Created by wazrx on 16/6/19.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "XWFilterAnimator+XWPageCurl.h"
@implementation XWFilterAnimator (XWPageCurl)
- (void)xw_pageCurlAnimationFor:(XWFilterTransitionView *)filterView transitionContext:(id<UIViewControllerContextTransitioning>)transitionContext duration:(NSTimeInterval)duration toFlag:(BOOL)flag{
CGFloat angle = self.revers && !flag ? self.startAngle + M_PI : self.startAngle;
CIFilter *filter = [CIFilter filterWithName: @"CIPageCurlWithShadowTransition"
keysAndValues:
kCIInputAngleKey, @(angle),
nil];
filterView.filter = filter;
[XWFilterTransitionView xw_animationWith:filterView duration:duration completion:^(BOOL finished) {
[filterView removeFromSuperview];
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}
@end
//
// XWFilterAnimator+XWRipple.h
// XWTransitionDemo
//
// Created by wazrx on 16/6/19.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "XWFilterAnimator.h"
@interface XWFilterAnimator (XWRipple)
- (void)xw_rippleAnimationFor:(XWFilterTransitionView *)filterView transitionContext:(id<UIViewControllerContextTransitioning>)transitionContext duration:(NSTimeInterval)duration;
@end
//
// XWFilterAnimator+XWRipple.m
// XWTransitionDemo
//
// Created by wazrx on 16/6/19.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "XWFilterAnimator+XWRipple.h"
@implementation XWFilterAnimator (XWRipple)
- (void)xw_rippleAnimationFor:(XWFilterTransitionView *)filterView transitionContext:(id<UIViewControllerContextTransitioning>)transitionContext duration:(NSTimeInterval)duration{
CIImage *img = [CIImage imageWithCGImage:[UIImage imageNamed:@"restrictedshine.tiff"].CGImage];
CIVector *vector = [filterView xw_getInnerVector];
CIFilter *filter = [CIFilter filterWithName: @"CIRippleTransition"
keysAndValues:
kCIInputShadingImageKey, img,
kCIInputCenterKey, [CIVector vectorWithX:0.5 * vector.CGRectValue.size.width
Y:0.5 * vector.CGRectValue.size.height],
nil];
filterView.filter = filter;
[XWFilterTransitionView xw_animationWith:filterView duration:duration completion:^(BOOL finished) {
[filterView removeFromSuperview];
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}
@end
//
// XWFilterAnimator+XWSwipe.h
// XWTransitionDemo
//
// Created by wazrx on 16/6/17.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "XWFilterAnimator.h"
@interface XWFilterAnimator (XWSwipe)
- (void)xw_swipeAnimationFor:(XWFilterTransitionView *)filterView transitionContext:(id<UIViewControllerContextTransitioning>)transitionContext duration:(NSTimeInterval)duration toFlag:(BOOL)flag;
@end
//
// XWFilterAnimator+XWSwipe.m
// XWTransitionDemo
//
// Created by wazrx on 16/6/17.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "XWFilterAnimator+XWSwipe.h"
@implementation XWFilterAnimator (XWSwipe)
- (void)xw_swipeAnimationFor:(XWFilterTransitionView *)filterView transitionContext:(id<UIViewControllerContextTransitioning>)transitionContext duration:(NSTimeInterval)duration toFlag:(BOOL)flag {
CGFloat angle = self.revers && !flag ? self.startAngle + M_PI : self.startAngle;
CIVector *vector = [filterView xw_getInnerVector];
CIFilter *filter = [CIFilter filterWithName:@"CISwipeTransition"
keysAndValues:
kCIInputExtentKey, vector,
kCIInputColorKey, [CIColor colorWithRed:0 green:0 blue:0 alpha:0],
kCIInputAngleKey, @(angle),
kCIInputWidthKey, @80.0,
@"inputOpacity", @0.0,
nil];
filterView.filter = filter;
[XWFilterTransitionView xw_animationWith:filterView duration:duration completion:^(BOOL finished) {
[filterView removeFromSuperview];
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}
@end
//
// XWFilterAnimator.h
// XWTransitionDemo
//
// Created by wazrx on 16/6/17.
// Copyright © 2016年 wazrx. All rights reserved.
// XWFilterAnimator 全都是基于不同的CIFilter产生的一些滤镜效果,貌似在模拟器无法运行这些效果,请在真机上测试
#import "XWTransitionAnimator.h"
#import "XWFilterTransitionView.h"
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSUInteger, XWFilterAnimatorType) {
XWFilterAnimatorTypeBoxBlur,//模糊转场,对应CIBoxBlur
XWFilterAnimatorTypeSwipe,//滑动过渡转场,对应CISwipeTranstion
XWFilterAnimatorTypeBarSwipe,//对应CIBarSwipeTranstion
XWFilterAnimatorTypeMask,//按指定遮罩图片转场,对应CIDisintegrateWithMaskTransition
XWFilterAnimatorTypeFlash,//闪烁转场,对应CIFlashTransition
XWFilterAnimatorTypeMod,//条纹转场 对应CIModTransition
XWFilterAnimatorTypePageCurl,//翻页转场 对应CIPageCurlWithShadowTransition
XWFilterAnimatorTypeRipple,//波纹转场,对应CIRippleTransition
XWFilterAnimatorTypeCopyMachine, //效果和XWCoolAnimator中的Scanning效果类似,对应CICopyMachineTransition
};
@interface XWFilterAnimator : XWTransitionAnimator
/**for XWFilterAnimatorTypeMask,如果为空,则为默认的maskImg*/
@property (nonatomic, strong) UIImage *maskImg;
/**是否翻转,对于有转场有方向之分的此属性可用,如果为YES,如果to转场为左,那么back转场为右,默认为YES*/
@property (nonatomic, assign) BOOL revers;
/**开始角度,对于有转场方向的转场此属性可用,0为左,M_PI_2 为下 M_PI 为右 M_PI_2 * 3为上,也可指定任意开始角度*/
@property (nonatomic, assign) CGFloat startAngle;
/**
* 初始化一个filter转场效果器
*
* @param type 效果枚举值
*
* @return 效果器
*/
+ (instancetype)xw_animatorWithType:(XWFilterAnimatorType)type;
@end
NS_ASSUME_NONNULL_END
\ No newline at end of file
//
// XWFilterAnimator.m
// XWTransitionDemo
//
// Created by wazrx on 16/6/17.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "XWFilterAnimator.h"
#import "XWFilterAnimator+XWBoxBlur.h"
#import "XWFilterAnimator+XWSwipe.h"
#import "XWFilterAnimator+XWBarSwipe.h"
#import "XWFilterAnimator+XWMask.h"
#import "XWFilterAnimator+XWFlash.h"
#import "XWFilterAnimator+XWMod.h"
#import "XWFilterAnimator+XWPageCurl.h"
#import "XWFilterAnimator+XWRipple.h"
#import "XWFilterAnimator+XWCopyMachine.h"
@implementation XWFilterAnimator{
UIView *_containerView;
XWFilterAnimatorType _type;
}
+ (instancetype)xw_animatorWithType:(XWFilterAnimatorType)type {
return[[self alloc] _initWithType:type];
}
- (instancetype)_initWithType:(XWFilterAnimatorType)type{
self = [super init];
if (self) {
_type = type;
self.needInteractiveTimer = YES;
_revers = YES;
}
return self;
}
- (void)xw_setToAnimation:(id<UIViewControllerContextTransitioning>)transitionContext{
UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIView *containerView = [transitionContext containerView];
_containerView = containerView;
[containerView addSubview:toVC.view];
XWFilterTransitionView *filterView = [[XWFilterTransitionView alloc] initWithFrame:containerView.bounds fromImage:[self xw_ImageFromsnapshotView:fromVC.view] toImage:[self xw_ImageFromsnapshotView:toVC.view]];
switch (_type) {
case XWFilterAnimatorTypeBoxBlur: {
[self xw_boxBlurAnimationFor:filterView transitionContext:transitionContext duration:self.toDuration];
break;
}
case XWFilterAnimatorTypeSwipe: {
[self xw_swipeAnimationFor:filterView transitionContext:transitionContext duration:self.toDuration toFlag:YES];
break;
}
case XWFilterAnimatorTypeBarSwipe:{
[self xw_barSwipeAnimationFor:filterView transitionContext:transitionContext duration:self.toDuration toFlag:YES];
break;
}
case XWFilterAnimatorTypeMask:{
[self xw_maskAnimationFor:filterView transitionContext:transitionContext duration:self.toDuration];
break;
}
case XWFilterAnimatorTypeFlash:{
[self xw_flashAnimationFor:filterView transitionContext:transitionContext duration:self.toDuration];
break;
}
case XWFilterAnimatorTypeMod:{
[self xw_modAnimationFor:filterView transitionContext:transitionContext duration:self.toDuration toFlag:YES];
break;
}
case XWFilterAnimatorTypePageCurl:{
[self xw_pageCurlAnimationFor:filterView transitionContext:transitionContext duration:self.toDuration toFlag:YES];
break;
}
case XWFilterAnimatorTypeRipple:{
[self xw_rippleAnimationFor:filterView transitionContext:transitionContext duration:self.toDuration];
break;
}
case XWFilterAnimatorTypeCopyMachine:{
[self xw_copyMachineAnimationFor:filterView transitionContext:transitionContext duration:self.toDuration toFlag:YES];
break;
}
}
[containerView addSubview:filterView];
}
- (void)xw_setBackAnimation:(id<UIViewControllerContextTransitioning>)transitionContext{
UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIView *containerView = [transitionContext containerView];
[containerView insertSubview:toVC.view atIndex:0];
_containerView = containerView;
XWFilterTransitionView *filterView = [[XWFilterTransitionView alloc] initWithFrame:containerView.bounds fromImage:[self xw_ImageFromsnapshotView:fromVC.view] toImage:[self xw_ImageFromsnapshotView:toVC.view]];
switch (_type) {
case XWFilterAnimatorTypeBoxBlur: {
[self xw_boxBlurAnimationFor:filterView transitionContext:transitionContext duration:self.backDuration];
break;
}
case XWFilterAnimatorTypeSwipe: {
[self xw_swipeAnimationFor:filterView transitionContext:transitionContext duration:self.backDuration toFlag:NO];
break;
}
case XWFilterAnimatorTypeBarSwipe:{
[self xw_barSwipeAnimationFor:filterView transitionContext:transitionContext duration:self.backDuration toFlag:NO];
break;
}
case XWFilterAnimatorTypeMask:{
[self xw_maskAnimationFor:filterView transitionContext:transitionContext duration:self.backDuration];
break;
}
case XWFilterAnimatorTypeFlash:{
[self xw_flashAnimationFor:filterView transitionContext:transitionContext duration:self.backDuration];
break;
}
case XWFilterAnimatorTypeMod:{
[self xw_modAnimationFor:filterView transitionContext:transitionContext duration:self.backDuration toFlag:NO];
break;
}
case XWFilterAnimatorTypePageCurl:{
[self xw_pageCurlAnimationFor:filterView transitionContext:transitionContext duration:self.backDuration toFlag:NO];
break;
}
case XWFilterAnimatorTypeRipple:{
[self xw_rippleAnimationFor:filterView transitionContext:transitionContext duration:self.backDuration];
break;
}
case XWFilterAnimatorTypeCopyMachine:{
[self xw_copyMachineAnimationFor:filterView transitionContext:transitionContext duration:self.backDuration toFlag:NO];
break;
}
}
[containerView addSubview:filterView];
}
- (UIImage *)xw_ImageFromsnapshotView:(UIView *)view{
CALayer *layer = view.layer;
UIGraphicsBeginImageContextWithOptions(layer.bounds.size, layer.opaque, 0);
CGContextRef context = UIGraphicsGetCurrentContext();
[layer renderInContext:context];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
- (void)xw_interactiveTransitionWillBeginTimerAnimation:(XWInteractiveTransition *)interactiveTransition{
_containerView.userInteractionEnabled = NO;
}
- (void)xw_interactiveTransition:(XWInteractiveTransition *)interactiveTransition willEndWithSuccessFlag:(BOOL)flag percent:(CGFloat)percent{
_containerView.userInteractionEnabled = YES;
}
@end
//
// XWBlurView.h
// XWTransitionDemo
//
// Created by wazrx on 16/6/17.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import <GLKit/GLKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface XWFilterTransitionView : GLKView
@property (nonatomic, assign) BOOL blurType;
@property (nonatomic, strong) CIFilter *filter;
- (instancetype)initWithFrame:(CGRect)frame
fromImage:(UIImage *)fromImage
toImage:(UIImage *)toImage;
- (CAAnimation *)xw_getInnerAnimation;
- (CIVector *)xw_getInnerVector;
+ (void)xw_animationWith:(XWFilterTransitionView *)filterView duration:(NSTimeInterval)duration completion:(void (^ __nullable)(BOOL finished))completion;
@end
NS_ASSUME_NONNULL_END
\ No newline at end of file
//
// XWBlurView.m
// XWTransitionDemo
//
// Created by wazrx on 16/6/17.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "XWFilterTransitionView.h"
@interface _XWDisplayRatioLayer : CALayer
@property (nonatomic, assign) CGFloat ratio;
@property (nonatomic, copy) void(^ratioUpdating)(CGFloat ratio);
@end
@implementation _XWDisplayRatioLayer
@dynamic ratio;
+ (BOOL)needsDisplayForKey:(NSString *)key{
if ([key isEqualToString:@"ratio"]) {
return YES;
}
return [super needsDisplayForKey:key];
}
- (void)display{
if (_ratioUpdating) {
_ratioUpdating([[self presentationLayer] ratio]);
}
}
@end
@interface XWFilterTransitionView ()<GLKViewDelegate, CAAnimationDelegate>
@property (nonatomic, weak) _XWDisplayRatioLayer *ratioLayer;
@property (nonatomic, assign) CGFloat ratio;
@property (nonatomic, copy) CIImage *(^animationConfig)(CGFloat ratio, CIImage *fromImg, CIImage * toImg, CIFilter * filter);
@property (nonatomic, copy) void(^completion)(BOOL finish);
@property (nonatomic, assign) CGFloat lastRatio;
@end
@implementation XWFilterTransitionView{
CIImage *_fromImg;
CIImage *_toImg;
CIContext *_saveContext;
CGRect _imgRect;
CIVector *_vector;
}
- (instancetype)initWithFrame:(CGRect)frame
fromImage:(UIImage *)fromImage
toImage:(UIImage *)toImage{
self = [super initWithFrame:frame];
if (!self) return nil;
_fromImg = [CIImage imageWithCGImage:fromImage.CGImage];
_toImg = [CIImage imageWithCGImage:toImage.CGImage];
_vector = [CIVector vectorWithX:0 Y:0 Z:fromImage.size.width * fromImage.scale W:fromImage.size.height * fromImage.scale];
CGFloat width = fromImage.size.width * fromImage.scale;
CGFloat height = fromImage.size.height * fromImage.scale;
_imgRect = CGRectMake(0, 0, width, height);
self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
_saveContext = [CIContext contextWithEAGLContext:self.context];
_XWDisplayRatioLayer *layer = [_XWDisplayRatioLayer new];
_ratioLayer = layer;
_ratioLayer.frame = CGRectMake(0, 0, 100, 100);
__weak typeof(self)weakSelf = self;
_ratioLayer.ratioUpdating = ^(CGFloat ratio){
weakSelf.ratio = ratio;
[weakSelf setNeedsDisplay];
};
[self.layer insertSublayer:_ratioLayer atIndex:0];
self.delegate = self;
return self;
}
- (CAAnimation *)_xw_filterBasicAnimation{
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"ratio"];
animation.fromValue = @0;
animation.toValue = @1;
return animation;
}
- (CIImage *)_xw_filterBasicImageForTransition
{
[_filter setValue:_fromImg forKey:kCIInputImageKey];
[_filter setValue:_toImg forKey:kCIInputTargetImageKey];
[_filter setValue:@(_ratio) forKey:kCIInputTimeKey];
CIImage *transitionImage = [_filter valueForKey:kCIOutputImageKey];
return transitionImage;
}
- (CIImage *)_xw_filterBlurImageForTransition{
CGFloat radius = 0;
if (_ratio < 0.5) {
[_filter setValue:_fromImg forKey:kCIInputImageKey];
radius = _ratio * 0.5 * 200;
}
else {
[_filter setValue:_toImg forKey:kCIInputImageKey];
radius = (1.0 - _ratio) * 200;
}
[_filter setValue:@(radius) forKey:kCIInputRadiusKey];
CIImage *transitionImage = [_filter valueForKey:kCIOutputImageKey];
return transitionImage;
}
- (void)_xw_filterViewDoAnimation:(NSTimeInterval)duration completion:(void (^ __nullable)(BOOL finished))completion{
_completion = completion;
CAAnimation *animation = [self _xw_filterBasicAnimation];
animation.duration = duration;
animation.delegate = self;
[_ratioLayer addAnimation:animation forKey:@"xw_filterAnimation"];
}
#pragma mark - <GLKViewDelegate>
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect{
if (_ratio >= 1 || _ratio <= 0) {
_ratio = _lastRatio > 0.5 ? 1 : 0;
}
if (!_filter) return;
CIImage *image = _blurType ? [self _xw_filterBlurImageForTransition] : [self _xw_filterBasicImageForTransition];
if (!image) return;
CGFloat scale = [[UIScreen mainScreen] scale];
CGRect nativeBounds = [[UIScreen mainScreen] nativeBounds];
CGRect destRect = CGRectMake(0, self.bounds.size.height * scale - _imgRect.size.height,
nativeBounds.size.width,
nativeBounds.size.height);
[_saveContext drawImage:image
inRect:destRect
fromRect:_imgRect];
_lastRatio = _ratio;
}
#pragma mark - <CAAnimationDelegate>
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
if (_completion) {
_completion(flag);
}
_completion = nil;
}
+ (void)xw_animationWith:(XWFilterTransitionView *)filterView duration:(NSTimeInterval)duration completion:(void (^ __nullable)(BOOL finished))completion {
[filterView _xw_filterViewDoAnimation:duration completion:completion];
}
- (CAAnimation *)xw_getInnerAnimation {
return [self _xw_filterBasicAnimation];
}
- (CIVector *)xw_getInnerVector {
return _vector;
}
@end
//
// XWMagicMoveAnimator.h
// XWTADemo
//
// Created by wazrx on 16/6/8.
// Copyright © 2016年 wazrx. All rights reserved.
// 神奇移动效果请配合UIViewController+XWTransition中的相关API使用,如果神奇移动的终止视图为cell,需要参考一下demo中的九宫格例子
#import "XWTransitionAnimator.h"
NS_ASSUME_NONNULL_BEGIN
@interface UIView (XWTransition)
//神奇移动的时候,如果对设置view的该属性为YES,则移动视图不会按照截图的方式生成,而且尝试直接取得其image(暂时支持imageView、button等),解决神奇移动从下到大会产生模糊的情况
@property (nonatomic, assign) BOOL magicMoveImageMode;
@end
@interface XWMagicMoveAnimator : XWTransitionAnimator
//是否开启弹簧效果
@property (nonatomic, assign) BOOL dampingEnable;
//设为YES后,对于做神奇移动数组中的所有View会直接取其图片而不会截图,可解决神奇移动从小变得较大的时候,截图不清晰的问题,如果想要对单个view最该设置,请参考上面的UIView分类的magicMoveImageMode属性
@property (nonatomic, assign) BOOL imageMode;
@end
UIKIT_EXTERN NSString *const kXWMagicMoveAnimatorStartViewVCKey;
UIKIT_EXTERN NSString *const kXWMagicMoveAnimatorEndViewVCKey;
NS_ASSUME_NONNULL_END
\ No newline at end of file
//
// XWMagicMoveAnimator.m
// XWTADemo
//
// Created by wazrx on 16/6/8.
// Copyright © 2016年 wazrx. All rights reserved.
//
#import "XWMagicMoveAnimator.h"
#import <objc/runtime.h>
static NSString *const kXWMagicMovePropertyInViewKey = @"kXWMagicMovePropertyInViewKey";
@implementation UIView (XWTransition)
- (void)setMagicMoveImageMode:(BOOL)magicMoveImageMode{
objc_setAssociatedObject(self, &kXWMagicMovePropertyInViewKey, @(magicMoveImageMode), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (BOOL)magicMoveImageMode{
return [objc_getAssociatedObject(self, &kXWMagicMovePropertyInViewKey) boolValue];
}
@end
@implementation XWMagicMoveAnimator
- (void)xw_setToAnimation:(id<UIViewControllerContextTransitioning>)transitionContext{
[self _xw_doAniamtionWithContext:transitionContext fromFlag:YES];
}
- (void)xw_setBackAnimation:(id<UIViewControllerContextTransitioning>)transitionContext{
[self _xw_doAniamtionWithContext:transitionContext fromFlag:NO];
}
-(void)_xw_doAniamtionWithContext:(id<UIViewControllerContextTransitioning>)transitionContext fromFlag:(BOOL)flag{
UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIViewController *realFromVC = [self _xw_getRealContainsGroupViewController:fromVC];
UIViewController *realToVC = [self _xw_getRealContainsGroupViewController:toVC];
NSArray<UIView *> *startViewGroup = objc_getAssociatedObject(realFromVC, flag ? &kXWMagicMoveAnimatorStartViewVCKey : &kXWMagicMoveAnimatorEndViewVCKey);
NSArray<UIView *> *endViewGroup = objc_getAssociatedObject(realToVC, !flag ? &kXWMagicMoveAnimatorStartViewVCKey : &kXWMagicMoveAnimatorEndViewVCKey);
if (!startViewGroup.count || !endViewGroup.count || startViewGroup.count != endViewGroup.count) {
NSLog(@"神奇移动的视图为空,或者移动前后视图不相等");
[transitionContext completeTransition:NO];
return;
}
UIView *containerView = [transitionContext containerView];
toVC.view.alpha = 0.0f;
[containerView addSubview:toVC.view];
NSArray *toRects = [self _xw_getFrameValueFromViewGroup:endViewGroup inContainerView:containerView];
NSArray<UIView *> *tempViewGroup = [self _xw_makeTempViewGroupWithViewGroup:startViewGroup inContainerView:containerView];
[self _xw_changeHiddenViewInGroup:startViewGroup hidden:YES];
[self _xw_changeHiddenViewInGroup:endViewGroup hidden:YES];
if (self.dampingEnable) {
[UIView animateWithDuration:flag ? self.toDuration : self.backDuration delay:0.0f usingSpringWithDamping:0.55 initialSpringVelocity:1 / 0.55 options:UIViewAnimationOptionCurveLinear animations:^{
fromVC.view.alpha = 0.0f;
toVC.view.alpha = 1.0f;
[tempViewGroup enumerateObjectsUsingBlock:^(UIView *tempSubView, NSUInteger idx, BOOL * _Nonnull stop) {
CGRect toRect = [toRects[idx] CGRectValue];
tempSubView.frame = toRect;
}];
} completion:^(BOOL finished) {
[tempViewGroup makeObjectsPerformSelector:@selector(removeFromSuperview)];
fromVC.view.alpha = 1.0f;
[self _xw_changeHiddenViewInGroup:startViewGroup hidden:NO];
[self _xw_changeHiddenViewInGroup:endViewGroup hidden:NO];
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}else{
[UIView animateWithDuration:flag ? self.toDuration : self.backDuration animations:^{
fromVC.view.alpha = 0.0f;
toVC.view.alpha = 1.0f;
[tempViewGroup enumerateObjectsUsingBlock:^(UIView *tempSubView, NSUInteger idx, BOOL * _Nonnull stop) {
CGRect toRect = [toRects[idx] CGRectValue];
tempSubView.frame = toRect;
}];
} completion:^(BOOL finished) {
[tempViewGroup makeObjectsPerformSelector:@selector(removeFromSuperview)];
fromVC.view.alpha = 1.0f;
[self _xw_changeHiddenViewInGroup:startViewGroup hidden:NO];
[self _xw_changeHiddenViewInGroup:endViewGroup hidden:NO];
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}
}
/**
* 判断当前控制器的类型,从而找到从出存有移动视图组的控制器
*/
- (UIViewController *)_xw_getRealContainsGroupViewController:(UIViewController *)controller{
UIViewController *realVC = controller;
if ([controller isKindOfClass:[UITabBarController class]]) {
UITabBarController *tabBarVC = (UITabBarController *)realVC;
if ([tabBarVC.selectedViewController isKindOfClass:[UINavigationController class]]) {
UINavigationController *navVC = (UINavigationController *)tabBarVC.selectedViewController;
realVC = navVC.topViewController;
}else{
realVC = tabBarVC.selectedViewController;
}
}
if ([controller isKindOfClass:[UINavigationController class]]) {
UINavigationController *navVC = (UINavigationController *)controller;
realVC = navVC.topViewController;
}
return realVC;
}
- (NSArray *)_xw_getFrameValueFromViewGroup:(NSArray<UIView *> *)group inContainerView:(UIView *)containerView{
NSMutableArray *temp = @[].mutableCopy;
[group enumerateObjectsUsingBlock:^(UIView *view, NSUInteger idx, BOOL * _Nonnull stop) {
CGRect rect = [view convertRect:view.bounds toView:containerView];
[temp addObject:[NSValue valueWithCGRect:rect]];
}];
return temp.copy;
}
- (NSArray<UIView *> *)_xw_makeTempViewGroupWithViewGroup:(NSArray<UIView *> *)group inContainerView:(UIView *)containerView{
NSMutableArray *temp = @[].mutableCopy;
[group enumerateObjectsUsingBlock:^(UIView *view, NSUInteger idx, BOOL * _Nonnull stop) {
UIView *tempView = [self _xw_snapshotView:view];
tempView.frame = [view convertRect:view.bounds toView:containerView];
[containerView addSubview:tempView];
[temp addObject:tempView];
}];
return temp.copy;
}
- (void)_xw_changeHiddenViewInGroup:(NSArray<UIView *> *)group hidden:(BOOL)flag{
[group enumerateObjectsUsingBlock:^(UIView * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
obj.hidden = flag;
}];
}
- (UIView *)_xw_snapshotView:(UIView *)view{
CALayer *layer = view.layer;
UIView *snapView = [UIView new];
snapView.frame = view.frame;
BOOL imgMode = [objc_getAssociatedObject(view, &kXWMagicMovePropertyInViewKey) boolValue] || _imageMode;
UIImage *img = nil;
if (imgMode) {//如果开启imgMode,优先直接获取图片,避免截图时时从小到大造成的模糊
if ([view isKindOfClass:[UIImageView class]]) {//取imageView中的image
img = [(UIImageView *)view image];
}else if ([view isKindOfClass:[UIButton class]]){//取button中的image
img = [(UIButton *)view currentImage];
}
if (!img && [view isKindOfClass:[UIView class]]) {//没取到尝试取content
img = [UIImage imageWithCGImage:(__bridge CGImageRef)view.layer.contents];
}
}
//若都没有取到,则截图
if (!img) {
UIGraphicsBeginImageContextWithOptions(layer.bounds.size, layer.opaque, 0);
CGContextRef context = UIGraphicsGetCurrentContext();
[layer renderInContext:context];
img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
snapView.layer.contents = (__bridge id)img.CGImage;
return snapView;
}
@end
NSString *const kXWMagicMoveAnimatorStartViewVCKey = @"kXWMagicMoveAnimatorStartViewVCKey";
NSString *const kXWMagicMoveAnimatorEndViewVCKey = @"kXWMagicMoveAnimatorEndViewVCKey";
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment