在应用程序中覆盖所有其他viewControllers的视图的正确方法是什么?

时间:2013-03-10 20:07:42

标签: ios objective-c cocoa-touch uiviewcontroller

我对iOS开发相对较新,正在筹划应用程序。该应用程序将有几个不同的场景/ ViewControllers将占据整个屏幕。

我打算在屏幕的左上方总是有一个小按钮,用户可以将用户带回主页,无论当前显示的是哪个vc。

我可以在每个viewController的视图中放置一个单独但相同的按钮,但这看起来不够优雅和脆弱。

我阅读View Controllers编程指南之后的本能是创建一个视图控制器容器,它将是根vc - 这个vc将有两个子vcs - 一个带有home按钮,另一个带有所有其他VC的进去(有效地成为新的根vc。)

这对于更有经验的iOS开发人员来说是否是一个明智的解决方案?有更简单的解决方案吗?

感谢收到任何建议。

2 个答案:

答案 0 :(得分:1)

我认为这可能是您最好的解决方案。在iOS中,ViewController占用了它的所有可用空间。如果没有您自己管理的“容器”视图,您放置的任何视图控制器都会占用整个窗口,覆盖您显示的任何内容。

但是,根据您的项目,还有一种可能更简单的替代方法。

您可以在某个中心位置创建一个UIView对象(您的按钮)(例如,您的App Delegate类)。该视图可以有一个附加到方法的按钮:

@implementation AppDelegate

- (void) someSetupMethod {
    UIButton* b = [UIButton buttonWithType:UIButtonTypeCustom];
    // setup whatever properties

    // Now set button to call a method *on this AppDelegate object* ("self"):
    [b addTarget:self action:@selector(homeButtonTapped:) forControlEvents:UIControlEventTouchUpInside];

    // Store the button definition somewhere permanant
    self.reusableHomeButton = b;
}

- (void) homeButtonTapped:(id)sender {
    // do something to pop view controllers back to what you want.
}

然后,在视图控制器中,他们可以在出现时显示主页按钮:

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

    AppDelegate* appDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
    [self.view addSubview:appDelegate.reusableHomeButton];
}

这利用了[view addSubview:...]的故意副作用,即如果视图已经存在于某个父视图中,则首先从该父视图中删除它,然后添加到新视图中视图。

它还利用了一个按钮可以将消息发送到任何对象的事实。它不必是ViewController,而是按下按钮的父视图。

这会使您的按钮在显示新控制器时从一个显示的视图控制器的.view“移动”到一个新按钮。

由于按钮具有AppDelegate对象的目标(并因此将其消息发送到该对象),因此只要app delegate对象存在以接收消息,它就可以“从任何地方”工作(它执行的时间很长)当你的应用程序正在运行)。

答案 1 :(得分:0)

使用Swift,您可以充分利用协议和协议扩展。我写了一篇关于这种方法的article。简而言之,您需要以下内容:

  1. 创建描述覆盖视图控制器的协议。
  2. 使用协议扩展封装将视图控制器呈现/解除的逻辑。
  3. 为叠加主机创建协议。
  4. 使用协议扩展封装将故事板中的覆盖视图控制器实例化为该协议的逻辑。
  5. 你们都准备好了。用法如下:

    class ViewController: UIViewController, OverlayHost {
        @IBAction func showOverlayButtonPressed() {
            showOverlay(type: YourOverlayViewController.self, 
                fromStoryboardWithName: "Main")
        }
    }
    

    源代码:https://github.com/agordeev/OverlayViewController