【问题标题】:Get UIViewController to reload different UIView programmatically获取 UIViewController 以编程方式重新加载不同的 UIView
【发布时间】:2012-06-14 15:22:08
【问题描述】:

我正在重写 UIViewController 中的 loadView 方法,如下所示:

-(void)loadView
{
    NSLog(@"HPSFormController loadView starting"); 

    HPSFormView* viewForThisController = [ [ HPSFormView alloc ] initWithFrame:_frame ] ;
    self.view = viewForThisController;

}

当在视图中按下某个按钮时,相同的 UIViewController 会再次获得控制权,此时我希望完全更改控制器显示的视图。如下:

-(void)buttonTapped
{
    ABCFormView* newview = [ [ ABCFormView alloc ] initWithFrame:_frame ] ;
    self.view = newview;
}

但是,buttonTapped 方法不会加载第二个视图。而是显示一个完全空白的视图。

如何让视图控制器在按下按钮时重新加载完全不同的视图?

【问题讨论】:

  • 您应该使用导航控制器并推送您使用正确选项集创建的同一 uiviewController 子类的新实例。
  • 这不是一个很好的选择,因为视图控制器包含很多我需要复制的模型信息,而且我经常切换视图,所以我会一直弹出和推送控制器.有没有办法简单地更改现有控制器正在管理的 UIView?
  • loadView 和 buttonTapped 之间的 _frame 是否保持一致? self.view 通常由 UIKit 编辑以考虑各种因素。我建议实际上不要更改 self.view,而只是添加和删除视图作为 self.view 的子视图。

标签: objective-c ios uiview uiviewcontroller


【解决方案1】:

但是,buttonTapped 方法不会加载第二个视图。而是显示一个完全空白的视图。

问题不可能出在您创建ABCFormView 的方式上吗?我的意思是,原来的视图似乎被一个空视图所取代,所以检查后者是如何创建的......

评论后编辑:

如果你说视图是“在视图控制器的 viewDidLoad 方法中创建的”,那么你应该实例化你的视图控制器:

@property (...) ABCFormViewController* newviewController;

....

-(void)buttonTapped
{
    self.newviewController = [ [ ABCFormViewController alloc ] init] ;
    self.view = newviewController.view;
}

请记住,只要您使用受控的viewnewviewController 就必须存在,否则您会崩溃。这就是我将其引用存储在属性中的原因。

【讨论】:

  • 视图是在视图控制器的 viewDidLoad 方法中正确创建的,但是当 buttonTapped 方法正确设置 self.view 时,它永远不会被调用(但是当 self.view 从内部设置时它会被调用加载视图)。
  • 您是否尝试过将您的ABCFormView 添加为子视图,而不是直接分配给 self.view?
【解决方案2】:

显然你不能通过简单地设置 self.view = newView; 来让你的新视图可见。因为 newView 从未作为子视图添加到任何其他视图中 - 即不在窗口中。

如果您需要切换到不同的视图,您可能应该将 APSFormView 作为子视图添加到您的 viewcontroller.view,当您需要切换时,从父视图中删除 APSFormView,然后将 ABCFormView 作为新的子视图添加到 viewcontroller.view。

【讨论】:

    【解决方案3】:

    如果您的 loadView 实现不需要做太多其他事情,最好使用故事板进行初始设置。很容易错过,但您可以在情节提要中指定视图应该是自定义类型(在“身份检查器”中选择视图)。此外,可能值得评估为什么同一视图控制器实例需要完全不同的视图类别;对我来说,这可能是关于应用程序设计的一个危险信号。两个视图控制器之间的流程可能会更好地为您服务,或者在这个自定义 UIView 扩展类中编写一些状态更改逻辑。对我而言,将根据视图所代表的模型以及每个视图旨在促进的行为来做出决定。

    如果模型不同(即您的第一个视图显示帐户列表,第二个视图显示一个帐户详细信息),或者行为明显不同(即第一个是查看帐户,第二个是创建一个新帐户) ,那么我将使用两个不同的视图控制器。

    如果模型和行为相似,并且样式应该改变,那么我可能会在自定义视图类中编写状态改变代码来重新排列事物等。

    如果您来自不同的平台,一开始可能看起来很傻,但我们确实会毫不犹豫地扔掉视图控制器。它们由框架优雅地处理,旨在管理“一屏内容”并轻松切换到另一屏。

    【讨论】:

      【解决方案4】:

      如果不知道 ABCFormViewController 里面是什么,就很难说清楚。我曾经在视图控制器上遇到了一些计时问题,我只需要生成视图,因为我想捕获它的内容以创建一个 pdf 文件(它的视图永远不会显示在屏幕上)。在那种情况下,我需要插入这样的代码:

          [newviewcontroller.view setneedsrefresh]; 
      

      在我做之前

           otherVC.view = newviewcontroller.view;
      

      否则我会得到一个空白页。 我相信我明白了这一点,因为当一切都整理好时,ARC 会释放 newviewcontroller,因此视图为零。在您的情况下,这可能不是问题。您是否需要将第二个和第三个视图控制器放入您的视图中,因为这样做更简单的方法是通过模态、弹出视图或导航控制器将控制权转移到其他视图控制器。另一种更常用的方法是在 XIB 中创建多个视图,然后将其加载到空白视图中,而不是为每个视图创建视图控制器。

      【讨论】:

      • 顺便说一句,如果您想获得多个视图并仅将第二个和第三个加载为子视图,则可以使用命令从超级视图中删除子视图……。 [[[self.view subviews] objectAtIndex:0] removeFromSuperview];
      猜你喜欢
      • 1970-01-01
      • 2017-07-22
      • 1970-01-01
      • 2017-07-02
      • 2012-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-08
      相关资源
      最近更新 更多