【问题标题】:why does this different "addSubView" code cause differences in behavior为什么这个不同的“addSubView”代码会导致行为差异
【发布时间】:2011-08-10 16:21:54
【问题描述】:

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

代码:

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

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

我使用旧代码时遇到的问题:

  • 我正在使用 UINavigationController 并有一个“mainView”UITableViewController,然后将一个 2 级视图推送到堆栈上,我们称之为“detailedView”UITableViewController。

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

  • 但是当启动时自动启动到第二个视图(当我保存状态)时,我可以进入第二个视图,但是在这种情况下,工具栏按钮不会出现在第二个视图的底部。当我回到主页时(通过 UINavigationController 标准安排),然后选择 UITableView 中的行,然后再次回到同一个视图,工具栏项看起来很好。

  • 无法追踪此问题,但最终通过反复试验,我注意到 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:还注意到,当我添加“self.window.rootViewController = self.navigationController”行时,以下 didFinishLaunchingWithOptions 代码有效。那就是没有这条线(这是 coredatabooks 示例所做的)我得到了问题。

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;

【问题讨论】:

  • 重新启动时如何导航到第二个视图控制器?

标签: iphone ios uinavigationcontroller uitableview


【解决方案1】:

这两种方法的区别在于,一种触发视图生命周期方法,另一种则不触发。

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

addSubview: 不这样做。

这有帮助吗?

编辑:

详细阅读您的帖子,您似乎正在以编程方式在详细视图的 viewDidAppear 方法上添加按钮。

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

如果您需要向后兼容 3.x,您可以自定义 UIWindow 子类。我的代码如下。使用window.djRootViewController = yourViewController 而不是window.rootViewController。它是为在界面生成器中使用而设计的。

#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

【讨论】:

  • 嗨罗伯特 - 我不得不承认,这对我来说并不完全有意义。哪里可以找到您在这里提到的信息? (例如,也许在其中一个苹果指南中?)。实际上应该使用哪种正确方法?我在 Apple UITableView 指南中注意到它指的是使用“addSubView) 方法......即在developer.apple.com/library/ios/documentation/UserExperience/…。我还在最初的帖子中更新了我的完整方法。
  • 哦,我确实有一个 NIB 文件,并在界面生成器中设置了根视图控制器/窗口 - 所以我想知道我是否在这里混合了一个 NIB 和编程方法,这可能会导致问题?
猜你喜欢
  • 1970-01-01
  • 2017-11-16
  • 1970-01-01
  • 2020-08-20
  • 1970-01-01
  • 1970-01-01
  • 2013-01-18
  • 1970-01-01
  • 2011-03-16
相关资源
最近更新 更多