在Cocoa Touch中协调控制器的devise模式

我创build了一个有很多自定义视图的iOS应用程序,所以使用默认的Cocoa视图不是一个选项。 然后,我决定使用Coordinating / Mediator Controller的devise模式(在iOS的Apress-Pro Objective-Cdevise模式中学习)。

从委托,我创build一个rootViewController指向协调控制器中的视图:

self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; coordinatingController = [C6CoordinatingController sharedInstance]; self.window.rootViewController = coordinatingController.activeVC; [self.window makeKeyAndVisible]; return YES; 

那么,在协调控制器中,我有独立创build方法:

 + (C6CoordinatingController *) sharedInstance{ if (sharedCoordinator == nil){ C6Log(@"New Shared Coordinator"); sharedCoordinator = [[super allocWithZone:NULL] init]; [sharedCoordinator initialize]; } else { C6Log(@"Return Singleton Shared Coordinator"); } return sharedCoordinator; } + (id) allocWithZone:(NSZone *)zone{ return [self sharedInstance]; } - (void) initialize{ C6Log(@""); [self checkDevice]; _mainVC = [C6MainViewController initWithDevice:device]; _activeVC = _mainVC; [self checkLanguage]; [self chooseFirstView]; } 

我也有一个select器来select第一个视图(我现在只有两个):

 -(void) chooseFirstView{ // If a language was not setted, go to language settings view if (!language) { C6Log(@"Going to Language Settings"); C6LanguageSettingsViewController *languageVC = [C6LanguageSettingsViewController initWithDevice:device]; [_mainVC.view addSubview:languageVC.view]; } else { C6Log(@"Going to User Settings", language); C6AccountSettingsViewController *accountVC = [C6AccountSettingsViewController initWithDevice:device]; [_mainVC.view addSubview:accountVC.view]; } } 

然后,我有一个IBAction被我的观点使用:

 - (IBAction) requestViewChangeByObject:(id)object { int buttonTag = [object tag]; // dividend int viewTag = buttonTag / divisor; // quotient int actionTag = buttonTag - (divisor * viewTag); // remainder C6Log(@"viewTag: %d | actionTag %d", viewTag, actionTag); switch (viewTag) { case LanguageTags: C6Log(@"LanguageTags"); break; case AccountTags: C6Log(@"AccountTags"); break; default: break; } 

在NIB中,我创build了一个Obect(协调控制器),我从那里调用IBAction。 它工作得很好,我可以改变我的意见(它仍然需要实施)………

但是…我也想改变语言,但是,因为它不是一个导航问题,我想从C6LanguageSettingsViewController而不是从C6CoodinatingController。

所以,我在C6LanguageSettingsViewController中创build了另一个IBAction:

 - (IBAction)chooseLang:(id)sender{ UIImage *bt; [self resetImagesToNormalState]; C6Log(@""); C6Log(@"%@", [sender tag]); C6Log(@"%@", sender); . . . 

当我连接button到这个IBAction(通过文件的所有者或通过LanguageSettingsViewController对象),应用程序中断,有时它显示没有错误,有时它提出无法识别的select器发送到实例EXC_BAD_ACCESS(代码= 1,地址= 0x … ……)在UIApplicationMain中。

我相信问题是NIB没有find文件的所有者…但我不知道如何解决它。

好的…这似乎是荒谬的,但我回答自己:P

我设法使它工作(finaly!),我发现我用BAAAAD方式pipe理viewControllers,所以我改变了协调控制器中的一些代码:

首先,我没有一个“真正的”mainViewController与NIBs和stuf没有更多…

老初始化

 - (void) initialize{ C6Log(@""); [self checkDevice]; _mainVC = [C6MainViewController initWithDevice:device]; _activeVC = _mainVC; [self checkLanguage]; [self chooseFirstView]; } 

新初始化

 - (void) initialize{ C6Log(@""); [self checkDevice]; [self checkLanguage]; [self chooseFirstView]; } 

checkDevicevalidation它是iPhone还是iPad,所以我可以select正确的NIB。

checkLanguage检查语言的[NSUserDefaults standardUserDefaults]

最后,我打电话chooseFirstView:

老selectFirstView

 -(void) chooseFirstView{ // If a language was not setted, go to language settings view if (!language) { C6Log(@"Going to Language Settings"); C6LanguageSettingsViewController *languageVC = [C6LanguageSettingsViewController initWithDevice:device]; [_mainVC.view addSubview:languageVC.view]; } else { C6Log(@"Going to User Settings", language); C6AccountSettingsViewController *accountVC = [C6AccountSettingsViewController initWithDevice:device]; [_mainVC.view addSubview:accountVC.view]; } } 

新selectFirstView

 -(void) chooseFirstView{ // If a language was not setted, go to language settings view _activeVC = [[UIViewController alloc] init]; UIImage *bgImage = [UIImage imageNamed:@"bg.png"]; UIImageView *bgView = [[UIImageView alloc] initWithImage:bgImage]; [_activeVC.view addSubview:bgView]; if (!language) { C6Log(@"Going to Language Settings"); languageVC = [C6LanguageSettingsViewController initWithDevice:device]; [_activeVC.view addSubview:languageVC.view]; } else { C6Log(@"Going to User Settings", language); accountVC = [C6AccountSettingsViewController initWithDevice:device]; [_activeVC.view addSubview:accountVC.view]; } } 

最大的变化是何时以及如何启动_activeVC …以及_languageVC和_accountVC现在都是全局variables。

那么,在这个变化之后,NIBbutton调用两个IBAction方法:它是文件的所有者和协调控制器。

另一个关于使用这种模式的大事情是如何从一个视图改变到另一个不破坏iOS设备的内存…以下是我如何在协调控制器内部做到这一点:

 - (IBAction) requestViewChangeByObject:(id)object { int buttonTag = [object tag]; // dividend int viewTag = buttonTag / divisor; // quotient int actionTag = buttonTag - (divisor * viewTag); // remainder C6Log(@"ViewTag: %d", viewTag); switch (viewTag) { case LanguageTags:{ C6Log(@"LanguageTags - button %d", actionTag); accountVC = [C6AccountSettingsViewController initWithDevice:device]; UIView *fromView = languageVC.view; UIView *toView = accountVC.view; [self switchFrom:fromView To:toView usingAnimation:AnimationPushFromRigh]; } break; case AccountTags:{ C6Log(@"AccountTags - button %d", actionTag); switch (actionTag) { case 0:{ C6Log(@"Go back"); languageVC = [C6LanguageSettingsViewController initWithDevice:device]; UIView *fromView = accountVC.view; UIView *toView = languageVC.view; [self switchFrom:fromView To:toView usingAnimation:AnimationPushFromLeft]; } break; default: break; } } break; default: break; } } 

在方法开始的时候,我做了很多math…我创build了一个模式,每个NIB的标签都应该有100个倍数…所以,语言从0开始,占100 …

 #define divisor 100 #define LanguageTags 0 #define AccountTags 1 

那么,我从一种观点转变到另一种观点的方式就在那里:

 -(void) switchFrom:(UIView*) fromView To:(UIView*) toView usingAnimation:(int) animation{ C6Log(@""); /*************** SET ALL DEFAULT TRANSITION SETTINGS ***************/ // Get the current view frame, width and height CGRect pageFrame = fromView.frame; CGFloat pageWidth = pageFrame.size.width; // Create the animation [UIView beginAnimations:nil context:nil]; // Create the delegate, so the "fromView" is removed after the transition [UIView setAnimationDelegate: fromView]; [UIView setAnimationDidStopSelector:@selector(removeFromSuperview)]; // Set the transition duration [UIView setAnimationDuration: 0.4]; // Add the "toView" as subview of "fromView" superview [fromView.superview addSubview:toView]; switch (animation) { case AnimationPushFromRigh:{ // Position the "toView" to the right corner of the page toView.frame = CGRectOffset(pageFrame, pageWidth,0); // Animate the "fromView" to the left corner of the page fromView.frame = CGRectOffset(pageFrame, -pageWidth,0); // Animate the "toView" to the center of the page toView.frame = pageFrame; // Animate the "fromView" alpha fromView.alpha = 0; // Set and animate the "toView" alpha toView.alpha = 0; toView.alpha = 1; // Commit the animation [UIView commitAnimations]; } break; case AnimationPushFromLeft:{ // Position the "toView" to the left corner of the page toView.frame = CGRectOffset(pageFrame, -pageWidth,0); // Animate the "fromView" to the right corner of the page fromView.frame = CGRectOffset(pageFrame, pageWidth,0); // Animate the "toView" to the center of the page toView.frame = pageFrame; // Animate the "fromView" alpha fromView.alpha = 0; // Set and animate the "toView" alpha toView.alpha = 0; toView.alpha = 1; // Commit the animation [UIView commitAnimations]; } break; default: break; } } 

我真的希望这有助于谁试图使用这种协调控制器模式:P

Interesting Posts