我们假设有这么一个需求:
我们的基本视图分为了左右两块,现在需要弹出一个新窗口。该窗口要求大小和位置恰好覆盖右视图。点击空白处关闭。
怎么去实现他。
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。可能是因为这是一个弹窗,所以并不能实现完全切合屏幕边缘的效果。
如果你还有其他的实现方法,请留言共同学习。
网友评论