【问题标题】:Programmatically Switching Views in Cocoa Touch在 Cocoa Touch 中以编程方式切换视图
【发布时间】:2010-09-27 01:41:28
【问题描述】:

如何在 iPhone 应用程序中以编程方式更改屏幕上的视图?

我已经能够创建导航视图并以编程方式推送/弹出它们以产生这种行为,但是如果我想简单地更改当前视图(不使用 UINavigation 控制器对象),那么实现这一点的最佳方法是什么?

一个简单的例子,想象一个有一个按钮的应用程序,当按下时会显示一个新的视图,或者可能是多个视图之一,这取决于一些内部状态变量。

我还没有看到任何尝试这样做的示例,而且我似乎对 UIViewController/UIView 对象之间的关系和初始化过程了解不够,无法以编程方式实现这一点。

【问题讨论】:

  • 好问题。也一直在寻找这个答案

标签: ios objective-c iphone cocoa-touch


【解决方案1】:

将通用 UIView 推入 UINavigationController 怎么样?

当您想要显示一个特定视图时,只需将其作为子视图添加到之前推送的 UIView。当您想要更改视图时,请移除之前的子视图并添加新的。

【讨论】:

  • 是否可以在没有顶部导航视图栏的情况下执行此操作?如果可能的话,我希望能够只用一个标准的 UIView 对象来做到这一点。
【解决方案2】:

您会想要探索-[UIView addSubview:]-[UIView removeFromSuperview]。您的基本窗口是 UIView(后代),因此您可以向其添加和删除视图。

【讨论】:

  • 我一定会遗漏一些东西,因为每当我尝试使用该方法时,我都会遇到运行时异常。我会继续阅读。
【解决方案3】:

我使用presentModalViewController:animated: 从主窗口的UIViewController 调出设置视图,然后当用户在设置视图中按下“完成”时,我从设置视图调用dismissModalViewControllerAnimated:(返回父视图) 像这样:

[[self parentViewController] dismissModalViewControllerAnimated:YES];

【讨论】:

  • 我实际上刚刚找到了一个这样做的例子,并且正在回答我自己的问题。谢谢。
  • 如果您只需要一个模态,我喜欢这个解决方案的简单性。此方法现已弃用,但您可以改用 presentViewController: animated: completion:
【解决方案4】:

我找到了一个示例程序,它使用 ModalView 来显示视图而不将它们嵌套为 NavigatorControlView。

iPhone Nav Bar Demo

上面的示例链接,使用 modalView 作为信息链接。并且还使用导航链接作为表格视图链接。

【讨论】:

    【解决方案5】:

    据我所知,NavBarDemo 很有趣,但归根结底,modalView 只是另一个被推送和弹出堆栈的视图。

    在地图应用程序等情况下,当用户开始输入地址时,地图视图会切换到列出搜索选项的表格视图?这两个视图是否在启动时都已初始化,并且搜索结果表视图刚刚设置为可见性 0,当您键入时,它切换为 1,或者它实际上是在文本字段的 touchUpInside 事件中加载的?

    我将尝试使用 UIView addSubview 来重新创建此操作并发布我的结果

    【讨论】:

      【解决方案6】:

      您可以使用以下方法:

      BaseView.h - 所有其他视图都继承自该视图:

      @interface BaseView : UIView {}
      @property (nonatomic, assign) UIViewController *parentViewController;
      @end
      

      BaseView.m

      @implementation BaseView
      @synthesize parentViewController;
      
      - (id)initWithFrame:(CGRect)frame {
          if ((self = [super initWithFrame:frame])) {
              // Initialization code
          }
          return self;
      }
      
      - (void)dealloc {
          [self setParentViewController:nil];
          [super dealloc];
      }
      
      @end
      

      其他视图可以从 BaseView 继承。他们的代码应该有点像下面这样:

      @implementation FirstView
      
      - (id)initWithFrame:(CGRect)frame {
          if ((self = [super initWithFrame:frame])) {
              [self setBackgroundColor:[UIColor yellowColor]];
      
              UIButton *button1 = [[UIButton alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 200.0f, 30.0f)];
              [button1 setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
              [button1 setBackgroundColor:[UIColor whiteColor]];
              [button1 setCenter:CGPointMake(160.0f, 360.0f)];
              [button1 setTitle:@"Show Second View" forState:UIControlStateNormal];
              [button1 addTarget:self action:@selector(switchView:) forControlEvents:UIControlEventTouchUpInside];
              [self addSubview:button1];
              [button1 release];      
      
              UIButton *button2 = [[UIButton alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 200.0f, 30.0f)];
              [button2 setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
              [button2 setBackgroundColor:[UIColor whiteColor]];
              [button2 setCenter:CGPointMake(160.0f, 120.0f)];
              [button2 setTitle:@"Show Sub View" forState:UIControlStateNormal];
              [button2 addTarget:self action:@selector(showView:) forControlEvents:UIControlEventTouchUpInside];
              [self addSubview:button2];
              [button2 release];              
          }
      
          return self;
      }
      
      - (void)showView:(id)sender {
          if (viewController == nil) {
              viewController = [[SubViewController alloc] initWithNibName:nil bundle:nil];        
          }
      
          [self addSubview:viewController.view];
      }
      
      - (void)switchView:(id)sender {
          SecondView *secondView = [[SecondView alloc] initWithFrame:self.frame];
          [self.parentViewController performSelector:@selector(switchView:) withObject:secondView];
          [secondView release];
      }
      
      - (void)dealloc {
          [viewController release];
          [super dealloc];
      }
      
      @end
      

      最后,所有视图都需要 1 个 UIViewController。 switchView: 方法将被调用来改变当前视图。 UIViewController 的代码可能是这样的:

      @implementation ViewController
      
      - (void)loadView {
          FirstView *firstView = [[FirstView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 480.0f)];    
          [firstView setParentViewController:self];
          [self setView:firstView];
          [firstView release];
      }
      
      - (void)switchView:(BaseView *)newView {
          [newView setParentViewController:self];
          [self retain];
          [self setView:newView];
          [self release];
      }
      
      - (void)didReceiveMemoryWarning {
          [super didReceiveMemoryWarning];
      }
      
      - (void)viewDidUnload {
          [super viewDidUnload];
      }  
      
      - (void)dealloc {
          [super dealloc];
      }
      
      @end
      

      您可以在此处下载示例应用程序(下一小时内):http://dl.dropbox.com/u/6487838/ViewSwitch.zip

      【讨论】:

        【解决方案7】:

        这个提示是在Apple's documentation 上说的,但并不重要。我发现自己很难理解它,而且它非常简单。

        只需将主窗口的 rootViewController 属性更改为拥有您要显示的视图层次结构的任何视图控制器。就这么简单。一旦属性更新,整个窗口内容就会更改为新视图的内容。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-01-02
          相关资源
          最近更新 更多