基于UIPresentationController的彈出框
簡(jiǎn)介:UIPresentationController 是 iOS8 新增的一個(gè) API攘宙,用來控制 controller 之間的跳轉(zhuǎn)特效瞻颂。
比如希望實(shí)現(xiàn)一個(gè)特效鸳劳,顯示一個(gè)自定義的視圖,并且在控制器視圖的上面歧强。如果在之前我們可以通過在UIWindow上自定義view來實(shí)現(xiàn),但是現(xiàn)在我們完全可以通過UIPresentationController來實(shí)現(xiàn)這種展示效果。
實(shí)現(xiàn)方式
1.創(chuàng)建UIPresentationController的子類
2.在子類PresentationController的.m文件中脓斩,重寫5個(gè)方法
(1).重寫presentationTransitionWillBegin方法:
//presentationTransitionWillBegin 是在呈現(xiàn)過渡即將開始的時(shí)候被調(diào)用的。我們?cè)谶@個(gè)方法中把半透明黑色背景 View 加入到 containerView 中畴栖,并且做一個(gè) alpha 從0到1的漸變過渡動(dòng)畫随静。
- (void) presentationTransitionWillBegin
{
//使用UIVisualEffectView實(shí)現(xiàn)模糊效果
UIBlurEffect *blur = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
_visualView = [[UIVisualEffectView alloc]initWithEffect:blur];
_visualView.frame = self.containerView.bounds;
_visualView.alpha = 0.4;
_visualView.backgroundColor = [UIColor blackColor];
[self.containerView addSubview:_visualView];
}
(2).重寫presentationTransitionDidEnd方法:
//presentationTransitionDidEnd: 是在呈現(xiàn)過渡結(jié)束時(shí)被調(diào)用的,并且該方法提供一個(gè)布爾變量來判斷過渡效果是否完成吗讶。在我們的例子中燎猛,我們可以使用它在過渡效果已結(jié)束但沒有完成時(shí)移除半透明的黑色背景 View。
-(void)presentationTransitionDidEnd:(BOOL)completed {
// 如果呈現(xiàn)沒有完成照皆,那就移除背景 View
if (!completed) {
[_visualView removeFromSuperview];
}
}
(3).重寫dismissalTransitionWillBegin方法:
//以上就涵蓋了我們的背景 View 的呈現(xiàn)部分重绷,我們現(xiàn)在需要給它添加淡出動(dòng)畫并且在它消失后移除它。正如你預(yù)料的那樣膜毁,dismissalTransitionWillBegin 正是我們把它的 alpha 重新設(shè)回0的地方论寨。
-(void)dismissalTransitionWillBegin {
_visualView.alpha = 0.0;
}
(4).重寫dismissalTransitionDidEnd方法:
//我們還需要在消失完成后移除背景 View星立。做法與上面 presentationTransitionDidEnd: 類似,我們重載 dismissalTransitionDidEnd: 方法
-(void)dismissalTransitionDidEnd:(BOOL)completed{
if (completed) {
[_visualView removeFromSuperview];
}
}
5.重寫frameOfPresentedViewInContainerView方法:
//還有最后一個(gè)方法需要重載葬凳。在我們的自定義呈現(xiàn)中绰垂,被呈現(xiàn)的 view 并沒有完全完全填充整個(gè)屏幕,而是很小的一個(gè)矩形火焰。被呈現(xiàn)的 view 的過渡動(dòng)畫之后的最終位置劲装,是由 UIPresentationViewController 來負(fù)責(zé)定義的。我們重載 frameOfPresentedViewInContainerView 方法來定義這個(gè)最終位置
- (CGRect)frameOfPresentedViewInContainerView
{
CGFloat windowH = [UIScreen mainScreen].bounds.size.height;
CGFloat windowW = [UIScreen mainScreen].bounds.size.width;
self.presentedView.frame = CGRectMake(0, windowH - 300, windowW, 300);
return self.presentedView.frame;
}
3.自定義繼承自UIViewController的子類昌简,在子類中編寫彈框匯總所要展示的內(nèi)容
//本demo中只展示了一個(gè)label
- (void)viewDidLoad {
[super viewDidLoad];
[self createView];
}
#pragma mark ********【界面】********彈框中需要展示的內(nèi)容
-(void)createView{
UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 300)];
label.backgroundColor = [UIColor cyanColor];
label.text = @"這是內(nèi)容視圖";
label.textAlignment = NSTextAlignmentCenter;
[self.view addSubview:label];
}
#pragma mark ********【操作】********隱藏彈框
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
[self dismissViewControllerAnimated:YES completion:nil];
}
4.在需要展示彈框的控制器中調(diào)用第3步中編寫的內(nèi)容視圖控制器ContentViewController占业,并實(shí)現(xiàn)UIViewControllerTransitioningDelegate
- (void)viewDidLoad {
[super viewDidLoad];
[self createView];
}
#pragma mark ********【界面】********創(chuàng)建彈出按鈕
-(void)createView{
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(100, 100, 100, 30);
[button setTitle:@"彈出視圖" forState:UIControlStateNormal];
button.titleLabel.textColor = [UIColor blueColor];
button.titleLabel.font = [UIFont systemFontOfSize:14.0];
[button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
button.backgroundColor = [UIColor grayColor];
[self.view addSubview:button];
}
#pragma mark ********【操作】********彈出按鈕的實(shí)現(xiàn)
-(void)buttonClicked:(UIButton *)sender
{
ContentViewController *vc = [[ContentViewController alloc]init];
vc.modalPresentationStyle = UIModalPresentationCustom;// 設(shè)置 動(dòng)畫樣式
vc.transitioningDelegate = self;// 此對(duì)象要實(shí)現(xiàn) UIViewControllerTransitioningDelegate 協(xié)議
[self presentViewController:vc animated:YES completion:nil];
}
#pragma mark - UIViewControllerTransitioningDelegate
// 返回控制控制器彈出動(dòng)畫的對(duì)象
//參數(shù):
//presentedViewController: 將要跳轉(zhuǎn)到的目標(biāo)控制器
// presentingViewController: 跳轉(zhuǎn)前的原控制器
- (UIPresentationController *)presentationControllerForPresentedViewController:(UIViewController *)presented presentingViewController:(UIViewController *)presenting sourceViewController:(UIViewController *)source{
return [[PresentationController alloc] initWithPresentedViewController:presented presentingViewController:presenting];
}
5.展示效果
參考CSDN大佬地址:https://blog.csdn.net/ideaspress/article/details/51177934
本Demo的Github地址:https://github.com/wangxj4268/-UIPresentationController-.git