/ / Cocoa-Touch-Interna: Woher kennt die Ansicht ihren Controller? - objektiv-c, kakao-touch, ios

Cocoa-Touch Interna: Wie kennt der View seinen Controller? - Ziel-C, Kakao-Touch, IOS

Wenn Sie einer Ansicht eine Unteransicht hinzufügen oder einem Fenster eine Ansicht hinzufügen, woher weiß iOS, zu welchem ​​Controller diese Ansicht gehört?

Einfaches Beispiel: Habe eine UIView ohne UIViewController und füge es dem Fenster hinzu [window addSubView:myView] -> es dreht sich nicht. Verwenden Sie jetzt eine UIViewController, lass es umsetzen shouldAutoRotateToInterfaceOrientation: und fügen Sie die Ansicht des Controllers zum Fenster hinzu: [window addSubView:myController.view] -> magischwird die Ansicht an die Schnittstellenorientierung angepasst.

Aber schauen Sie sich den Code an: in beiden Fällen a UIView wurde hinzugefügt. Wie kann iOS möglicherweise im zweiten Fall a UIViewController war beteiligt?

Ich bin daran interessiert, wie das intern gemacht wird. Meine beste Vermutung ist das UIViewController.view ist ein Setter, der den Controller einem internen Array von Controllern hinzufügt oder sich einer internen Variablen zuordnet, die den gerade aktiven Controller enthält.

Antworten:

4 für die Antwort № 1

Einfach. Hinein sehen UIView.h. Es ist genau dort. Jeder UIView hat einen Zeiger auf a UIViewController (was anscheinend als "viewDelegate" bezeichnet wird).


1 für die Antwort № 2

Dave DeLong ist korrekt (und bekommt +1), da UIView.h eindeutig als @package definiert ist, sodass alles in UIKit darauf zugreifen kann.

Hier ist ein Beispiel für den Zugriff auf diese Variable nur zu Bildungszwecken (offensichtlich werden Sie dies in einer realen Anwendung nicht tun).

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;
}

0 für die Antwort № 3

UIViewController verfügt über eine private Klassenmethode (aufgerufen controllerForView:, Glaube ich), die verwendet wird, um die Ansichten zu findenRegler. Intern wird wahrscheinlich eine Tabelle verwendet, um die beiden zu verbinden. Diese Methode ermittelt einfach die richtige Position in dieser Tabelle und gibt ihren Wert zurück. Wenn das Ergebnis null ist, wird die Standardimplementierung verwendet (drehen Sie sich nicht).

Wenn Sie sich für den Namen der Methode sicher sein möchten, setzen Sie in -[UIView becomeFirstResponder], tippen Sie auf ein Textfeld und gehen Sie den Code schrittweise durch, bis er im Aufrufstapel erscheint. Ich schlage vor zu verwenden becomeFirstResponder denn es ist einfacher zu steuern als die meisten Dinge, die den View-Controller erhalten.