为什么这个不同的“addSubView”代码会导致行为上的差异

为什么更改下面的代码从旧到新条目修复了以下问题。

码:

// OLD Entry - Did not work //[self.window addSubview:navigationController.view]; // NEW Entry - Fixed it self.window.rootViewController = self.navigationController; 

使用旧代码时出现问题:

  • 我使用一个UINavigationController,并有一个“mainView”UITableViewController,然后我推到堆栈上的第二级视图,我们称之为“detailedView”UITableViewController。

  • 正常导航从主要到细节工作正常

  • 但是,当启动时自动启动到第二个视图(当我保存状态),我到第二个视图确定,但在这种情况下工具栏button不会出现在第二个视图的底部。 当我回到主页面(通过UINavigationController标准安排),然后selectUITableView中的行,再次返回到相同的视图工具栏项目显示正常。

  • 无法跟踪这个,但最后通过试验和错误,我注意到在appDelegate(所有地方)代码(见上文)的这种变化似乎解决了这个问题。

有任何想法吗?

编辑:为了完整,这里是完整的方法

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { RootViewController *rootViewController = (RootViewController *)[navigationController topViewController]; NSManagedObjectContext *context = [self managedObjectContext]; if (!context) { abort(); // TODO: Do better job here than abort } rootViewController.managedObjectContext = context; self.window.rootViewController = self.navigationController; [self.window makeKeyAndVisible]; return YES; } 

编辑2:哦,我有一个NIB文件,并在界面生成器的根视图控制器/窗口设置 – 所以我想知道如果我在这里混合NIB和程序化的方法,也许这可能会导致问题?

编辑3:还注意到,下面didFinishLaunchingWithOptions代码工作时,我添加“self.window.rootViewController = self.navigationController”行。 这是没有这条线(这是coredatookook例子),我得到的问题。

 RootViewController *rootViewController = (RootViewController *)[navigationController topViewController]; rootViewController.managedObjectContext = self.managedObjectContext; self.window.rootViewController = self.navigationController; // WORKS WHEN I ADD THIS LINE IN FOR SOME REASON??? // Configure and show the window [window addSubview:[navigationController view]]; [window makeKeyAndVisible]; return YES; 

这两种方法之间的区别在于触发视图生命周期方法而不是其他方法。

即设置window.rootViewController将导致旧的视图控制器接收消息:viewDidDissaper viewWillDissapear等。而新的视图控制器将收到viewWillApear,viewDidAppear等。

addSubview:不这样做。

这有帮助吗?

编辑:

详细阅读您的文章,看起来您正在以详细视图的viewDidAppear方法编程方式添加button。

UIWindowrootViewController属性从4.0开始添加。 文档没有明确提到它会触发视图生命周期方法,我发现通过像你自己的痕迹和错误。 (也许有人可以提出反对苹果文件的问题)。

如果你需要向后兼容3.x,你可以这个自定义的UIWindow子类。 我的代码如下。 使用window.djRootViewController = yourViewController而不是window.rootViewController 。 它被devise用于界面生成器。

 #import <UIKit/UIKit.h> @interface DJWindow : UIWindow { UINavigationController* m_navigationController; } @property (nonatomic, retain) UIViewController* djRootViewController; @end #import "DJWindow.h" @interface DJWindow() - (void) customInit; @end @implementation DJWindow - (id) initWithCoder:(NSCoder *)coder { self = [super initWithCoder:coder]; if (self) { [self customInit]; } return self; } - (void) customInit { m_navigationController = [[UINavigationController alloc] init]; m_navigationController.navigationBarHidden = YES; [self addSubview:m_navigationController.view]; } - (void) setRootViewController:(UIViewController *)rootViewController { NSLog(@"ERROR, do not set the rootViewController property, use djRootViewController instead"); } - (void) setDjRootViewController:(UIViewController *)djRootViewController { if (djRootViewController == nil) { [m_navigationController setViewControllers:nil]; } else { NSArray* vcArray = [NSArray arrayWithObject:djRootViewController]; [m_navigationController setViewControllers:vcArray]; } } - (UIViewController*) djRootViewController { return m_navigationController.visibleViewController; } - (void)dealloc { [m_navigationController release]; [super dealloc]; } @end