Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 黑屏-视图中将显示superview为零_Ios_Objective C_View_Superview - Fatal编程技术网

Ios 黑屏-视图中将显示superview为零

Ios 黑屏-视图中将显示superview为零,ios,objective-c,view,superview,Ios,Objective C,View,Superview,我有一个从选项卡式应用程序模板创建的应用程序。(ARC,iOS 4) 2上有几个选项卡和一个按钮。选项卡viewcontroller.view(ViewCont2) 此按钮通过presentModalViewController方法加载另一个viewcontroller的(ModalViewCont)视图 ModalViewCont上有一个关闭按钮,它调用dismissModalViewControllerAnimated 在ViewCont2的ViewDidEnglish中,我将self.v

我有一个从选项卡式应用程序模板创建的应用程序。(ARC,iOS 4)

  • 2上有几个选项卡和一个按钮。选项卡viewcontroller.view(ViewCont2)
  • 此按钮通过presentModalViewController方法加载另一个viewcontroller的(ModalViewCont)视图
  • ModalViewCont上有一个关闭按钮,它调用dismissModalViewControllerAnimated
  • 在ViewCont2的ViewDidEnglish中,我将self.view=nil和其他outlets设置为nil以卸载视图,以便下次它出现在屏幕上时重新加载。我这样做是因为它继承自基类(BaseViewCont),该基类初始化视图控制器的一些常规属性,并在viewDidLoad方法中添加一些按钮、标签等。因此,从该基类继承的ViewController可能会在其viewDidLoad方法中以不同的方式配置这些属性
问题

现在,当ModalViewCont出现在屏幕上时,按下Home按钮将应用程序置于后台,在将应用程序取回后,关闭ModalViewCont不会返回ViewCont2的视图,而是会返回一个底部带有选项卡栏的黑屏。同样的事情发生在不放置应用程序背景/前景的情况下;如果在轻敲2之前轻敲其他凸耳。选项卡。(编辑:只有在view中设置为nil的self.view将消失而不是VIEWDIDGEARE时,才会发生这种情况。)

我确定ViewCont2加载一个新视图(选中它的引用),但视图的superview为零,因此新视图不会显示,而是显示一个黑屏

不起作用的事情

  • 使用[self.view removeFromSuperview];在设置self.view=nil之前
  • 在视图中,将显示向父视图添加视图;[self.parentViewController.view addSubview:self.view];这一个工作不顺利,视图稍微向上放置在屏幕上。这是因为层次结构中还有其他几个超级视图
我考虑过的解决方案

  • 1-如果viewDidLoad中的superview为nil,则它将在ViewWill中可用(假设)。因此,ViewCont2的VIEWWILLISPENCE方法可用于通过以下方式正确加载superview:
_

  • 2-可以使用基类的ViewWillAspect方法进行初始化,因此无需卸载视图。所以,性能可以得到优化,不会在每次视图消失时卸载。此外,最好通过检查标志只执行一次初始化,而不是每次出现时都执行初始化
问题

  • 1-为什么不恢复superview?我该怎么办?(这是我想理解和解决的主要问题,而不是尝试其他方法……)
  • 2-通过将nil分配给视图以卸载它,我是否做错了什么?如果是这样,在这种情况下(选项卡式应用程序),我应该如何正确卸载视图
  • 3-1有什么问题吗。解决方案?这看起来像是一场混战吗?关于superview和ViewWill的假设是否正确

编辑:如果调用viewDidLoad的时间早于它应该调用的时间(即当viewDidLoad中的view nilled将消失而不是ViewDidDemouse),则superview未设置。

我认为不应该将该视图指定为nil。 如果我没有弄错,您希望在每次视图出现时刷新/重新加载内容。 因此,您应该尝试刷新视图,而不是将视图设置为nil。您可以通过添加:

    - (void)viewWillAppear{
    [self.view setNeedsDisplay];}

请告诉我我是否正确理解您的问题

这看起来很奇怪,但您的建议(1)确实是解决此问题的正确方法:

-(void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    if (!self.view.superview) { // check if view has been added to view hierarchy
        self.tabBarController.selectedViewController = nil;
        self.tabBarController.selectedViewController = self;
    }
}
您的第二个建议对性能有好处(因为视图加载是一项昂贵的操作),但它不能解决问题。在以下情况下,您也可以在不将视图设置为nil的情况下得到一个黑屏(在iOS模拟器中进行测试):

  • 打开模态视图
  • 模拟内存警告->这将卸载tabbarcontroller中的视图
  • 按home(主页)按钮,然后再次打开应用程序
  • 关闭模式视图->黑屏
  • 通常,您可以假设在viewDidLoad中设置了视图属性,在ViewWillDisplay+ViewDidDisplay中,视图已添加到视图层次结构中;因此,此时superview应该在那里(这里superview是UIViewControllerRapperView类的tabbarcontroller的私有视图)。然而,在我们的例子中,虽然视图被重新加载(在应用程序恢复时),但它没有添加到视图层次结构中,从而导致黑屏。这似乎是UtiAbbarController中的一个错误

    该解决方法强制再次执行外观选择器。因此,将再次调用ViewWillDisplay,这次将使用superview。同时,ViewDidDisplay将被调用两次


    将self.view设置为nil是可以的,但在大多数情况下不应该是必需的。让系统决定何时卸载视图(当内存不足时,iOS可以卸载视图)。视图控制器代码的设计应确保用户界面可以随时重新配置,而无需重新加载视图。

    您无法完全控制视图的加载和卸载时间,您也不能自己手动加载/卸载视图

    相反,您应该将视图加载/卸载视为完全由您的
    UIViewController
    s决定,您只负责:

    • 通过将UIViewController子类与nib文件关联,或通过手动实现
      loadView
      来实现实际加载
    • 可选地实现
      viewDidLoad
      viewWillUnload
      viewDidUnload
      回调,视图控制器在决定加载/卸载其视图时调用这些回调
    -(void)viewWillAppear:(BOOL)animated
    {
        [super viewWillAppear:animated];
    
        if (!self.view.superview) { // check if view has been added to view hierarchy
            self.tabBarController.selectedViewController = nil;
            self.tabBarController.selectedViewController = self;
        }
    }
    
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
        // A root view controller other than the actual UITabBarController is required.
        self.window.rootViewController = [[UIViewController alloc] init];
        [self.window makeKeyAndVisible];    
        self.tabBarController = [[UITabBarController alloc] init];
        self.tabBarController.viewControllers = [NSArray arrayWithObjects:viewController1, ..., nil];
    
        [self.window.rootViewController 
            presentModalViewController:self.tabBarController animated:NO];
    }
    
    - (void) tabBarBlankScreenFix1
    {
        self.window.rootViewController = [[UIViewController alloc] init];
        [self.window makeKeyAndVisible];
        [self.window addSubview:self.tabBarController.view];            
        self.window.rootViewController = self.tabBarController;
    
    }
    
    - (void) tabBarBlankScreenFix2
    {
        self.window.rootViewController = [[UIViewController alloc] init];
        [self.window makeKeyAndVisible];
        [self.window addSubview:self.tabBarController.view];
    }