为什么这个不同的“addSubView”代码导致行为差异 [英] why does this different "addSubView" code cause differences in behavior

查看:99
本文介绍了为什么这个不同的“addSubView”代码导致行为差异的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么将以下代码从旧条目更改为新条目可修复以下问题。

Why does changing the below code from the Old to New entry fix the following problem.

代码:

  // OLD Entry - Did not work
  //[self.window addSubview:navigationController.view];

  // NEW Entry - Fixed it
  self.window.rootViewController = self.navigationController;

使用旧密码时出现问题:

Problem when I use Old Code:


  • 我正在使用UINavigationController,并且有一个mainViewUITableViewController,然后是第二级视图,我将其推入堆栈,我们称之为detailedViewUITableViewController。

  • I'm using a UINavigationController and have a "mainView" UITableViewController and then a 2nd level view I push onto the stack, let's call it "detailedView" UITableViewController.

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

Navigating normally back and forward from main to details works fine

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

BUT when automatically launch on startup into the 2nd view (as I save state) I get to the 2nd view OK, however the TOOLBAR BUTTONS do NOT appear at the bottom of the 2nd view in this case. When I go back to main page (via UINavigationController standard arrangements), and then then select the row in the UITableView, and go back into the same view again the toolbar items appear fine.

无法跟踪此情况,但最终通过反复试验我注意到appDelegate(所有地方)的代码更改(见上文)似乎解决了这个问题。

Couldn't track this down but finally through trial and error I noted this change in code (see above) in the appDelegate (of all places) seems to fix the issue.

有什么想法吗?

编辑:完整性这里是完整的方法

For completeness here is the full method

- (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和编程方法可能会导致问题?

EDIT 2: Oh, I do have a NIB file and have the root view controller/window setup in interface builder - so I'm wondering if I'm mixing a NIB and programmatic approach up here perhaps which might cause problems?

编辑3:此外注意到以下didFinishLaunchingWithOptions代码工作时我添加了self.window.rootViewController = self.navigationController行。这是没有这一行(这是coredatabooks的例子)我得到了问题。

EDIT 3: Also noted that the following didFinishLaunchingWithOptions code worked when I added the "self.window.rootViewController = self.navigationController" line. That is without this line (which is what the coredatabooks example does) I get the issue.

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;


推荐答案

这两种方法的区别在于一个触发了查看生命周期方法,另一方面没有。

The difference between the two methods is that one triggers the view lifecycle methods the other dose not.

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

I.e. setting window.rootViewController will cause the old view controller to receive the messages: viewDidDissaper viewWillDissapear etc.. while the new view controller will receive the viewWillApear, viewDidAppear etc..

addSubview:不会这样做。

这有用吗? ?

编辑:

详细阅读你的帖子看起来你好像是在详细视图的 viewDidAppear 方法上以编程方式添加按钮。

Reading your post in detail it looks like you are adding the buttons programatically on the viewDidAppear method of the detail view.

rootViewController 属性 UIWindow 自4.0起添加。文档没有明确提到它将触发视图生命周期方法,我通过像你自己的跟踪和错误发现了这一点。 (也许有人可以提出针对苹果文档的问题)。

The rootViewController property of UIWindow was added as of 4.0. The documentation does not explicitly mention that it will trigger the view life cycle methods, i found this out through trail and error like yourself. (perhaps someone can raise an issue against the apple documentation).

如果你需要向后兼容3.x你可以这是一个自定义UIWindow子类。我的代码如下。使用 window.djRootViewController = yourViewController 而不是 window.rootViewController 。它设计用于Interface构建器。

If you need to be backwards compatible for 3.x you can this a custom UIWindow subclass. My code is below. use window.djRootViewController = yourViewController instead of window.rootViewController. It is designed for use in Interface builder.

#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

这篇关于为什么这个不同的“addSubView”代码导致行为差异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆