0

我试图让我的头脑围绕视图控制器、子视图控制器、视图、容器等。我正在制作一个简单的应用程序,它将在左侧有一组图标,单击时将打开一个不同的屏幕右手边。基本设计是:

在此处输入图像描述

菜单栏将始终位于左侧,内容位于蓝色框中。我是否正确地说我应该具有以下结构:

在此处输入图像描述

那么当在左侧 UIView 上按下图像时,我应该将新的 UIView 推到右侧吗?或者这些应该是 UIViewControllers 吗?容器从哪里进入?

是否可以通过 Storyboards 执行此操作,或者是否无法链接按钮以将新的 UIView 推送到屏幕的不同部分,因此我需要通过代码来执行此操作?

4

2 回答 2

3

一种选择是使用UISplitViewControllerwhich 为您完成大部分工作。但这是我将如何去做。

  1. 有一个 HomeViewController,它是控制的基础层。这个类将处理:

    1.1 左侧按钮的 UI

    1.2 控制按下左键时发生的情况

    1.3 切换右侧的子视图控制器

  2. 左边UIView有个叫navView什么的,右边UIView有个叫containerView。

    2.1 navView 将始终可见

    2.2 containerView 负责显示你childViewController的视图

  3. 每当按下左侧的按钮时,您都会删除当前的 childViewController 并添加一个新的。

这是一个很好的教程


编辑**

回应评论:

When you initialize the TabBar it keeps an array of the viewControllers. So your right, viewDidLoad is only called once. All you have to do to achieve that is keep an array of all your viewControllers and switch them from there. I can post code on this if you want, it seemed a bit overkill for the initial question

这是我如何做到的示例:

- (void)updateChildViewController {

    //This is the VC that was being shown, but will be replaced by the new currentlyVisisbleViewController, we keep track of it so in the transitionFromViewController: method we have viewController to switch from.
    UIViewController *previousVisibleViewController = self.currentlyVisibleViewController;

    //We keep and array of both view controllers so that we only have to load them into memory once, so their viewDidLoad is only called once.
    if (!viewControllers) {
        viewControllers = [[NSMutableArray alloc] initWithObjects:[NSNull null], [NSNull null], nil];
    }

    //If a given VC has not been loaded before we know becuase it's spot in the viewControllers array will be Null. (as seen in the line above)
    if ([viewControllers objectAtIndex:self.displayType] == [NSNull null]) {

        id newlyLoadedViewController;

        //I have two display types I switch between, a map and list
        if (self.displayType == DTMap) {
            newlyLoadedViewController = [[MapViewController alloc] initWithNibName:@"MapViewController" bundle:nil];
        }
        else if (self.displayType == DTList) {
            newlyLoadedViewController = [[ListViewController alloc] initWithNibName:@"ListViewController" bundle:nil];

        }

        //Set the object in it's location in viewControllers array
        [viewControllers setObject:newlyLoadedViewController atIndexedSubscript:self.displayType];
    }

    //Set the new currentlyVisibleViewController
    self.currentlyVisibleViewController = [viewControllers objectAtIndex:self.displayType];

    //Adjust the frame to fit in the contentView (or the "container" view)
    self.currentlyVisibleViewController.view.frame = self.contentView.frame;

    //Make sure that it resizes on rotation automatically along with the contentView.
    self.currentlyVisibleViewController.view.autoresizingMask = self.contentView.autoresizingMask;

    //Let the old VC know that is going to be removed if it exist. We lazy load the UIViewControllers so on intial launch, there is only one UIViewController loaded, once we switch to another one we will have a previousVisibleViewController.
    if (previousVisibleViewController) {
        [previousVisibleViewController willMoveToParentViewController:nil];
    }

    //Add the currentlyVisibleViewController as a childViewController
    [self addChildViewController:self.currentlyVisibleViewController];

    //If there was a previousVC then we animate between them
    if (previousVisibleViewController) {
        [self transitionFromViewController:previousVisibleViewController
                          toViewController:self.currentlyVisibleViewController
                                  duration:0.0f
                                   options:UIViewAnimationOptionTransitionNone
                                animations:^{}
                                completion:^(BOOL finished) {

                                    //Notify the new visible viewController than the move is done
                                    [self.currentlyVisibleViewController didMoveToParentViewController:self];

                                    //Tell the old one it is no longer on the screen and has been removed.
                                    [previousVisibleViewController removeFromParentViewController];
                                }];
    }

    //Otherwise it's the first time we are adding a child so we need to link the views
    else {

        //Add it to content view, calls willMoveToParentViewController for us. We only have to set this once.
        [self.contentView addSubview:self.currentlyVisibleViewController.view];
    }

}
于 2013-11-07T22:46:53.247 回答
0

我建议使用容器视图控制器作为布局的根,然后为左侧菜单设置子视图控制器,为当前选定的项目/选项卡设置另一个视图控制器。然后在选择时,您只需交换右侧的(子)视图控制器(即从父视图控制器中删除当前视图控制器并添加一个新视图控制器)。虽然一开始听起来可能有点复杂,但当您继续进行项目时,它会更健壮且更容易实现更复杂的场景。

于 2013-11-07T22:41:59.303 回答