gpt4 book ai didi

iphone - Cocoa Touch 中的协调 Controller 设计模式

转载 作者:可可西里 更新时间:2023-11-01 06:11:50 24 4
gpt4 key购买 nike

我正在创建一个包含大量自定义 View 的 iOS 应用程序,因此无法使用默认的 Cocoa View 。然后,我决定采用Coordinating/Mediator Controller 设计模式(在 Apress - Pro Objective-C Design Patterns for iOS 中学习)。

我从委托(delegate)中创建了一个指向协调 Controller 中的 View 的 rootViewController:

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

然后,在协调 Controller 中,我有单例创建方法:

+ (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];
}

我还有一个选择器可以选择第一个 View (我目前只有两个):

-(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 供我的 View 使用:

- (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 中,我创建了一个对象(协调 Controller ),并从那里调用了 IBAction。效果很好,我可以改变我的看法(仍然需要实现)…………

但是……我也想更改语言,但是,因为这不是导航问题,所以我想从 C6LanguageSettingsViewController 而不是 C6CoodinatingController 进行。

因此,我在 C6LanguageSettingsViewController 中创建了另一个 IBAction:

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

当我将按钮连接到此 IBAction(通过文件所有者或通过 LanguageSettingsViewController 对象)时,应用程序中断,有时它没有显示任何错误,有时它会显示 Unrecognized selector sent to instance 或UIApplicationMain 中的EXC_BAD_ACCESS (Code=1, address = 0x…………)

我认为问题是 NIB 没有找到文件的所有者……但我不确定如何解决它。

最佳答案

好吧……这看起来很荒谬,但我在回答自己:P

我设法让它工作(终于!),我发现我正在以 BAAAAD 的方式管理 viewControllers,所以,我更改了协调 Controller 中的一些代码:

首先,我没有带 NIB 和 stuf 的“真正的”mainViewController……

旧初始化

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

NEW初始化

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

checkDevice 验证它是 iPhone 还是 iPad,因此我可以选择正确的 Nib 。

checkLanguage 检查语言的 [NSUserDefaults standardUserDefaults]

最后,我调用 chooseFirstView:

老选择FirstView

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

新的 chooseFirstView

-(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 现在都是全局变量这一事实。

好吧,在此更改之后,NIB 按钮调用两个 IBAction 方法:它是文件的所有者和协调 Controller 。

使用这种模式的另一件大事是如何在不爆炸 iOS 设备内存的情况下从一个 View 更改为另一个 View ……以下是我在协调 Controller 中的操作方式:

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

在方法的开头,我做了很多数学运算……我“创建”了一个模式,其中每个 NIB 的标签都应该以 100 的倍数开头……所以,语言以 0 开头,帐户以 100 开头…………

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

然后,我从一个 View 更改为另一个 View 的方式就在那里:

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

我真的希望这对尝试使用这种协调 Controller 模式的人有所帮助 :P

关于iphone - Cocoa Touch 中的协调 Controller 设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10834826/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com