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

标签 iphone ios uiview uiviewcontroller

所以,我试图在 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/

相关文章:

iphone - ios - 如何用名称初始化数组?

iphone - 如何从 ABAddressBookRef 中提取国家/地区字段?

ios - 在 iOS 中的字典中使用字典数组的 NSPredicate 进行过滤

iphone - ios5 上的自动释放替代方案

ios - View 中的图像大于设备屏幕

ios - 如果没有动画影响,立即移动到完成

iPhone游戏开发,用文件或sqlite保存状态?

iphone - IOS8应用程序支持IOS 7和IOS 6吗?

ios - Xcode 5 iOS 7 中的自动属性综合警告

uiview - 如何使用动画缩放 uiview 及其内部的所有内容(其他自定义绘制的 uiview)?