Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
GMBase
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
gengmeiios
GMBase
Commits
86d3092a
Commit
86d3092a
authored
Apr 08, 2020
by
汪洋
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
使用协议来添加 navigion 动画
parent
3e4f79e9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
118 additions
and
48 deletions
+118
-48
Podfile.lock
Example/Podfile.lock
+4
-4
GMCustomNavigationAnimationProtocol.h
GMBase/Classes/GMCustomNavigationAnimationProtocol.h
+50
-0
GMNavigationController.h
GMBase/Classes/GMNavigationController.h
+1
-0
GMNavigationController.m
GMBase/Classes/GMNavigationController.m
+12
-13
GMPresentAnimation.h
GMBase/Classes/GMPresentAnimation.h
+8
-4
GMPresentAnimation.m
GMBase/Classes/GMPresentAnimation.m
+20
-14
UIViewController+PushType.h
GMBase/Classes/UIViewController+PushType.h
+0
-2
UIViewController+PushType.m
GMBase/Classes/UIViewController+PushType.m
+3
-11
GMCustomNavigationAnimationProtocol.h
GMCustomNavigationAnimationProtocol.h
+20
-0
No files found.
Example/Podfile.lock
View file @
86d3092a
...
@@ -14,7 +14,7 @@ PODS:
...
@@ -14,7 +14,7 @@ PODS:
- AFNetworking/Serialization (3.1.0)
- AFNetworking/Serialization (3.1.0)
- AFNetworking/UIKit (3.1.0):
- AFNetworking/UIKit (3.1.0):
- AFNetworking/NSURLSession
- AFNetworking/NSURLSession
- GMBase (1.1.
4
):
- GMBase (1.1.
5
):
- GMHud
- GMHud
- GMJSONModel
- GMJSONModel
- GMKit
- GMKit
...
@@ -90,7 +90,7 @@ SPEC REPOS:
...
@@ -90,7 +90,7 @@ SPEC REPOS:
- GMNetService
- GMNetService
- GMPhobos
- GMPhobos
- GMRefresh
- GMRefresh
https://github.com/
cocoapods/s
pecs.git:
https://github.com/
CocoaPods/S
pecs.git:
- AFNetworking
- AFNetworking
- Masonry
- Masonry
- MBProgressHUD
- MBProgressHUD
...
@@ -104,7 +104,7 @@ EXTERNAL SOURCES:
...
@@ -104,7 +104,7 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
SPEC CHECKSUMS:
AFNetworking: 5e0e199f73d8626b11e79750991f5d173d1f8b67
AFNetworking: 5e0e199f73d8626b11e79750991f5d173d1f8b67
GMBase:
aa92f9e566cc5807d1c1439d3e8c588b5b413a7
e
GMBase:
b747cd3ecd7a5109469113cf48ce04ae6d16cdb
e
GMCache: b78d8e46db864405e91d226ce640cc80d966c611
GMCache: b78d8e46db864405e91d226ce640cc80d966c611
GMHud: 45aa755b72a65f89d810430336803086359c0fb1
GMHud: 45aa755b72a65f89d810430336803086359c0fb1
GMJSONModel: 5e81a98de668e9f93cf6ff77869f77b0d1a806be
GMJSONModel: 5e81a98de668e9f93cf6ff77869f77b0d1a806be
...
@@ -120,4 +120,4 @@ SPEC CHECKSUMS:
...
@@ -120,4 +120,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: b9c24bb8fb1ea50b58c59e079b456b4ca1d9b998
PODFILE CHECKSUM: b9c24bb8fb1ea50b58c59e079b456b4ca1d9b998
COCOAPODS: 1.
7.4
COCOAPODS: 1.
9.1
GMBase/Classes/GMCustomNavigationAnimationProtocol.h
0 → 100644
View file @
86d3092a
//
// GMCustomNavigationAnimationProtocol.h
// Pods
//
// Created by wangyang on 2020/4/7.
//
#ifndef GMCustomNavigationAnimationProtocol_h
#define GMCustomNavigationAnimationProtocol_h
/// 通过此协议来约束所有自定义 navigation 动画类的行为。
@protocol
GMControllerAnimatedTransitioning
<
UIViewControllerAnimatedTransitioning
>
/// 自定义 navigation 动画类需要知道某一时刻是 push还是pop。
@property
(
nonatomic
,
assign
)
UINavigationControllerOperation
transitionType
;
@end
/// 对于想要使用自定义 push、pop 动画的 controller,需要实现该协议。
/// GMNavigationController 会检查 controller 是否实现该协议以决定是否要使用自定义动画
/// 该协议要求controller 需要实现一个属性,
/// 并且要求该属性也需要实现一个协议:GMControllerAnimatedTransitioning。
/// 该属于会用在 GMNavigationController中,具体逻辑请自行查找。
/// 下面有一个 Demo
@protocol
GMCustomNavigationAnimationProtocol
<
NSObject
>
@property
(
nonatomic
,
strong
)
id
<
GMControllerAnimatedTransitioning
>
navigationAnimation
;
@end
#endif
/* Demo
// 挂载协议
@interface GMController () <GMCustomNavigationAnimationProtocol>
@end
@implementation GMController
// 使用synthesize确保协议中要求的属性有正确的 set 和 get 方法
@synthesize navigationAnimation;
- (void)initController {
[super initController];
// 为协议中要求的属性赋值
GMPresentAnimation *navigationAnimation = [GMPresentAnimation new];
navigationAnimation.needMask = YES;
self.navigationAnimation = navigationAnimation;
}
*/
GMBase/Classes/GMNavigationController.h
View file @
86d3092a
...
@@ -9,6 +9,7 @@
...
@@ -9,6 +9,7 @@
#import <UIKit/UIKit.h>
#import <UIKit/UIKit.h>
@interface
GMNavigationController
:
UINavigationController
@interface
GMNavigationController
:
UINavigationController
// TODO: wangyang 这个属性的历史需要找人了解清楚,缺少对应的注释
@property
(
nonatomic
,
assign
)
BOOL
needPopPresetAnimation
;
@property
(
nonatomic
,
assign
)
BOOL
needPopPresetAnimation
;
@end
@end
GMBase/Classes/GMNavigationController.m
View file @
86d3092a
...
@@ -10,6 +10,8 @@
...
@@ -10,6 +10,8 @@
#import "UIViewController+PushType.h"
#import "UIViewController+PushType.h"
#import "GMPresentAnimation.h"
#import "GMPresentAnimation.h"
@import
GMKit
;
@import
GMKit
;
#import "GMCustomNavigationAnimationProtocol.h"
@interface
GMNavigationController
()
<
UINavigationControllerDelegate
>
@interface
GMNavigationController
()
<
UINavigationControllerDelegate
>
...
@@ -27,31 +29,28 @@
...
@@ -27,31 +29,28 @@
animationControllerForOperation
:
(
UINavigationControllerOperation
)
operation
animationControllerForOperation
:
(
UINavigationControllerOperation
)
operation
fromViewController
:
(
UIViewController
*
)
fromVC
fromViewController
:
(
UIViewController
*
)
fromVC
toViewController
:
(
UIViewController
*
)
toVC
{
toViewController
:
(
UIViewController
*
)
toVC
{
if
(
operation
==
UINavigationControllerOperationPush
&&
[
toVC
conformsToProtocol
:
@protocol
(
GMCustomNavigationAnimationProtocol
)])
{
if
(
operation
==
UINavigationControllerOperationPush
&&
toVC
.
isPresent
)
{
id
<
GMCustomNavigationAnimationProtocol
>
controller
=
(
id
<
GMCustomNavigationAnimationProtocol
>
)
toVC
;
GMPresentAnimation
*
animation
=
[[
GMPresentAnimation
alloc
]
init
]
;
id
<
GMControllerAnimatedTransitioning
>
animation
=
controller
.
navigationAnimation
;
animation
.
transitionType
=
operation
;
animation
.
transitionType
=
operation
;
return
animation
;
return
animation
;
}
else
if
(
operation
==
UINavigationControllerOperationPop
&&
(
fromVC
.
isPresent
||
self
.
needPopPresetAnimation
))
{
}
else
if
(
operation
==
UINavigationControllerOperationPop
&&
([
fromVC
conformsToProtocol
:
@protocol
(
GMCustomNavigationAnimationProtocol
)]
||
self
.
needPopPresetAnimation
))
{
_needPopPresetAnimation
=
NO
;
id
<
GMCustomNavigationAnimationProtocol
>
controller
=
(
id
<
GMCustomNavigationAnimationProtocol
>
)
fromVC
;
GMPresentAnimation
*
animation
=
[[
GMPresentAnimation
alloc
]
init
]
;
id
<
GMControllerAnimatedTransitioning
>
animation
=
controller
.
navigationAnimation
;
animation
.
transitionType
=
operation
;
animation
.
transitionType
=
operation
;
return
animation
;
return
animation
;
}
}
return
nil
;
return
nil
;
}
}
// 依据supportedInterfaceOrientations文档,控制旋转的代码需要写在root view controller,或者全屏的presenting controller
// 依据supportedInterfaceOrientations文档,控制旋转的代码需要写在root view controller,或者全屏的presenting controller
// app的root view controller就是这个GMNavigationController,所以相关控制代码在这里。
// app的root view controller就是这个GMNavigationController,所以相关控制代码在这里。
-
(
BOOL
)
shouldAutorotate
-
(
BOOL
)
shouldAutorotate
{
{
return
NO
;
return
NO
;
}
}
-
(
UIInterfaceOrientationMask
)
supportedInterfaceOrientations
-
(
UIInterfaceOrientationMask
)
supportedInterfaceOrientations
{
{
return
UIInterfaceOrientationMaskPortrait
;
return
UIInterfaceOrientationMaskPortrait
;
}
}
@end
@end
GMBase/Classes/GMPresentAnimation.h
View file @
86d3092a
...
@@ -6,9 +6,13 @@
...
@@ -6,9 +6,13 @@
// Copyright © 2017年 更美互动信息科技有限公司. All rights reserved.
// Copyright © 2017年 更美互动信息科技有限公司. All rights reserved.
//
//
#import <Foundation/Foundation.h>
#import "GMCustomNavigationAnimationProtocol.h"
/// 模拟 presentController 动画
/// push 时下往上的位移动画,pop 时从上往下的位移动画
@interface
GMPresentAnimation
:
NSObject
<
GMControllerAnimatedTransitioning
>
// 当 needMask = YES 时,会一个透明 mask 将 fromVC 与 toVC 隔开。默认为 NO。
@property
(
nonatomic
,
assign
)
BOOL
needMask
;
// 通过使用GMPresentAnimation,来自定义 push 动画
@interface
GMPresentAnimation
:
NSObject
<
UIViewControllerAnimatedTransitioning
>
@property
(
nonatomic
,
assign
)
UINavigationControllerOperation
transitionType
;
@end
@end
GMBase/Classes/GMPresentAnimation.m
View file @
86d3092a
...
@@ -8,15 +8,19 @@
...
@@ -8,15 +8,19 @@
#import "GMPresentAnimation.h"
#import "GMPresentAnimation.h"
#import "UIViewController+PushType.h"
#import "UIViewController+PushType.h"
@interface
GMPresentAnimation
()
@interface
GMPresentAnimation
()
{
/// 与 needMask 属性配合使用。当 needMask = YES 时,_mask 将会展示在 fromVC 与 toVC 层级的中间。默认不展示。
UIView
*
_mask
;
}
@property
(
nonatomic
,
assign
)
NSTimeInterval
duration
;
@property
(
nonatomic
,
assign
)
NSTimeInterval
duration
;
@end
@end
@implementation
GMPresentAnimation
@implementation
GMPresentAnimation
@synthesize
transitionType
;
-
(
instancetype
)
init
{
-
(
instancetype
)
init
{
// 默认 push 动画时间0.6
if
(
self
=
[
super
init
])
{
if
(
self
=
[
super
init
])
{
self
.
duration
=
0
.
3
;
self
.
duration
=
0
.
3
;
self
.
needMask
=
NO
;
}
}
return
self
;
return
self
;
}
}
...
@@ -33,11 +37,12 @@
...
@@ -33,11 +37,12 @@
[[
transitionContext
containerView
]
addSubview
:
fromVC
.
snapshot
];
[[
transitionContext
containerView
]
addSubview
:
fromVC
.
snapshot
];
// 添加一个半透明的蒙层,展示在 from view 下面
// 添加一个半透明的蒙层,展示在 from view 下面
UIView
*
mask
=
[[
UIView
alloc
]
initWithFrame
:
bounds
];
_mask
=
[[
UIView
alloc
]
initWithFrame
:
bounds
];
mask
.
backgroundColor
=
[
UIColor
colorWithWhite
:
0
alpha
:
0
.
64
];
_mask
.
backgroundColor
=
[
UIColor
colorWithWhite
:
0
alpha
:
0
.
64
];
mask
.
alpha
=
0
;
_mask
.
alpha
=
0
;
mask
.
tag
=
100
;
if
(
self
.
needMask
)
{
[[
transitionContext
containerView
]
addSubview
:
mask
];
[[
transitionContext
containerView
]
addSubview
:
_mask
];
}
// 系统不会为我们自动添加 toView,所以我们需要自己添加,以保证 toView 的页面及动画正常展示
// 系统不会为我们自动添加 toView,所以我们需要自己添加,以保证 toView 的页面及动画正常展示
[[
transitionContext
containerView
]
addSubview
:
toView
];
[[
transitionContext
containerView
]
addSubview
:
toView
];
...
@@ -50,7 +55,7 @@
...
@@ -50,7 +55,7 @@
// 从下到上的平移动画
// 从下到上的平移动画
[
UIView
animateWithDuration
:[
self
transitionDuration
:
transitionContext
]
animations
:
^
{
[
UIView
animateWithDuration
:[
self
transitionDuration
:
transitionContext
]
animations
:
^
{
toView
.
frame
=
bounds
;
toView
.
frame
=
bounds
;
mask
.
alpha
=
1
;
_
mask
.
alpha
=
1
;
}
completion
:^
(
BOOL
finished
)
{
}
completion
:^
(
BOOL
finished
)
{
[
transitionContext
completeTransition
:
YES
];
[
transitionContext
completeTransition
:
YES
];
}];
}];
...
@@ -63,8 +68,8 @@
...
@@ -63,8 +68,8 @@
UIView
*
toView
=
[
transitionContext
viewForKey
:
UITransitionContextToViewKey
];
UIView
*
toView
=
[
transitionContext
viewForKey
:
UITransitionContextToViewKey
];
// 必须把先前的 mask view 拿出来,显示的标记为 alpha = 1,要不然会发现该蒙层是突然消失
// 必须把先前的 mask view 拿出来,显示的标记为 alpha = 1,要不然会发现该蒙层是突然消失
// 经
常
打断点发现,其 alpha 此时为0,所以必须要设置一下 alpha = 1
// 经打断点发现,其 alpha 此时为0,所以必须要设置一下 alpha = 1
[[
transitionContext
containerView
]
viewWithTag
:
100
]
.
alpha
=
1
;
_mask
.
alpha
=
1
;
//将toView加到toVC.snapshot 的的下面。
//将toView加到toVC.snapshot 的的下面。
// 不加的话,动画结束后看不到 toView
// 不加的话,动画结束后看不到 toView
...
@@ -77,9 +82,11 @@
...
@@ -77,9 +82,11 @@
newFrame
.
origin
.
y
=
CGRectGetHeight
(
bound
);
newFrame
.
origin
.
y
=
CGRectGetHeight
(
bound
);
[
UIView
animateWithDuration
:[
self
transitionDuration
:
transitionContext
]
animations
:
^
{
[
UIView
animateWithDuration
:[
self
transitionDuration
:
transitionContext
]
animations
:
^
{
fromView
.
frame
=
newFrame
;
fromView
.
frame
=
newFrame
;
[[
transitionContext
containerView
]
viewWithTag
:
100
]
.
alpha
=
0
;
_mask
.
alpha
=
0
;
}
completion
:^
(
BOOL
finished
)
{
}
completion
:^
(
BOOL
finished
)
{
[[[
transitionContext
containerView
]
viewWithTag
:
100
]
removeFromSuperview
];
if
(
self
.
needMask
)
{
[
_mask
removeFromSuperview
];
}
// 动画结束后移除toVC.snapshot,留着会挡住toVC,用户无法交互
// 动画结束后移除toVC.snapshot,留着会挡住toVC,用户无法交互
[
toVC
.
snapshot
removeFromSuperview
];
[
toVC
.
snapshot
removeFromSuperview
];
// 需要将toVC.snapshot清空,下一次弹窗时再重新生成 snapshot,确保每一次 snapshot 为最新画面
// 需要将toVC.snapshot清空,下一次弹窗时再重新生成 snapshot,确保每一次 snapshot 为最新画面
...
@@ -88,8 +95,7 @@
...
@@ -88,8 +95,7 @@
}];
}];
}
}
-
(
NSTimeInterval
)
transitionDuration
:
(
nullable
id
<
UIViewControllerContextTransitioning
>
)
transitionContext
-
(
NSTimeInterval
)
transitionDuration
:
(
nullable
id
<
UIViewControllerContextTransitioning
>
)
transitionContext
{
{
return
self
.
duration
;
return
self
.
duration
;
}
}
...
...
GMBase/Classes/UIViewController+PushType.h
View file @
86d3092a
...
@@ -10,7 +10,5 @@
...
@@ -10,7 +10,5 @@
@interface
UIViewController
(
Push
)
@interface
UIViewController
(
Push
)
@property
(
nonatomic
,
strong
)
UIView
*
snapshot
;
@property
(
nonatomic
,
strong
)
UIView
*
snapshot
;
//push type是否是模态动画
@property
(
nonatomic
,
assign
)
BOOL
isPresent
;
-
(
void
)
popToPresentPreviousController
;
-
(
void
)
popToPresentPreviousController
;
@end
@end
GMBase/Classes/UIViewController+PushType.m
View file @
86d3092a
...
@@ -9,6 +9,7 @@
...
@@ -9,6 +9,7 @@
#import "UIViewController+PushType.h"
#import "UIViewController+PushType.h"
#import <objc/runtime.h>
#import <objc/runtime.h>
#import "GMNavigationController.h"
#import "GMNavigationController.h"
#import "GMCustomNavigationAnimationProtocol.h"
@implementation
UIViewController
(
PushType
)
@implementation
UIViewController
(
PushType
)
-
(
UIView
*
)
snapshot
-
(
UIView
*
)
snapshot
...
@@ -26,20 +27,11 @@
...
@@ -26,20 +27,11 @@
objc_setAssociatedObject
(
self
,
@"gmSnapshot"
,
snapshot
,
OBJC_ASSOCIATION_RETAIN_NONATOMIC
);
objc_setAssociatedObject
(
self
,
@"gmSnapshot"
,
snapshot
,
OBJC_ASSOCIATION_RETAIN_NONATOMIC
);
}
}
-
(
BOOL
)
isPresent
{
// TODO: wangyang 从 release 分支看一下此处的逻辑,查清此处应该怎么改
return
[
objc_getAssociatedObject
(
self
,
@"gmIsPresent"
)
boolValue
];
}
-
(
void
)
setIsPresent
:
(
BOOL
)
isPresent
{
objc_setAssociatedObject
(
self
,
@"gmIsPresent"
,
[
NSNumber
numberWithBool
:
isPresent
],
OBJC_ASSOCIATION_RETAIN_NONATOMIC
);
}
-
(
void
)
popToPresentPreviousController
{
-
(
void
)
popToPresentPreviousController
{
for
(
int
index
=
0
;
index
<
self
.
navigationController
.
viewControllers
.
count
;
index
++
)
{
for
(
int
index
=
0
;
index
<
self
.
navigationController
.
viewControllers
.
count
;
index
++
)
{
UIViewController
*
controller
=
self
.
navigationController
.
viewControllers
[
index
];
UIViewController
*
controller
=
self
.
navigationController
.
viewControllers
[
index
];
if
(
controller
.
isPresent
)
{
if
([
controller
conformsToProtocol
:
@protocol
(
GMCustomNavigationAnimationProtocol
)])
{
GMNavigationController
*
nav
=
(
GMNavigationController
*
)
self
.
navigationController
;
nav
.
needPopPresetAnimation
=
YES
;
UIViewController
*
previewController
=
self
.
navigationController
.
viewControllers
[
index
-
1
];
UIViewController
*
previewController
=
self
.
navigationController
.
viewControllers
[
index
-
1
];
[
controller
.
navigationController
popToViewController
:
previewController
animated
:
YES
];
[
controller
.
navigationController
popToViewController
:
previewController
animated
:
YES
];
return
;
return
;
...
...
GMCustomNavigationAnimationProtocol.h
0 → 100644
View file @
86d3092a
//
// GMCustomNavigationAnimationProtocol.h
// Pods
//
// Created by wangyang on 2020/4/7.
//
#ifndef GMCustomNavigationAnimationProtocol_h
#define GMCustomNavigationAnimationProtocol_h
@protocol
GMControllerAnimatedTransitioning
<
UIViewControllerAnimatedTransitioning
>
@property
(
nonatomic
,
assign
)
UINavigationControllerOperation
transitionType
;
@end
@protocol
GMCustomNavigationAnimationProtocol
<
NSObject
>
@property
(
nonatomic
,
strong
)
id
<
GMControllerAnimatedTransitioning
>
navigationAnimation
;
@end
#endif
/* GMCustomNavigationAnimationProtocol_h */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment