Commit 401aef70 authored by luyueming's avatar luyueming

Merge branch 'master' into lym/text

* master:
  删除没有用的代码
  增加数组越界判断
  使用协议来添加 navigion 动画
  GMPresentAnimation 初步成型,但是还需要拆分
  优化 present 动画
  Bump version to 1.1.5
  add WMFetchDataViewModel+GMRequest.h
  add WMFetchDataViewModel+GMRequest.h
  Bump version to 1.1.4
  基类初始化referrer_link

# Conflicts:
#	GMBase/Classes/GMNavigationController.m
冲突
parents 56c6bb56 4a4ba4ae
......@@ -14,7 +14,7 @@ PODS:
- AFNetworking/Serialization (3.1.0)
- AFNetworking/UIKit (3.1.0):
- AFNetworking/NSURLSession
- GMBase (1.0.8):
- GMBase (1.1.5):
- GMHud
- GMJSONModel
- GMKit
......@@ -65,7 +65,7 @@ PODS:
- SDWebImage
- GMNetService (1.0.2):
- AFNetworking (= 3.1.0)
- GMPhobos (1.3.0):
- GMPhobos (1.3.5):
- GMCache
- GMKit
- GMRefresh (1.0.2):
......@@ -90,7 +90,7 @@ SPEC REPOS:
- GMNetService
- GMPhobos
- GMRefresh
https://github.com/cocoapods/specs.git:
https://github.com/CocoaPods/Specs.git:
- AFNetworking
- Masonry
- MBProgressHUD
......@@ -104,13 +104,13 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
AFNetworking: 5e0e199f73d8626b11e79750991f5d173d1f8b67
GMBase: ad83ba98fe54c94ce29a0392c28a64cdf7be2e9c
GMBase: b747cd3ecd7a5109469113cf48ce04ae6d16cdbe
GMCache: b78d8e46db864405e91d226ce640cc80d966c611
GMHud: 45aa755b72a65f89d810430336803086359c0fb1
GMJSONModel: 5e81a98de668e9f93cf6ff77869f77b0d1a806be
GMKit: 11c9ab9a317f381a05b0e1e577dd95a495625edf
GMNetService: 7c69e7981b4fac29657fad5fc86a0c453196b862
GMPhobos: 7aec8c5025c2f67798a46fb1570e5ebb4ebfd06a
GMPhobos: 1e2d68c456b69bf156276d7242877498107474db
GMRefresh: 9d2c521e3d49b68d3c736fb138a87fae4adb05f9
Masonry: 678fab65091a9290e40e2832a55e7ab731aad201
MBProgressHUD: 1569cf7ace17a8bac47aabfbb8580a49690386d1
......@@ -120,4 +120,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: b9c24bb8fb1ea50b58c59e079b456b4ca1d9b998
COCOAPODS: 1.7.4
COCOAPODS: 1.9.1
Pod::Spec.new do |s|
s.name = 'GMBase'
s.version = '1.1.3'
s.version = '1.1.5'
s.summary = '更美iOS APP 的 Objective-C 基础Pod库'
s.homepage = 'http://git.wanmeizhensuo.com/gengmeiios/GMBase'
s.license = '仅限北京更美互动信息科技有限公司内部使用'
......
//
// 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;
}
*/
......@@ -9,6 +9,5 @@
#import <UIKit/UIKit.h>
@interface GMNavigationController : UINavigationController
@property (nonatomic, assign) BOOL needPopPresetAnimation;
@end
......@@ -9,7 +9,8 @@
#import "GMNavigationController.h"
#import "UIViewController+PushType.h"
#import "GMPresentAnimation.h"
//@import GMKit;
#import "GMCustomNavigationAnimationProtocol.h"
@import GMKit;
@interface GMNavigationController ()<UINavigationControllerDelegate>
......@@ -27,31 +28,28 @@
animationControllerForOperation:(UINavigationControllerOperation)operation
fromViewController:(UIViewController *)fromVC
toViewController:(UIViewController *)toVC {
if (operation == UINavigationControllerOperationPush && toVC.isPresent) {
GMPresentAnimation *animation = [[GMPresentAnimation alloc] init];
animation.transitionType = operation;
if (operation == UINavigationControllerOperationPush && [toVC conformsToProtocol:@protocol(GMCustomNavigationAnimationProtocol)]) {
id<GMCustomNavigationAnimationProtocol> controller = (id<GMCustomNavigationAnimationProtocol>)toVC;
id<GMControllerAnimatedTransitioning> animation = controller.navigationAnimation;
animation.transitionType = operation;
return animation;
} else if (operation == UINavigationControllerOperationPop && (fromVC.isPresent || self.needPopPresetAnimation)) {
_needPopPresetAnimation = NO;
GMPresentAnimation *animation = [[GMPresentAnimation alloc] init];
animation.transitionType = operation;
} else if (operation == UINavigationControllerOperationPop && [fromVC conformsToProtocol:@protocol(GMCustomNavigationAnimationProtocol)] ) {
id<GMCustomNavigationAnimationProtocol> controller = (id<GMCustomNavigationAnimationProtocol>)fromVC;
id<GMControllerAnimatedTransitioning> animation = controller.navigationAnimation;
animation.transitionType = operation;
return animation;
}
return nil;
return nil;
}
// 依据supportedInterfaceOrientations文档,控制旋转的代码需要写在root view controller,或者全屏的presenting controller
// app的root view controller就是这个GMNavigationController,所以相关控制代码在这里。
- (BOOL)shouldAutorotate
{
- (BOOL)shouldAutorotate {
return NO;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
@end
......@@ -6,8 +6,13 @@
// 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;
@interface GMPresentAnimation : NSObject<UIViewControllerAnimatedTransitioning>
@property(nonatomic,assign)UINavigationControllerOperation transitionType;
@end
......@@ -8,131 +8,101 @@
#import "GMPresentAnimation.h"
#import "UIViewController+PushType.h"
@interface GMPresentAnimation() <UIViewControllerAnimatedTransitioning>
@property(nonatomic,assign)NSTimeInterval duration;
@interface GMPresentAnimation () {
/// 与 needMask 属性配合使用。当 needMask = YES 时,_mask 将会展示在 fromVC 与 toVC 层级的中间。默认不展示。
UIView *_mask;
}
@property(nonatomic, assign) NSTimeInterval duration;
@end
@implementation GMPresentAnimation
@synthesize transitionType;
- (instancetype)init
{
// 默认 push 动画时间0.6
- (instancetype)init {
if (self = [super init]) {
// self.duration = 0.6;
self.duration = 0.6;
self.duration = 0.3;
self.needMask = NO;
}
return self;
}
- (void)push:(id<UIViewControllerContextTransitioning>)transitionContext
{
UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
NSTimeInterval duration = [self transitionDuration:transitionContext];
CGRect bound = [[UIScreen mainScreen] bounds];
fromVC.view.hidden = YES;
- (void)push:(id<UIViewControllerContextTransitioning>)transitionContext {
CGRect bounds = [[UIScreen mainScreen] bounds];
UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];
UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];
// 在containerView上加一个toVC.snapshot,把之前页面当作背景
// 不加的话,toView在动画结束时会被系统移除,进而底部背景会突然变白
UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
fromVC.snapshot.frame = bounds;
[[transitionContext containerView] addSubview:fromVC.snapshot];
[[transitionContext containerView] addSubview:toVC.view];
[[toVC.navigationController.view superview] insertSubview:fromVC.snapshot belowSubview:toVC.navigationController.view];
toVC.navigationController.view.layer.anchorPoint = CGPointMake(0.5, 2.0);
toVC.navigationController.view.frame = bound;
toVC.navigationController.view.transform = CGAffineTransformMakeTranslation(0, CGRectGetHeight(bound));
[UIView animateWithDuration:duration
delay:0
usingSpringWithDamping:1.0
initialSpringVelocity:0
options:UIViewAnimationOptionCurveLinear
animations:^{
fromVC.snapshot.transform = CGAffineTransformMakeTranslation(0, 0);
toVC.navigationController.view.transform = CGAffineTransformMakeTranslation(0, 0);
}
completion:^(BOOL finished) {
fromVC.view.hidden = NO;
[fromVC.snapshot removeFromSuperview];
[transitionContext completeTransition:YES];
}];
// 添加一个半透明的蒙层,展示在 from view 下面
_mask = [[UIView alloc] initWithFrame:bounds];
_mask.backgroundColor = [UIColor colorWithWhite:0 alpha:0.64];
_mask.alpha = 0;
if (self.needMask) {
[[transitionContext containerView] addSubview:_mask];
}
// 系统不会为我们自动添加 toView,所以我们需要自己添加,以保证 toView 的页面及动画正常展示
[[transitionContext containerView] addSubview:toView];
// 先将toView放置在屏幕下边,为下一步的平移动画做准备
CGRect newFrame = toView.frame;
newFrame.origin.y = CGRectGetHeight(bounds);
toView.frame = newFrame;
// 从下到上的平移动画
[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
toView.frame = bounds;
_mask.alpha = 1;
} completion:^(BOOL finished) {
[transitionContext completeTransition:YES];
}];
}
- (void)pop:(id<UIViewControllerContextTransitioning>)transitionContext
{
UIViewController * fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController * toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
NSTimeInterval duration = [self transitionDuration:transitionContext];
CGRect bound = [[UIScreen mainScreen] bounds];
[fromVC.view addSubview:fromVC.snapshot];
fromVC.navigationController.navigationBar.hidden = YES;
// 添加阴影
fromVC.snapshot.layer.shadowColor = [UIColor colorWithRed:0.2 green:0.2 blue:0.2 alpha:0.8].CGColor;
fromVC.snapshot.layer.shadowOffset = CGSizeMake(-3, 0);
fromVC.snapshot.layer.shadowOpacity = 0.5;
fromVC.view.layer.anchorPoint = CGPointMake(0.5, 2.5);
fromVC.view.frame = bound;
toVC.view.hidden = YES;
[[transitionContext containerView] addSubview:toVC.view];
[[transitionContext containerView] addSubview:toVC.snapshot];
[[transitionContext containerView] sendSubviewToBack:toVC.snapshot];
[UIView animateWithDuration:duration
delay:0
usingSpringWithDamping:1.0
initialSpringVelocity:0
options:UIViewAnimationOptionCurveLinear
animations:^{
fromVC.view.transform = CGAffineTransformMakeTranslation(0, CGRectGetHeight(bound));
toVC.snapshot.alpha = 1;
}
completion:^(BOOL finished) {
toVC.navigationController.navigationBar.hidden = NO;
toVC.view.hidden = NO;
[fromVC.snapshot removeFromSuperview];
[toVC.snapshot removeFromSuperview];
if (![transitionContext transitionWasCancelled])
{
toVC.snapshot = nil;
}
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
- (void)pop:(id<UIViewControllerContextTransitioning>)transitionContext {
CGRect bound = [[UIScreen mainScreen] bounds];
UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey];;
UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];
// 必须把先前的 mask view 拿出来,显示的标记为 alpha = 1,要不然会发现该蒙层是突然消失
// 经打断点发现,其 alpha 此时为0,所以必须要设置一下 alpha = 1
_mask.alpha = 1;
//将toView加到toVC.snapshot 的的下面。
// 不加的话,动画结束后看不到 toView
// 动画过程中看到的是toVC.snapshot
// 并且需要将 toView放到toVC.snapshot的下面,确保view层级正确
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
[[transitionContext containerView] insertSubview:toView belowSubview:toVC.snapshot];
CGRect newFrame = fromView.frame;
newFrame.origin.y = CGRectGetHeight(bound);
[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
fromView.frame = newFrame;
_mask.alpha = 0;
} completion:^(BOOL finished) {
if (self.needMask) {
[_mask removeFromSuperview];
}
// 动画结束后移除toVC.snapshot,留着会挡住toVC,用户无法交互
[toVC.snapshot removeFromSuperview];
// 需要将toVC.snapshot清空,下一次弹窗时再重新生成 snapshot,确保每一次 snapshot 为最新画面
toVC.snapshot = nil;
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}
- (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext
{
- (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext {
return self.duration;
}
- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext
{
if (self.transitionType == UINavigationControllerOperationPush)
{
- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext {
if (self.transitionType == UINavigationControllerOperationPush) {
[self push:transitionContext];
}
else if (self.transitionType == UINavigationControllerOperationPop)
{
} else if (self.transitionType == UINavigationControllerOperationPop) {
[self pop:transitionContext];
}
}
......
......@@ -10,7 +10,5 @@
@interface UIViewController (Push)
@property (nonatomic, strong) UIView *snapshot;
//push type是否是模态动画
@property (nonatomic, assign) BOOL isPresent;
- (void)popToPresentPreviousController;
@end
......@@ -9,6 +9,7 @@
#import "UIViewController+PushType.h"
#import <objc/runtime.h>
#import "GMNavigationController.h"
#import "GMCustomNavigationAnimationProtocol.h"
@implementation UIViewController (PushType)
- (UIView *)snapshot
......@@ -26,22 +27,16 @@
objc_setAssociatedObject(self, @"gmSnapshot", snapshot, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (BOOL)isPresent {
return [objc_getAssociatedObject(self, @"gmIsPresent") boolValue];
}
-(void)setIsPresent:(BOOL)isPresent {
objc_setAssociatedObject(self, @"gmIsPresent", [NSNumber numberWithBool:isPresent], OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (void)popToPresentPreviousController {
for (int index = 0; index < self.navigationController.viewControllers.count; index++) {
UIViewController *controller = self.navigationController.viewControllers[index];
if (controller.isPresent) {
GMNavigationController *nav = (GMNavigationController *)self.navigationController;
nav.needPopPresetAnimation = YES;
UIViewController *previewController = self.navigationController.viewControllers[index - 1];
[controller.navigationController popToViewController:previewController animated:YES];
if ([controller conformsToProtocol:@protocol(GMCustomNavigationAnimationProtocol)]) {
if (index - 1 >= 0) {
UIViewController *previewController = self.navigationController.viewControllers[index - 1];
[controller.navigationController popToViewController:previewController animated:YES];
} else {
[controller.navigationController popViewControllerAnimated:YES];
}
return;
}
}
......
......@@ -61,6 +61,7 @@
[self hideLeftButtonForRootController];
//保证一些网络请求需要接参数referer的时候referer是有值的
[self initReferer];
[self initRefererLink];
[self initReferrerTabName];
[self setupEmptyView];
}
......
//
// WMFetchDataViewModel+GMRequest.h
// Gengmei
//
// Created by 汪俊 on 2017/7/13.
// Copyright © 2017年 更美互动信息科技有限公司. All rights reserved.
//
#import "WMFetchDataViewModel.h"
@interface WMFetchDataViewModel (GMRequest)
/**
因为这个是拼在url query中,所以后端给我们时,我们不需求关心它是NSNumber或者是String类型,原样传回去就可以
但其实在get方法的确是返回了String类型,因为这样便于清空offset,及对offset进行判断
未来offset会集成到FetchDataViewModel
*/
@property (nonatomic, strong) id offset;
@end
//
// WMFetchDataViewModel+GMRequest.m
// Gengmei
//
// Created by 汪俊 on 2017/7/13.
// Copyright © 2017年 更美互动信息科技有限公司. All rights reserved.
//
#import "WMFetchDataViewModel+GMRequest.h"
#import <objc/runtime.h>
@implementation WMFetchDataViewModel (GMRequest)
- (void)setOffset:(id)offset {
objc_setAssociatedObject(self, @selector(offset), offset, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (id)offset {
id _offset = objc_getAssociatedObject(self, @selector(offset));
if (_offset == nil) {
return @"";
}
if ([_offset isKindOfClass:[NSNumber class]]) {
return [_offset stringValue];
}
return _offset;
}
@end
//
// 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 */
......@@ -5,57 +5,57 @@
<testcase classname="fastlane.lanes" name="00: Verifying fastlane version" time="0.008809">
<testcase classname="fastlane.lanes" name="00: Verifying fastlane version" time="0.005779">
</testcase>
<testcase classname="fastlane.lanes" name="01: default_platform" time="0.001725">
<testcase classname="fastlane.lanes" name="01: default_platform" time="0.001067">
</testcase>
<testcase classname="fastlane.lanes" name="02: git_pull" time="1.239387">
<testcase classname="fastlane.lanes" name="02: git_pull" time="1.124838">
</testcase>
<testcase classname="fastlane.lanes" name="03: pod_repo_update" time="1.061352">
<testcase classname="fastlane.lanes" name="03: pod_repo_update" time="0.949571">
</testcase>
<testcase classname="fastlane.lanes" name="04: pod_lib_lint" time="48.022356">
<testcase classname="fastlane.lanes" name="04: pod_lib_lint" time="17.807304">
</testcase>
<testcase classname="fastlane.lanes" name="05: version_bump_podspec" time="0.008015">
<testcase classname="fastlane.lanes" name="05: version_bump_podspec" time="0.00348">
</testcase>
<testcase classname="fastlane.lanes" name="06: git_commit_all" time="0.055346">
<testcase classname="fastlane.lanes" name="06: git_commit_all" time="0.021413">
</testcase>
<testcase classname="fastlane.lanes" name="07: add_git_tag" time="0.023059">
<testcase classname="fastlane.lanes" name="07: add_git_tag" time="0.012612">
</testcase>
<testcase classname="fastlane.lanes" name="08: push_to_git_remote" time="1.019469">
<testcase classname="fastlane.lanes" name="08: push_to_git_remote" time="0.879309">
</testcase>
<testcase classname="fastlane.lanes" name="09: pod_push" time="23.800727">
<testcase classname="fastlane.lanes" name="09: pod_push" time="31.951709">
</testcase>
<testcase classname="fastlane.lanes" name="10: pod_repo_update" time="1.037171">
<testcase classname="fastlane.lanes" name="10: pod_repo_update" time="1.114873">
</testcase>
......
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