iOS 获取当前正在显示的ViewController

来源:互联网 发布:js控制div宽度 编辑:程序博客网 时间:2024/05/20 20:58
[objc] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. 适用范围,tabbar的子视图都是NavigationController,其它情况可以根据情况调整  

[objc] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. - (UIViewController *)getCurrentVC{  
  2.       
  3.     UIViewController *result = nil;  
  4.     UIWindow * window = [[UIApplication sharedApplication] keyWindow];  
  5.     //app默认windowLevel是UIWindowLevelNormal,如果不是,找到UIWindowLevelNormal的  
  6.     if (window.windowLevel != UIWindowLevelNormal)  
  7.     {  
  8.         NSArray *windows = [[UIApplication sharedApplication] windows];  
  9.         for(UIWindow * tmpWin in windows)  
  10.         {  
  11.             if (tmpWin.windowLevel == UIWindowLevelNormal)  
  12.             {  
  13.                 window = tmpWin;  
  14.                 break;  
  15.             }  
  16.         }  
  17.     }  
  18.     id  nextResponder = nil;  
  19.     UIViewController *appRootVC=window.rootViewController;  
  20. //    如果是present上来的appRootVC.presentedViewController 不为nil  
  21.     if (appRootVC.presentedViewController) {  
  22.         nextResponder = appRootVC.presentedViewController;  
  23.     }else{  
  24.         UIView *frontView = [[window subviews] objectAtIndex:0];  
  25.         nextResponder = [frontView nextResponder];   <span style="font-family: Arial, Helvetica, sans-serif;">//  这方法下面有详解    </span>  
  26.     }  
  27.       
  28.     if ([nextResponder isKindOfClass:[UITabBarController class]]){  
  29.         UITabBarController * tabbar = (UITabBarController *)nextResponder;  
  30.         UINavigationController * nav = (UINavigationController *)tabbar.viewControllers[tabbar.selectedIndex];  
  31. //        UINavigationController * nav = tabbar.selectedViewController ; 上下两种写法都行  
  32.         result=nav.childViewControllers.lastObject;  
  33.           
  34.     }else if ([nextResponder isKindOfClass:[UINavigationController class]]){  
  35.         UIViewController * nav = (UIViewController *)nextResponder;  
  36.         result = nav.childViewControllers.lastObject;  
  37.     }else{  
  38.         result = nextResponder;  
  39.     }  
  40.       
  41.     return result;  
  42. }  


- (nullable UIResponder*)nextResponder  解释

问题1。 如何调用父view的controller里面的方法?

答案如下:
[[self superview ].nextResponder  method];
[[[self superview ] nextResponder]  method];
[self.nextResponder method];
上面的都可以,看情况使用,使用的时候最好判断一下。

官方解释
UIView implements this method by returning the UIViewController object that manages it (if it has one) or its superview (if it doesn’t); UIViewController implements the method by returning its view’s superview; UIWindow returns the application object, and UIApplication returns nil.


问题2:当一个子view需要接收点击事件,而父view也需要接收点击事件, 如何做?

当然, 你可能会说直接调用mysubview.superView即可, 这样做也确实是可以做到,但有时子view是不一定知道有这个特定的父view的存在的,如动态添加子view。

所以这里就可以用到消息响应链拉技术。

下面要做的也就是,让子view接收这些事件后,同时把这些事件继续向上传,会一直传到UIApplication为止。 而在传的过程中,如果子view接收了这些事件,那么事件会自然终止,我们现在可以做的是同时让子view接收事件,而且还让事件不终止,并继续向上传。

摘取一部分说明:

当用户  与  iPhone的触摸屏  产生  互动时,硬件  就会探测到  物理接触  并且  通知  操作系统。接着  操作系统  就会创建  相应的事件  并且  将  其  传递给  当前正在运行的应用程序的事件队列。然后  这项事件  会被事件循环  传递给  优先响应者物件。优先响应者物件  是  事件  被触发时  和  用户  交互的物件,比如  按钮物件、视图物件。如果  我们  编写了  代码  让  优先响应者  处理  这种类型的事件,那么  它  就会处理  这种类型的事件。处理完  某项事件后,响应者  有  两个选项:1、将  其  丢弃;2、将  其  传递给  响应链条中的下一个响应者。下一个响应者的地址   存储  在当前响应者物件所包含的变量nextResponder当中。如果  优先响应者  无法处理  一项事件,那么  这项事件  就传递给  下一个响应者,直到  这项事件  到达  能处理它的响应者  或者  到达  响应链条的末端,也就是  UIApplication类型的物件。UIApplication类型的物件  收到  一项事件后,也是  要么  处理,要么  丢弃。

比如  有  一个视图物件,这个视图物件上  有  一个按钮物件。当用户  触摸  这个按钮物件时,作为优先响应者,这个按钮物件  就会收到  一项事件。如果  这个按钮物件  无法处理  这项事件,就会将  这项事件  传递给  视图物件。如果  视图物件  无法处理  这项事件,就会将  这项事件  传递给  视图控制器物件。以此类推。

应该注意的  是  当我们  在使用  响应链条时,一项事件  并不会自动地  从一个响应者  传递到  下一个响应者。如果  要将  一项事件  从一个响应者  传递到  下一个响应者,我们  必须编写  代码  才能办到。

要做的如下:

view的代码如下:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

// 这里可以做子view自己想做的事,做完后,事件继续上传,就可以让其父类,甚至父viewcontroller获取到这个事件了

[[self nextResponder]touchesBegan:toucheswithEvent:event];

}


- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event

{

[[self nextResponder]touchesEnded:toucheswithEvent:event];

}


- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event

{

[[self nextRespondertouchesCancelled:toucheswithEvent:event];

}


- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event

{

[[self nextRespondertouchesMoved:toucheswithEvent:event];

}

另外需要注意的是:在重写这几个方法时,最好保证这几个方法都重写,否则事件响应链可能会变混乱。这是我的猜测哈,没有实际验证过。
2 0
原创粉丝点击