gpt4 book ai didi

iphone - 为什么这个不同的 "addSubView"代码会导致行为差异

转载 作者:可可西里 更新时间:2023-11-01 03:12:09 25 4
gpt4 key购买 nike

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

代码:

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

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

使用旧代码时出现的问题:

  • 我正在使用 UINavigationController 并有一个“mainView”UITableViewController,然后我将一个二级 View 插入堆栈,我们称它为“detailedView”UITableViewController。

  • 从主要内容到详细信息的正常来回导航工作正常

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

  • 无法追踪到这个问题,但最终通过反复试验,我注意到 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 文件,并且在界面生成器中设置了 Root View Controller /窗口 - 所以我想知道我是否在这里混合了一个 NIB 和编程方法,这可能会导致问题吗?

编辑 3:还注意到以下 didFinishLaunchingWithOptions 代码在我添加“self.window.rootViewController = self.navigationController”行时有效。如果没有这一行(这是 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;

最佳答案

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

即设置 window.rootViewController 将导致旧 View Controller 接收消息:viewDidDissaper viewWillDissapear 等。而新 View Controller 将接收 viewWillApear、viewDidAppear 等。

addSubview: 不会这样做。

这有帮助吗?

编辑:

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

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

如果您需要向后兼容 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

关于iphone - 为什么这个不同的 "addSubView"代码会导致行为差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5750766/

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