如果您向视图添加子视图或向窗口添加视图,iOS如何知道此视图所属的控制器?
简单示例:
拥有一个没有UIViewController
的UIView并将其添加到窗口[window addSubView:myView]
- >它不会旋转。
现在使用UIViewController
,让它实现shouldAutoRotateToInterfaceOrientation:
并将控制器的视图添加到窗口:[window addSubView:myController.view]
- > 神奇地,视图将调整为界面方向。
但请查看代码:在这两种情况下都添加了UIView
。 iOS如何可能意识到在第二种情况下涉及UIViewController
?
我对如何在内部完成这项工作感兴趣。我最好的猜测是UIViewController.view
是一个setter,它将控制器添加到内部控制器数组中,或者将自己分配给一个保存当前活动控制器的内部变量。
答案 0 :(得分:4)
简单。查看UIView.h
。它就在那里。每个UIView
都有一个指向UIViewController
的指针(显然称为“viewDelegate”)。
答案 1 :(得分:1)
Dave DeLong是正确的(获得+1),因为它明确地将UIView.h定义为@package,因此UIKit中的任何内容都可以访问它。
以下是仅出于教育目的访问该变量的示例(显然,您不会在实际应用程序中执行此操作)。
<强> SomeAppDelegate.m 强>
@synthesize navigationController=_navigationController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
// Add the navigation controller's view to the window and display.
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
//DO NOT TRY THIS AT HOME
UIView *mynavview = self.navigationController.view;
//Guaranteed _viewDelegate atleast in iOS 4.3
Ivar ivar = class_getInstanceVariable([UIView class], "_viewDelegate");
UIViewController *controller = object_getIvar(mynavview, ivar);
NSLog(@"controller = self.navigationController? %@", controller == self.navigationController ? @"Yes" : @"No");
return YES;
}
答案 2 :(得分:0)
UIViewController有一个私有类方法(我相信称为controllerForView:
),用于查找视图的控制器。在内部,可能有一个表用于将两者连接在一起,此方法只是在该表中找到正确的位置并返回其值。当结果为nil时,将使用默认实现(不要旋转)。
如果要确定方法的名称,请在-[UIView becomeFirstResponder]
中设置断点,点击文本字段,然后逐步执行代码,直到它出现在调用堆栈中。我建议使用becomeFirstResponder
因为它比获取视图控制器的大多数事情更容易控制。