目录
1. UIViewController生命周期
2. 跳转
3. 高度自定义控制器间过渡
4. ViewController 间传值
5. 容器视图控制器
6. CGFloat、CGPoint、CGSize、CGRect
7. 屏幕旋转
- UIViewController生命周期
注意:上下拉手机的菜单,并不会走VC的apperar、disappear方法
- 跳转
方式一(present从下方弹出)
// present下一页
[self presentViewController:vc animated:true completion:^{
}];
// 返回上一页
[self dismissViewControllerAnimated:true completion:^{
}];
弹出气泡视图
// 1.自定义控制器(:UIViewController)
YTGrabOrderPopViewController *grabPopC=[YTGrabOrderPopViewController new];
// 设置pop视图显示大小
[grabPopC setPreferredContentSize:CGSizeMake(142, 160)];
// 设置presentVC的弹出方式为pop
[grabPopC setModalPresentationStyle:UIModalPresentationPopover];
// 2.
UIPopoverPresentationController *popVC=[grabPopC popoverPresentationController];
[popVC setDelegate:self]; // <UIPopoverPresentationControllerDelegate>
// 方式一:对于View
[popVC setSourceView:button]; //
[popVC setSourceRect:button.bounds]; // 位置:可调整
// 方式二:对于UIBarButtonItem
[popVC setBarButtonItem:[UIBarButtonItem new]];
// 3.弹出
[self presentViewController:grabPopC animated:true completion:^{
}];
present前可以配置过渡类型(高度自定义 参见下一节)
[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篇)
push(从右侧弹出)
前提:在push栈中,[[UINavigationController alloc]initWithRootViewController:[UIViewController new]];
》》》跳转到下一页(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 <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface TransitionManager : NSObject<UIViewControllerAnimatedTransitioning,UIViewControllerTransitioningDelegate>
/**
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<UIViewControllerContextTransitioning>)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<UIViewControllerContextTransitioning>)transitionContext{
return 0.82;
}
#pragma mark UIViewControllerTransitioningDelegate
// 当present VC后调用,返回 过渡动画管理者(实现了UIViewControllerAnimatedTransitioning的类),一般返回单独的遵守该协议的动画类
-(id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source{
self.presenting=true;
return self;
}
// 当dismiss VC后调用,返回 过渡动画管理者
- (id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed{
self.presenting=false;
return self;
}
// 返回<UIViewControllerInteractiveTransitioning>
//- (id <UIViewControllerInteractiveTransitioning>)interactionControllerForPresentation:(id <UIViewControllerAnimatedTransitioning>)animator{
//
//}
// 返回<UIViewControllerInteractiveTransitioning>
//- (id <UIViewControllerInteractiveTransitioning>)interactionControllerForDismissal:(id <UIViewControllerAnimatedTransitioning>)animator{
//
//}
//
//// 返回 :UIPresentationController
//- (UIPresentationController *)presentationControllerForPresentedViewController:(UIViewController *)presented presentingViewController:(nullable UIViewController *)presenting sourceViewController:(UIViewController *)source{
//
//}
// 动画阶段1(presenting)-——自定义方法
-(void)RunPresentAnimation:(id<UIViewControllerContextTransitioning>)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<UIViewControllerContextTransitioning>)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 <NSObject>
-(void)attentionExpert:(NSString *)expertId;
@end
@property (nonatomic,weak) id<ExpertViewControllerDele> *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移除
6. CGFloat、CGPoint、CGSize、CGRect
CGFloat
在UIView的坐标系统中,使用CGFloat类型的数据而不是Double或者Float
let x=CGFloat(12.0) :将Double或者Float转换成CGFloat
CGPoint
var point=CGPoint(x:30.0,y:50.0)
CGSize
var size=CGSize(width:20.0,height:10.0)
CGRect
var rect=CGRect(origin:point,size:size)
var rect=CGRect(x:10.0,y:10.0,width:20.0,height:5.0)
使用:
minX minY midX midY maxX maxY rect1.intersects(rect2) 是否 相交
rect1.intersect(rect2) 返回相交部分
rect1.contains(rect2) 是否 包含
常用:
//
CGRectZero
// 是否有交集
CGRectIntersectsRect(rect1, rect2)
// 返回交集rect
CGRectIntersection(rect1, rect2)
// 是否相同
CGRectEqualToRect(rect1, rect2)
// 是否包含
CGRectContainsRect(rect1, rect2)
// 是否包含某点
CGRectContainsPoint(rect, CGPointMake(0, 0))
// 返回合集
CGRectUnion(rect1, rect2)
// frame<——>str
CGRectFromString(NSStringFromCGRect(frame))
//
CGRectGetMidX(rect)
CGRectGetMinX(rect)
CGRectGetMaxX(rect)
CGRectGetMidY(rect)
CGRectGetMinY(rect)
CGRectGetMaxY(rect)
CGRectGetWidth(rect)
CGRectGetHeight(rect)
7. 屏幕旋转
- 选择项目支持的旋转方向
方式1
项目 | General | Deployment Info 下选择项目支持的方向
Portrait 正常方向 (Home键在下)
Landscape Left (Home键在)
Landscape Right (Home键在)
Upside Down (Home键在上)
方式2
AppDelegate中+
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
return UIInterfaceOrientationMaskPortrait;
}
- 指定页面旋转
/**
想让某页面旋转,那它的父级页面也必须支持旋转
*/
1.自定义UITabbarController中+
// IOS6后
// 是否允许旋转
-(BOOL)shouldAutorotate{
return self.selectedViewController.shouldAutorotate;
}
// 返回 哪些方向允许旋转
-(UIInterfaceOrientationMask)supportedInterfaceOrientations{
return self.selectedViewController.supportedInterfaceOrientations;
}
/*
UIInterfaceOrientationMaskPortrait = (1 << UIInterfaceOrientationPortrait),//向上为正方向的竖屏
UIInterfaceOrientationMaskLandscapeLeft = (1 << UIInterfaceOrientationLandscapeLeft),//向左移旋转的横屏
UIInterfaceOrientationMaskLandscapeRight = (1 << UIInterfaceOrientationLandscapeRight),//向右旋转的横屏
UIInterfaceOrientationMaskPortraitUpsideDown = (1 << UIInterfaceOrientationPortraitUpsideDown),//向下为正方向的竖屏
UIInterfaceOrientationMaskLandscape = (UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight),//向左或者向右的横屏
UIInterfaceOrientationMaskAll = (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskPortraitUpsideDown),//所有的横竖屏方向都支持
UIInterfaceOrientationMaskAllButUpsideDown = (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight),//支持向上的竖屏和左右方向的横屏
*/
// 返回 最优先使用的方向
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
return UIInterfaceOrientationPortrait;
}
/*
UIInterfaceOrientationUnknown = UIDeviceOrientationUnknown,//屏幕方向未知
UIInterfaceOrientationPortrait = UIDeviceOrientationPortrait,//向上正方向的竖屏
UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown,//向下正方向的竖屏
UIInterfaceOrientationLandscapeLeft = UIDeviceOrientationLandscapeRight,//向右旋转的横屏
UIInterfaceOrientationLandscapeRight = UIDeviceOrientationLandscapeLeft//向左旋转的横屏
此方法用来设置当前页面默认第一次进入的时候显示的屏幕方向
*/
// IOS6前
// VC是否支持旋转屏幕(不支持则旋转屏幕时界面不动)
//- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation{
// return toInterfaceOrientation==UIInterfaceOrientationPortrait;
//}
2.自定义Nav中+
-(BOOL)shouldAutorotate{
return self.topViewController.shouldAutorotate;
}
-(UIInterfaceOrientationMask)supportedInterfaceOrientations{
return self.topViewController.supportedInterfaceOrientations;
}
3.自定义基类VC中+
-(UIInterfaceOrientationMask)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}
-(BOOL)shouldAutorotate{
return false;
}
4.需要旋转的VC中+
-(BOOL)shouldAutorotate{
return true;
}
- 主动旋转
当用户设置iPhone禁止旋转后,以上方法失效(即不会旋转)
[[UIDevice currentDevice]setValue:[NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight] forKey:@"orientation"];
- 监听旋转
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChange:) name:UIDeviceOrientationDidChangeNotification object:nil];