gpt4 book ai didi

iphone - UIWindow subview 在应用程序变为事件状态后消失

转载 作者:行者123 更新时间:2023-12-01 19:20:49 26 4
gpt4 key购买 nike

所以,我试图在 Application UIWindow 上实现一个固定的顶部横幅和多个 View Controller 的工作导航。我知道还有其他方法可以执行此操作,但对于我的项目要求,我需要使用 xibs。

下面的代码允许实现这一点:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

self.headerView = [[UIImageView alloc] init];
self.headerView.frame = CGRectMake(0.0f, 20.0f, 320.0f, 44.0f);
self.headerView.image = [UIImage imageNamed: @"header-banner-background.png"];
[self.window addSubview:self.headerView];

self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];

UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:self.viewController];

self.window.rootViewController = navigationController;
[self.window makeKeyAndVisible];
return YES;
}

然后在每个 ViewController viewWillAppear 方法中,我调整了 self.view 和 self.navigationController.navigationBar.frame 的大小,以便在横幅下方显示自己:
self.navigationController.navigationBar.frame = CGRectMake(0, 64, 320, 44);
self.view.frame = CGRectMake(0, 64, 320, 396);

这很好,完全按照我想要的方式工作。

但是如果用户按下主页按钮并且应用程序退出事件状态,当它再次变为事件状态时,最后一个 viewController 会显示但没有 UIWindow 横幅,并且 self.view 和 navigationBar 显示在顶部。

当然,当前的 UIViewController viewWillAppear 方法在应用程序返回事件时不会被调用,但即使我将调整大小代码放在另一个函数中并通过通知调用它也不起作用。但是当用户按下一个 bar item 并在导航堆栈中移动时,一切都会再次运行,UIWindow 会显示 headerView。

任何人都明白为什么当应用程序返回事件时 UIWindow headerView 会消失?

编辑1:可能的解决方案?
@interface RootViewController ()
{
ViewController *viewController;
UINavigationController *navigationController;
}

@end

@implementation RootViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
}
return self;
}

- (void)loadView
{
// Implement loadView to create a view hierarchy programmatically, without using a nib.
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 88)];

UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
[imageView setImage:[UIImage imageNamed:@"header"]];

[view addSubview:imageView];

navigationController.navigationBar.frame = CGRectMake(0, 44, 320, 44);

[view addSubview:navigationController.navigationBar];

self.view = view;

}

编辑 2:第二种可能的解决方案,仍然无法正常工作
- (void)loadView
{
NSLog(@"loadView root");

// Implement loadView to create a view hierarchy programmatically, without using a nib.
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 88)];

UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
[imageView setImage:[UIImage imageNamed:@"banner"]];
[view addSubview:imageView];

navigationController = [[UINavigationController alloc] init];
navigationController.navigationBar.frame = CGRectMake(0, 43, 320, 44);
[view addSubview:navigationController.navigationBar];

[self addChildViewController:navigationController];

self.view = view;
[self.view setBackgroundColor:[UIColor yellowColor]];
}

这是结果,看起来很好,没有 viewController1 的推送(注意黄色背景来自 rootViewController):

Without push

相反,这是添加的结果:
- (void)viewDidLoad
{
viewController1 = [[ViewController1 alloc] initWithNibName:@"ViewController1" bundle:nil];
[navigationController pushViewController:viewController1 animated:YES];
}

With PUSH

新的 View Controller 没有被推送(背景应该是黑色的)并且导航栏已经消失了。

编辑 3:Olloqui 解决方案,仍然无法工作
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window setBackgroundColor:[UIColor redColor]];

UIView *bannerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
[self.window addSubview:bannerView];

UIView *navigationView = [[UIView alloc] initWithFrame:CGRectMake(0, 44, 320, 416)];

ViewController1 *viewController1 = [[ViewController1 alloc] initWithNibName:@"ViewController1" bundle:nil];
self.navigationController = [[UINavigationController alloc] initWithRootViewController:viewController1];
self.navigationController.navigationBar.frame = CGRectMake(0, 0, 320, 44);

[navigationView addSubview:self.navigationController.navigationBar];

[self.window addSubview:navigationView];

self.window.rootViewController = self.navigationController;

self.window.autoresizesSubviews = YES;

[self.window makeKeyAndVisible];
return YES;
}

结果是我只有横幅,viewController1 被推送但没有显示导航栏。我真的需要弄清楚这一点,有人有不同的方法吗?

最佳答案

窗口期望有一个由它的 rootViewController 属性控制的 Root View 。从后台返回时,窗口只要求 rootViewController 恢复该 View Controller View 的外观。它不会要求所有 subview 刷新。

为了解决这个问题,我将创建一个新的 Root View Controller 。这将具有横幅和导航 Controller 。然后,该导航 Controller 将保存您的普通 View Controller 并管理导航。应用程序从后台返回后,横幅将正确显示。当导航发生在导航 Controller 中时,您的横幅将是静止的。

编辑:我编写了一个小示例程序。

我从一个简单的单 View 应用程序模板开始。我为内容添加了两个 View Controller 。仅具有用于区分的标签,并且具有用于加载第二个 View 的按钮。

所有的魔法都发生在主视图 Controller 的 viewDidLoad 方法中:

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
OneViewController *oneVC = [[OneViewController alloc] initWithNibName:@"OneViewController" bundle:nil];
self.navController = [[UINavigationController alloc]initWithRootViewController:oneVC];
self.navController.view.frame = CGRectMake(0.0, 64.0, 320.0, 416.0);
[self.view addSubview:self.navController.view];
[self addChildViewController:self.navController];
}

此 View 的 nib 加载横幅的 ImageView 。

The example project in on Bitbucket.

关于iphone - UIWindow subview 在应用程序变为事件状态后消失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10433459/

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