弹窗效果的实现

我们假设有这么一个需求:

我们的基本视图分为了左右两块,现在需要弹出一个新窗口。该窗口要求大小和位置恰好覆盖右视图。点击空白处关闭。
怎么去实现他。

1、addSubView

这个是最基础,也是最容易想到的方法。创建好自己的弹窗View,然后覆盖在右视图的位置,完成。至于点击空白关闭,实现的方式也很多,比如hittest,或者索性将弹窗View设为全屏,左视图部分透明,并添加点击关闭事件。

代码就略了。

该方法有一个问题,如果界面存在多个弹窗,或者弹窗的业务复杂,按照界面和数据业务分离的原则,所有弹窗的业务,会和基本视图的业务都写在一起,形成一个Massive View Controller。

2、container

使用storyboard的开发者,应该看到过一个控件。

Container View:
2597513B-1F53-4546-9302-076FAF02B635.png

这个控件其实就是把新的viewController的view添加到你现在控制器的view上。代码如下:

SecondViewController *secondViewController = [SecondViewController new];
UIView *containerView = secondViewController.view;
[self.view addSubview:containerView];

备注,如果来回切换多个弹出视图,并保存每个视图的状态。可以考虑addChildViewController,API已经为我们提供了相关方法:

UIViewController的transitionFromViewController:
当然也可以自己玩,比如上面的例子中,SecondViewController如果是一个UITabBarController,便可以像使用tabbar一样,随意使用container。
实现点击空白消失的方法,没有找到啥好方法,暂时就hittest捕获点击位置,然后关闭弹窗吧。

3、modal
直接模态跳转到新的viewController里,这个viewController里,设置背景透明,然后弹窗视图大小和位置放到与上级右视图相同的位置。

viewController透明的方法,一直觉得百度不怎么靠谱,百度到的都是

vc1.modalPresentationStyle = UIModalPresentationCurrentContext;

vc2.view.backgroundColor = [UIColor clearColor];

[vc1 presentModalViewController:vc2 animated:YES];

亲测iOS8及其以上无效。

iOS8及其以上应该使用

vc2.modalPresentationStyle = UIModalPresentationOverCurrentContext;

vc2.view.backgroundColor = [UIColor clearColor];

[vc1 presentModalViewController:vc2 animated:YES];

4、popoverPresentationController
个人其实挺喜欢这种方法,毕竟弹窗事件,关闭事件都是现成的,只是没有找到有效的设置大小和位置的方法。尴尬。

DetailViewController *popoverViewController = [DetailViewController new];

popoverViewController.modalPresentationStyle = UIModalPresentationPopover;

popoverViewController.popoverPresentationController.sourceView = self.view;

popoverViewController.popoverPresentationController.sourceRect = detailView.frame;

popoverViewController.popoverPresentationController.permittedArrowDirections = 0;

popoverViewController.preferredContentSize = detailView.bounds.size;

[self presentViewController:popoverViewController animated:NO completion:nil];

设置位置的方法应该是sourceView和sourceRect,设置大小的方法应该是preferredContentSize。可能是因为这是一个弹窗,所以并不能实现完全切合屏幕边缘的效果。

如果你还有其他的实现方法,请留言共同学习。

你可能感兴趣的:(弹窗效果的实现)