可重复使用的按钮栏?

时间:2012-09-25 22:03:56

标签: objective-c cocoa-touch ios6

我正在使用故事板实现IOS6应用。我希望每个屏幕 - 对不起,场景 - 让应用程序在顶部有一个包含不同大小的不同图像按钮的视图。点击按钮可以将用户带到应用程序的不同场景。

据我所知,这对于UITabController来说太复杂了。我尝试为该视图创建一个单独的视图控制器并在每个场景中包含视图,但视图中的任何功能(例如按钮)都会导致应用程序崩溃。

看起来我可能必须在一个场景中的故事板中实现此视图,然后将其复制并粘贴到每个其他场景中,将每个场景中的segue连接到每个其他场景。真是个噩梦!还有更好的方法吗?

1 个答案:

答案 0 :(得分:1)

由于您尝试创建自定义UITabBarController,因此应使用容器视图控制器。要做到这一点:

  1. 打开你的故事板并添加一个自定义的UIVIewController(让我们称之为ContainerViewController)。
  2. 将代表您的标签的UIVIews插入该控制器,然后在屏幕的其余部分插入另一个UIVIew(下面的代码中的* currentView)。这就是儿童控制器用来显示场景的内容。
  3. 为您需要的每个场景(子控制器)创建一个UIVIewController,就像通常一样,并为每个场景提供一个唯一的标识符(Identity Inspector - > Storyboard ID)
  4. 现在你必须在ContainerViewController中添加以下代码:

    @interface ContainerViewController ()
        @property (strong, nonatomic) IBOutlet UIView *currentView; // Connect the UIView to this outlet
        @property (strong, nonatomic) UIViewController *currentViewController;
        @property (nonatomic) NSInteger index;
    @end
    
    @implementation ContainerViewController
    
    // This is the method that will change the active view controller and the view that is shown
     - (void)changeToControllerWithIndex:(NSInteger)index
    {
        if (self.index != index){
            self.index = index;
            [self setupTabForIndex:index];
    
            // The code below will properly remove the the child view controller that is
            // currently being shown to the user and insert the new child view controller.
            UIViewController *vc = [self setupViewControllerForIndex:index];
            [self addChildViewController:vc];
            [vc didMoveToParentViewController:self];
    
            if (self.currentViewController){
                [self.currentViewController willMoveToParentViewController:nil];
    
                [self transitionFromViewController:self.currentViewController toViewController:vc duration:0 options:UIViewAnimationOptionTransitionNone animations:^{
                    [self.currentViewController.view removeFromSuperview];
                    [self.currentView addSubview:vc.view];
                } completion:^(BOOL finished) {
                    [self.currentViewController removeFromParentViewController];
                    self.currentViewController = vc;
                }];
            } else {
                [self.currentView addSubview:vc.view];
                self.currentViewController = vc;
            }
        }
    }
    
    // This is where you instantiate each child controller and setup anything you need  on them, like delegates and public properties.
    - (UIViewController *)setupViewControllerForIndex:(NSInteger)index {
    
        // Replace UIVIewController with your custom classes
        if (index == 0){
            UIViewController *child = [self.storyboard instantiateViewControllerWithIdentifier:@"STORYBOARD_ID_1"];
            return child;
        } else {
            UIViewController *child = [self.storyboard instantiateViewControllerWithIdentifier:@"STORYBOARD_ID_2"];
            return child;
        }
    }
    
    // Use this method to change anything you need on the tabs, like making the active tab a different colour
    - (void)setupTabForIndex:(NSInteger)index{
    
    }
    
    // This will recognize taps on the tabs so the change can be done
    - (IBAction)tapDetected:(UITapGestureRecognizer *)gestureRecognizer {
        [self changeToControllerWithIndex:gestureRecognizer.view.tag];
    }
    

    最后,您创建的代表标签的每个视图都应该拥有自己的TapGestureRecognizer和一个标签编号。

    通过这一切,您将拥有一个带有所需按钮的控制器(它们不必是可重复使用的),您可以在其中添加所需的功能(这就是使用setupTabBarForIndex:方法)你不会违反DRY。