- 最近在用Xcode7做项目的过程中遇到了如题的需求,按照iOS8以前的做法程序就直接崩溃了。可以看出这个需求从Xcode6到Xcode7的实现方法上有了一些改动,但是基本思路还是没有变,利用自定义UIWindow来实现。状态栏本质上是一个UIWindowLevelStatusBar级别的UIWindow,它之所以能够一直显示在APP的顶端不被覆盖,就是因为其优先级比我们的keyWindow高,这里为了监听到状态栏的点击,就自定义一个和状态栏尺寸一样大的window覆盖在上面就OK了,下面看代码。
- 在程序启动完成后就创建一个状态栏大小的窗口放在导航栏上
/**
初始化顶部窗口,并设置其跟控制器,注意Xcode7以后窗口不设置跟控制器就报错
*/
private func setupTopWindow()
{
topWindow = UIWindow(frame:UIApplication.sharedApplication().statusBarFrame)
topWindow?.windowLevel = UIWindowLevelAlert
topWindow?.backgroundColor = UIColor.clearColor()
topWindow?.rootViewController = TopWindowViewController()
topWindow?.backgroundColor = UIColor.blueColor()
topWindow?.hidden = false
}
注意:Xcode7和Xcode6的区别就在这里,Xcode6创建窗口不一定需要根控制器,就给一个警告,Xcode7以后不给跟控制器就直接崩溃了,那就来一个更控制器专门用来做这个窗口的点击,在touchBegan中实现自己的代码即可,下面看下我实现的小demo
- 首先,在keyWindow的根控制器为一个导航控制器,导航控制器的跟控制器为SuperViewController
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
window = UIWindow(frame: UIScreen.mainScreen().bounds)
//设置keyWindow的跟控制器
window?.rootViewController = UINavigationController(rootViewController: SuperViewController())
//初始化顶部窗口
setupTopWindow()
window?.makeKeyAndVisible()
return true
}
在SuperViewController的view上放了一个尺寸和控制器View一样大的scrollView
view.addSubview(scorollView)
scorollView.frame = UIScreen.mainScreen().bounds
在scrollview上添加两个TableView
//加入子控制器
addChildViewController(firstTableViewController)
addChildViewController(secondTableViewController)
//加入控制器对应的view
scorollView.addSubview(firstTableViewController.view)
firstTableViewController.view.frame = UIScreen.mainScreen().bounds
scorollView.addSubview(secondTableViewController.view)
secondTableViewController.view.frame = CGRectMake(UIScreen.mainScreen().bounds.size.width, 0, UIScreen.mainScreen().bounds.size.width, UIScreen.mainScreen().bounds.size.height)
这样就大概两个TableView就可以通过scrollview来回滚动了,那么怎么判断一个view当前是否可见呢,有以下几个条件,重点是一个坐标系的转换
func isVisiable() ->Bool
{
if alpha <= 0.01 || hidden == true
{
return false
}
let convertRect = superview!.convertRect(frame, toView: UIApplication.sharedApplication().keyWindow)
let rectIntersectsRect = CGRectIntersectsRect(convertRect,UIApplication.sharedApplication().keyWindow!.bounds)
if rectIntersectsRect && self.window == UIApplication.sharedApplication().keyWindow
{
return true
}
else
{
return false
}
}
然后再给UIView写一个分类寻找当前可见的tableView,然后利用递归的思想去寻找当前显示在用户面前的那个“MRright”
func searchVisiableView()
{
for view in subviews
{
if !(view.isVisiable() && view.isKindOfClass(UITableView.self))
{
for childView in view.subviews
{
childView.searchVisiableView()
}
}
else
{
(view as! UITableView).scrollToRowAtIndexPath(NSIndexPath(forRow: 0, inSection: 0), atScrollPosition: UITableViewScrollPosition.Top, animated: true)
return
}
}
}
详细的demo地址:https://github.com/xuhongru/xuhongru_Priest/tree/master