如何以编程方式删除在父类 NIB 文件中创建的选项卡条目?

18

我在 iPhone 应用程序中有一个常见的标签栏,包含三个选项卡,在按下按钮后从几个视图中呈现。我采用的方法是仿照 Tweetie 应用程序中描述在 Robert Conn 的文章 中的工作流程。

请注意,主控制器是导航控制器;标签栏放置在视图控制器的 NIB 文件中,并且在 delegate 的 didSelectItem 方法中处理切换选项卡的效果。

@interface GameTabBarController : UIViewController<UITabBarDelegate> {
  UITabBar *tabBar;
  UITabBarItem *lastGameTabBarItem;
  UITabBarItem *previousGamesTabBarItem;
  UITabBarItem *myBetsTabBarItem;

  NSArray *viewControllers;
  UIViewController *currentViewController;
}

@implementation GameTabBarController
  ...

  - (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item {
    UIViewController *viewController = nil;

    // Get the view controller linked to the tab bar item pressed
    ...

    // Switch to the view
    [self.currentViewController.view removeFromSuperview];
    [self.view addSubview:viewController.view];
    self.currentViewController = viewController;
  }

  ...
@end

由于选项卡栏的视图必须根据应用程序所来自的视图控制器进行自定义,因此我将这个 GameTabBarController 设计为一个父类,并在其中使用该具有标签栏的 NIB 文件。然后,我创建了几个子类:

@interface FirstGameTabBarController : GameTabBarController {
  ...   
}

@interface SecondGameTabBarController : GameTabBarController {
  ...   
}

...
我的问题是,在某些子类中,我想删除与父类关联的NIB文件的第三个选项卡。但由于没有涉及UITabBarController,因此我无法像在网上找到的典型方法一样删除选项卡条目的视图控制器。
如何做到这一点?是否可以删除先前在NIB文件中添���的元素?
谢谢!
更新 解决方案非常简单...我只需要替换选项卡条目,而不是视图控制器:
NSMutableArray *items = [NSMutableArray arrayWithArray:self.tabBar.items];
[items removeObjectAtIndex:2];
[self.tabBar setItems:items];

感谢 @Praveen S 指导我正确的方向。

4个回答

46
以下代码是解决方案:
NSMutableArray *tbViewControllers = [NSMutableArray arrayWithArray:[self.tabBarController viewControllers]];
[tbViewControllers removeObjectAtIndex:2];
[self.tabBarController setViewControllers:tbViewControllers];

1
这个方法在iOS11中仍然可用,不像其他一些丑陋的hack。^_^ - Kaolin Fire

8
这是我在Swift 4和5中使用的方法:
  1. Create a custom UITabBarController class.
  2. Assign the custom UITabBarController class to the view on storyboard.
  3. Remove the UIViewController on viewDidLoad:

    class TabViewController: UITabBarController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            self.viewControllers?.remove(at: 1)
        }
    }
    

按照我的预期工作。在我看来,这是最好的方法。 - brainray
这样使用安全吗? - Yawar

8

Swift 4

func removeTab(at index: Int) {
    guard let viewControllers = self.tabBarController?.viewControllers as? NSMutableArray else { return }
    viewControllers.removeObject(at: index)
    self.tabBarController?.viewControllers = (viewControllers as! [UIViewController])
}

@Yawar,也许在您的视图控制器层次结构中没有正确配置选项卡控制器。 - mourodrigo

2
你可以在你的类中保留对该选项卡栏对象的引用,并对其执行所需的操作。
IBOutlet <Type> name;

通过界面构建器连接它,您可以执行操作,在您的情况下,您可能正在考虑将其从超级视图中移除。


你指引了我正确的方向,尽管你的回答并不完全是我在寻找的。我正在更新问题,以发布我最终完成的内容。 - elitalon
2
您不能直接从其父视图中删除 UITabBarItem,因为它是一个 UIBarItem,它继承自 NSObject 而不是 UIView。您需要遍历 UITabBar 的子视图,并找出哪个对应于 UITabBarItem,这可能需要使用私有 API。 - devios1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接