目录
1. UIViewController
注意:
上下拉手机的菜单,并不会走VC的apperar、disappear方法
- UIViewController生命周期
见iOS调试篇
- 跳转
方式一(presentVC)
// present下一页
[self presentViewController:vc animated:true completion:^{
}];
// 返回上一页
[self dismissViewControllerAnimated:true completion:^{
}];
presentVC,前配置过渡类型(高度自定义 参见下一节)
[vc setModalTransitionStyle:UIModalTransitionStyleCoverVertical];
/*
过渡style
UIModalTransitionStyleCoverVertical 由下而上(默认)
UIModalTransitionStyleCrossDissolve 淡入淡出
UIModalTransitionStyleFlipHorizontal 右侧向上翻转
UIModalTransitionStylePartialCurl 向上翻页
*/
[vc setModalPresentationStyle:UIModalPresentationFullScreen];
/*
弹出style
UIModalPresentationFullScreen 全屏(默认,原VC的View消失)
UIModalPresentationOverFullScreen 占满全屏(原VC的View不消失)
UIModalPresentationPageSheet
UIModalPresentationFormSheet
UIModalPresentationCurrentContext
UIModalPresentationCustom
UIModalPresentationOverCurrentContext
UIModalPresentationPopover
UIModalPresentationNone
*/
// 弹出我的是谁
id presentVC=self.presentingViewController;
// 我弹出的是谁
id presentedVC=self.presentedViewController;
方式二(具体参见iOS之UINavigationController篇)
跳到新页(2种)
// 方式一
[self.navigationController pushViewController:[UIViewController new] animated:true];
// 方式二
[self.navigationController showViewController:[UIViewController new] sender:nil];
返回到前页(3种)
// 一:返回到上一页
[self.navigationController popViewControllerAnimated:true];
// 二:返回到根视图页
[self.navigationController popToRootViewControllerAnimated:true];
// 三:返回到指定页
[self.navigationController popToViewController:self.navigationController.viewControllers[0] animated:true];
- 高度自定义控制器间过渡
TransitionManager.h
#import
#import
@interface TransitionManager : NSObject
/**
true:正在present
false:正在dismiss
*/
@property (nonatomic,assign) BOOL presenting;
@end
TransitionManager.m
#import "TransitionManager.h"
@interface TransitionManager()
@end
@implementation TransitionManager
// 动画结束时(不一定和过渡时间一致,只要动画停止)调用
-(void)animationEnded:(BOOL)transitionCompleted{
if(!transitionCompleted){ //
}else{
}
}
#pragma mark UIViewControllerAnimatedTransitioning
// 过渡时调用(1.获取到2个VC的View(2个阶段VC代表的不一样) 2. 分为两个阶段做不同的变化)
-(void)animateTransition:(id)transitionContext{
//
UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIView *toView = toVC.view;
UIView *fromView = fromVC.view;
// [toVC beginAppearanceTransition:YES animated:YES]; toVC 调用viewWillAppear 不加不会调用
if(self.presenting){
// 阶段1
[self RunPresentAnimation:transitionContext fromVC:fromVC toVC:toVC fromView:fromView toView:toView];
}else{
// 阶段2
[self RunDismissAnimation:transitionContext fromVC:fromVC toVC:toVC fromView:fromView toView:toView];
}
// [fromVC beginAppearanceTransition:NO animated:YES]; fromVC 调用viewDidDisappear
}
// 过渡时间(没什么影响,真正决定的还是以上方法中动画设置的时间)
-(NSTimeInterval)transitionDuration:(id)transitionContext{
return 0.82;
}
#pragma mark UIViewControllerTransitioningDelegate
// 当present VC后调用,返回 过渡动画管理者(实现了UIViewControllerAnimatedTransitioning的类),一般返回单独的遵守该协议的动画类
-(id)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source{
self.presenting=true;
return self;
}
// 当dismiss VC后调用,返回 过渡动画管理者
- (id )animationControllerForDismissedController:(UIViewController *)dismissed{
self.presenting=false;
return self;
}
// 返回
//- (id )interactionControllerForPresentation:(id )animator{
//
//}
// 返回
//- (id )interactionControllerForDismissal:(id )animator{
//
//}
//
//// 返回 :UIPresentationController
//- (UIPresentationController *)presentationControllerForPresentedViewController:(UIViewController *)presented presentingViewController:(nullable UIViewController *)presenting sourceViewController:(UIViewController *)source{
//
//}
// 动画阶段1(presenting)-——自定义方法
-(void)RunPresentAnimation:(id)transitionContext fromVC:(UIViewController *)fromVC toVC:(UIViewController *)toVC fromView:(UIView *)fromView toView:(UIView *)toView {
/*
设置toVC的初始位置,并添加到总容器View上(此时fromView已经在上面)
*/
// 获取总容器View
UIView* containerView = [transitionContext containerView];
// 获取fromVC的frame
CGRect frame = [transitionContext initialFrameForViewController:fromVC];
// 底部滑进 离屏滑入 即y坐标 从height --->0
CGRect offScreenFrame = frame;
offScreenFrame.origin.y = offScreenFrame.size.height;
toView.frame = offScreenFrame;
//
[containerView insertSubview:toView aboveSubview:fromView];
/*
对formView 和 toView 进行动画
*/
//三维变化
CATransform3D t1 = CATransform3DIdentity;
t1.m34 = 1.0/-1000;
//x y方向各缩放比例为0.95
t1 = CATransform3DScale(t1, 0.95, 0.95, 1);
//x方向旋转15°
t1 = CATransform3DRotate(t1, 15.0f * M_PI/180.0f, 1, 0, 0);
CATransform3D t2 = CATransform3DIdentity;
t2.m34 = 1.0/-1000;
//沿Y方向向上移动
t2 = CATransform3DTranslate(t2, 0, -fromView.frame.size.height*0.08, 0);
//在x y方向各缩放比例为0.8
t2 = CATransform3DScale(t2, 0.8, 0.8, 1);
//UIView关键帧动画 总的持续时间:1.0
[UIView animateKeyframesWithDuration:1.0 delay:0.0 options:UIViewKeyframeAnimationOptionCalculationModeCubic animations:^{
//开始时间:1.0*0.0 持续时间:1.0*0.4
[UIView addKeyframeWithRelativeStartTime:0.0f relativeDuration:0.4f animations:^{
//执行t1动画 缩放并旋转角度
fromView.layer.transform = t1;
//fromView的透明度
fromView.alpha = 0.6;
}];
//开始时间:1.0*0.1 持续时间:1.0*0.5
[UIView addKeyframeWithRelativeStartTime:0.1f relativeDuration:0.5f animations:^{
//执行t2动画 向上平移和缩放
fromView.layer.transform = t2;
}];
//开始时间:1.0*0.0 持续时间:1.0*1.0
[UIView addKeyframeWithRelativeStartTime:0.0f relativeDuration:1.0f animations:^{
//toView向上滑入
toView.frame = frame;
}];
} completion:^(BOOL finished) {
// 过渡动画结束
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}
// 动画阶段2-——自定义方法
-(void)RunDismissAnimation:(id)transitionContext fromVC:(UIViewController *)fromVC toVC:(UIViewController *)toVC fromView:(UIView *)fromView toView:(UIView *)toView {
/*
隐藏vc2,还原vc1
*/
CGRect frame = [transitionContext initialFrameForViewController:fromVC];
toView.frame = frame;
CGRect frameOffScreen = frame;
frameOffScreen.origin.y = frame.size.height;
CATransform3D t1 = CATransform3DIdentity;
t1.m34 = 1.0/-1000;
t1 = CATransform3DScale(t1, 0.95, 0.95, 1);
t1 = CATransform3DRotate(t1, 15.0f * M_PI/180.0f, 1, 0, 0);
// 关键帧过渡动画
[UIView animateKeyframesWithDuration:1.0 delay:0 options:UIViewKeyframeAnimationOptionCalculationModeCubic animations:^{
[UIView addKeyframeWithRelativeStartTime:0.0f relativeDuration:1.0f animations:^{
fromView.frame = frameOffScreen;
}];
[UIView addKeyframeWithRelativeStartTime:0.35f relativeDuration:0.35f animations:^{
toView.layer.transform = t1;
//透明度为1.0
toView.alpha = 1.0;
}];
[UIView addKeyframeWithRelativeStartTime:0.75f relativeDuration:0.25f animations:^{
//还原3D状态
toView.layer.transform = CATransform3DIdentity;
}];
} completion:^(BOOL finished) {
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}
@end
- ViewController 间传值
方式一 (通过属性传值)
/**
id
*/
@property (nonatomic,copy) NSString *expertId;
方式二 (通过block传值)
/**
attentionBlock
*/
@property (nonatomic,copy) void (^attentionBlock)(NSString *expertId);
方式三 (dele)
@protocol ExpertViewControllerDele
-(void)attentionExpert:(NSString *)expertId;
@end
@property (nonatomic,weak) id *dele;
方式四 (通知)
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(handleAttention:) name:@"AttentionExpert" object:nil];
[[NSNotificationCenter defaultCenter]postNotificationName:@"AttentionExpert" object:@{@"expertId":@"110",@"isAttention":@(1)}];
方式五 (target+action)
- 容器视图控制器
系统自带的容器视图控制器:UINavigationController, UITabBarController和UISplitViewController
普通子控制器
点击按钮进入页面B(根据接口获取的不同的状态,进入不同的页面)
一般把判断的逻辑放在页面B,而不是按钮所在的页面A。这时需要根据不同的条件添加不同的控制器以显示不同的页面。
// 添加
[self addChildViewController:vc];
[self.view addSubview:vc.view]; // 注意:这里会调用viewDidLoad等方法
// 移除
[vc removeFromParentViewController]; // 将vc从总VC中移除,此时视图还在屏幕上
[vc.view removeFromSuperview]; // 将vc的view移除