10

我正在开发更可能是tabBarController应用程序的应用程序。但我不能使用,tabBarController因为我需要tab底部的自定义处理程序,我也需要项目之间的自定义空间。所以我正在创建 custom tabBarController

我想知道最好的方法。目前我的方法是这种方式(使用storyboardand iOS6):- 我采用了一个UIToolbarViewController充当底tab栏(CustomTabBarViewController)的方法。我拿了ContainerViews每个标签。当用户在 上选择一个项目时toolbar,我将显示它containerView

请告诉我我是否出错或指导最佳方式。谢谢。

4

4 回答 4

17

你这样做非常非常错误。当您可以只使用默认视图层次结构时,不要创建自定义视图层次结构。

您要做的是创建一个子类UITabBarController并创建一个 .xib 文件,该文件将包含您的自定义标签栏 - 只是一个图像和任意数量的 UIButtons(我想 5 个)。

在此处输入图像描述

为所有这些设置标签,只有 1-5 个标签,您可以使用自定义UIView子类来完成,但在这种情况下这将是多余的,所以它只是获取带有标签的控件。

创建一个子类UITabBarController。您需要引用所有这些按钮以及查看最后按下哪个按钮的属性,以便您可以适当地更新 UI。还为不同的控制状态分配不同的图像或标题,在这种情况下我使用默认并选择。

MYBaseTabBarController.h

@interface MYBaseTabBarController : UITabBarController
@property (strong, nonatomic) UIButton *btn1;
@property (strong, nonatomic) UIButton *btn2;
@property (strong, nonatomic) UIButton *btn3;
@property (strong, nonatomic) UIButton *btn4;
@property (strong, nonatomic) UIButton *btn5;
@property (weak, nonatomic) UIButton *lastSender;

@property (strong, nonatomic) UIView *tabBarView;

@end

MYBaseTabBarController.m

首先,创建视图控制器(UINavigationController在这种情况下都是子类)并将它们UITabBarController作为viewControllers属性分配给您的子类。

- (id)init {
  self = [super init];
  if (self) {
    [self setup];
  }
  return self;
}

- (void)setup {
  NSMutableArray *viewControllers = [NSMutableArray array];

  MYViewController1 *viewController1 = [[MYStoryboardManager storyboard1] instantiateInitialViewController];
  viewController1.title = @"1";
  [viewControllers addObject:viewController1];

  MYViewController2 *viewController2 = [[MYStoryboardManager storyboard2] instantiateInitialViewController];
  viewController2.title = @"2";
  [viewControllers addObject:viewController2];

  UIViewController *blankController = [UIViewController new]; // Center button, performs an action instead of leading to a controller
  [viewControllers addObject:blankController];

  MYViewController3 *viewController3 = [[MYStoryboardManager storyboard3] instantiateInitialViewController];
  viewController3.title = @"3";
  [viewControllers addObject:viewController3];

  MYViewController3 *viewController4 = [[MYStoryboardManager storyboard4] instantiateInitialViewController];
  viewController4.title = @"4";
  [viewControllers addObject:viewController4];

  self.viewControllers = viewControllers;
}

接下来获取您之前创建的按钮并在-viewDidLoad方法中为它们分配操作:

- (void)viewDidLoad {
  [super viewDidLoad];

  _tabbarView = [[[NSBundle mainBundle] loadNibNamed:@"MyTabBar" owner:nil options:nil] lastObject]; // "MyTabBar" is the name of the .xib file
  _tabbarView.frame = CGRectMake(0.0,
                                 self.view.frame.size.height - _tabbarView.frame.size.height,
                                 _tabbarView.frame.size.width,
                                 _tabbarView.frame.size.height); // make it overlay your actual tab bar
  [self.view addSubview:_tabbarView];

  _btn1 = (UIButton *)[_tabbarView viewWithTag:1];
  [_btn1 addTarget:self action:@selector(processBtn:) forControlEvents:UIControlEventTouchUpInside];

  _btn2 = (UIButton *)[_tabbarView viewWithTag:2];
  [_btn2 addTarget:self action:@selector(processBtn:) forControlEvents:UIControlEventTouchUpInside];

  _btn3 = (UIButton *)[_tabbarView viewWithTag:3];
  [_btn3 addTarget:self action:@selector(processBtn:) forControlEvents:UIControlEventTouchUpInside];

  _btn4 = (UIButton *)[_tabbarView viewWithTag:4];
  [_btn4 addTarget:self action:@selector(processBtn:) forControlEvents:UIControlEventTouchUpInside];

  _btn5 = (UIButton *)[_tabbarView viewWithTag:5];
  [_btn5 addTarget:self action:@selector(processBtn:) forControlEvents:UIControlEventTouchUpInside];

  _lastSender = _btn1;
  [self setSelectedViewController:self.viewControllers[0]]; // make first controller selected
}

添加处理方法:

- (void)processBtn:(UIButton *)sender {
  _lastSender = sender;
  [self setSelectedViewController:[self.viewControllers objectAtIndex:sender.tag - 1]];
}

最后覆盖该-setSelectedViewController:方法:

- (void)setSelectedViewController:(UIViewController *)selectedViewController {
  if (_lastSender != _btn3) { // check if it's not the action button
    for (UIButton *btn in [_tabbarView subviews]) {
      if ([btn isKindOfClass:[UIButton class]]) {
        if (btn == _lastSender) {
          btn.selected = YES;
        }
        else {
          btn.selected = NO;
        }
      }
    }
  }
  if ([self.viewControllers indexOfObject:selectedViewController] == 2) {
    MYActionController *viewController = [[MYStoryboardManager actionStoryboard] instantiateInitialViewController];
    [self presentViewController:viewController animated:YES completion:nil];
  }
  else {
    if (self.selectedViewController == selectedViewController) {
      [(UINavigationController *)self.selectedViewController popToRootViewControllerAnimated:animate]; // pop to root if tapped the same controller twice
    }
    [super setSelectedViewController:selectedViewController];
  }
}

我假设您在启用 ARC 的情况下进行编程,并且您有一个管理故事板的类,但无论如何这非常简单。

于 2013-05-03T10:09:20.700 回答
4

下面的代码在我的项目中完美运行。

我使用了如下的swift3版本:

我添加了 MyTabBar.xib 文件,其中包含带有 4 个按钮的 UIView。在 xib 文件中,设置 UIView 的类。class = "MyTabBar" 相应地
给 4 个按钮标签 1,2,3,4..

在 myTabBarController 文件下方

myTabBarController.swift 代码如下:

class myTabBarController: UITabBarController {

var tabBarView: UIView!

var btn1: UIButton!
var btn2: UIButton!
var btn3: UIButton!
var btn4: UIButton!

var lastSender: UIButton!

var categoryViewController: CategoryViewController?
var subCategoryViewController: SubCategoryViewController?
var scoreViewController: ScoreViewController?
var profileViewController: ProfileViewController?

override func viewDidLoad() {
    super.viewDidLoad()
    self.setup()

    tabBarView = Bundle.main.loadNibNamed("MyTabBar", owner: nil, options: nil)?.last as! UIView
    tabBarView.frame = CGRect(x: 0.0, y: self.view.frame.size.height - tabBarView.frame.size.height, width: tabBarView.frame.size.width, height: tabBarView.frame.size.height)
    self.view.addSubview(tabBarView)

    btn1 = tabBarView.viewWithTag(1) as? UIButton
    btn1.addTarget(self, action: #selector(self.processBtn), for: .touchUpInside)
    btn2 = tabBarView.viewWithTag(2) as? UIButton
    btn2.addTarget(self, action: #selector(self.processBtn), for: .touchUpInside)
    btn3 = tabBarView.viewWithTag(3) as? UIButton
    btn3.addTarget(self, action: #selector(self.processBtn), for: .touchUpInside)
    btn4 = tabBarView.viewWithTag(4) as? UIButton
    btn4.addTarget(self, action: #selector(self.processBtn), for: .touchUpInside)

    let width1 = self.view.frame.width/4
    btn1.frame = CGRect(x: 0, y: 0, width: width1, height: tabBarView.frame.size.height)
    btn2.frame = CGRect(x: btn1.frame.width, y: 0, width: width1, height: tabBarView.frame.size.height)
    btn3.frame = CGRect(x: btn2.frame.origin.x+btn2.frame.width, y: 0, width: width1, height: tabBarView.frame.size.height)
    btn4.frame = CGRect(x: btn3.frame.origin.x+btn3.frame.width, y: 0, width: width1, height: tabBarView.frame.size.height)

    lastSender = btn1
    selectedViewController = viewControllers?[0]
}

func processBtn(_ sender: UIButton) {
    lastSender = sender
    selectedViewController = viewControllers?[sender.tag - 1]

    if sender.tag == 1 {
        btn1.backgroundColor = UIColor.red
        btn2.backgroundColor = UIColor.yellow
        btn3.backgroundColor = UIColor.yellow
        btn4.backgroundColor = UIColor.yellow
    }else if sender.tag == 2 {
        btn1.backgroundColor = UIColor.yellow
        btn2.backgroundColor = UIColor.red
        btn3.backgroundColor = UIColor.yellow
        btn4.backgroundColor = UIColor.yellow
    }else if sender.tag == 3 {
        btn1.backgroundColor = UIColor.yellow
        btn2.backgroundColor = UIColor.yellow
        btn3.backgroundColor = UIColor.red
        btn4.backgroundColor = UIColor.yellow
    }else if sender.tag == 4 {
        btn1.backgroundColor = UIColor.yellow
        btn2.backgroundColor = UIColor.yellow
        btn3.backgroundColor = UIColor.yellow
        btn4.backgroundColor = UIColor.red
    }
}

func setup() {
    var viewControllers = [AnyObject]()

    categoryViewController = self.storyboard!.instantiateViewController(withIdentifier: "CategoryViewController") as? CategoryViewController
    viewControllers.append(categoryViewController!)

    subCategoryViewController = self.storyboard!.instantiateViewController(withIdentifier: "SubCategoryViewController") as? SubCategoryViewController
    viewControllers.append(subCategoryViewController!)

    scoreViewController = self.storyboard!.instantiateViewController(withIdentifier: "ScoreViewController") as? ScoreViewController
    viewControllers.append(scoreViewController!)

    profileViewController = self.storyboard!.instantiateViewController(withIdentifier: "ProfileViewController") as? ProfileViewController
    viewControllers.append(profileViewController!)

    self.viewControllers = viewControllers as? [UIViewController]
}

func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {

    for view in tabBarView.subviews as [UIView] {
        if let btn = view as? UIButton {
            if btn == lastSender {
                btn.isSelected = true
            }
            else {
                btn.isSelected = false
            }
        }
    }

    if self.selectedViewController == viewController {
        (self.selectedViewController as? UINavigationController)?.popToRootViewController(animated: true)
        // pop to root if tapped the same controller twice
    }

    return (viewController != tabBarController.selectedViewController)
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

}

这样您就可以根据需要设计自定义标签栏。

谢谢

于 2017-08-28T09:00:59.643 回答
0

以下是您需要遵循的步骤才能制作以下视图:-

1:取一个 UITabBarController 并将其设置为应用程序窗口的 rootViewController。

2:现在将五个选项卡添加到此 UITabbarController 。

3:为每个选项卡分别添加五个单独的 UINavigationController。

4:现在分别给UINavigationController添加五个不同的UIViewController。

5:现在创建一个自定义标签栏:

5.1:创建自定义Tabbar的方法之一是获取Tabbar高度的UIView并将UIButtons作为Tab添加到Tabbar。

6:将自定义 tabBar 添加到 MainWindow 。在自定义标签栏上选择各种按钮时,更改应用程序 UITabbarController 的 setSelectedIndex。

于 2013-05-03T10:06:47.707 回答
0

对于 ios 9.0+,在水平方向使用 UIStackView 并创建一个 xib 并将其命名为 CustomTabBarView

自定义TabBarView.Xib在其中插入 uistackview

像这样设置堆栈视图属性

创建另一个视图 CustomTabBarItem。

CustomTabBarItem.xib 在此处输入图像描述

创建CustomTabBarItem.swift文件以实现 TabItem 的功能

class CustomTabItem: UIView {

//MARK:- IBOutlets
@IBOutlet weak var itemImage: UIImageView!
@IBOutlet weak var itemTitle: SelectableLabel!
@IBOutlet weak var topButton: UIButton!

//MARK:- Variables
var isSelected: Bool = false {
    didSet {
        self.itemImage.image = CommonFunctions.getTabItemImage(isSelected: isSelected, tag: topButton.tag)
        itemTitle.isSelected = isSelected
        if isSelected {
            self.backgroundColor = UIColor.appDarkBlueColor
        }
        else {
            self.backgroundColor = UIColor.appWhiteColor
        }
    }
}

//MARK:- IBActions
@IBAction func onClickButton(_ sender: Any) {

}

}

在 TabBarViewController 中实现此代码

func createCustomTabBarView(tabItemCount: Int){

    customTabBarView = Bundle.main.loadNibNamed("CustomTabBarView", owner: nil, options: nil)?.last as! UIView
    customTabBarView.frame = CGRect(x: 0, y: self.view.frame.height - self.tabBar.frame.height, width: self.tabBar.frame.width, height: self.tabBar.frame.size.height)
    self.view.addSubview(customTabBarView)

    var stackView = UIStackView()
    for subView in customTabBarView.subviews{
        if subView is UIStackView {
            stackView = subView as! UIStackView
        }
    }

    for i in 0..<tabItemCount {
        let customTabItemView = Bundle.main.loadNibNamed("CustomTabItem", owner: nil, options: nil)?.last as! CustomTabItem
        switch i {
        case CustomTabbarButtonTag.TabBarItem_First.rawValue:
            customTabItemView.itemTitle.text = "TabBarItem_First"
            customTabItemView.topButton.tag = CustomTabbarButtonTag.TabBarItem_First.rawValue
            customTabItemView.isSelected = false

        case CustomTabbarButtonTag.TabBarItem_Second.rawValue:
            customTabItemView.itemTitle.text = "TabBarItem_Second"
            customTabItemView.topButton.tag = CustomTabbarButtonTag.TabBarItem_Second.rawValue
            lastSelectedTabItem = customTabItemView
            customTabItemView.isSelected = true

        case CustomTabbarButtonTag.TabBarItem_Third.rawValue:
            customTabItemView.itemTitle.text = "TabBarItem_Third"
            customTabItemView.topButton.tag = CustomTabbarButtonTag.TabBarItem_Third.rawValue
            customTabItemView.isSelected = false

        case CustomTabbarButtonTag.TabBarItem_Fourth.rawValue:
            customTabItemView.itemTitle.text = "TabBarItem_Fourth" 
            customTabItemView.topButton.tag = CustomTabbarButtonTag.TabBarItem_Fourth.rawValue
            customTabItemView.isSelected = false
            cmsTabItem = customTabItemView

        default:
            break
        }

        customTabItemView.topButton.addTarget(self, action: #selector(tabBarButtonPressed), for: .touchUpInside)
        stackView.addArrangedSubview(customTabItemView)
    }
}

//MARK:- IBActions
func tabBarButtonPressed(_ sender: UIButton){
    // create global variable lastSelectedTabItem for store last selected tab item and set its isSelected value for manage highlight current selected tabItem
    lastSelectedTabItem.isSelected = false
    let customTabItem = sender.superview as! CustomTabItem
    lastSelectedTabItem = customTabItem
    lastSelectedTabItem.isSelected = true 
    self.selectedIndex = sender.tag
}
于 2017-05-27T10:32:39.987 回答