哪个是创建自定义标签栏控制器的最佳方法?

时间:2013-05-03 09:30:40

标签: ios objective-c uitabbarcontroller

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

我想知道最好的方法。目前我的方法是这样的(使用storyboardiOS6): - 我在UIToolbarViewController,它将作为底部tab栏( CustomTabBarViewController)。我为每个标签选择了ContainerViews。当用户选择toolbar上的项目时,我会显示containerView

请告诉我,如果我出错或指导最佳方式。感谢。

4 个答案:

答案 0 :(得分:17)

你这样做非常错误。如果只能使用默认视图层次结构,请不要创建自定义视图层次结构。

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

enter image description here

为所有这些标签设置标签,只需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进行编程,并且您有一个管理故事板的课程,但无论如何这都非常简单。

答案 1 :(得分:2)

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

我使用了 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()
}

}

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

由于

答案 2 :(得分:0)

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

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

2:现在为这个UITabbarController添加五个标签。

3:分别为每个Tab添加五个单独的UINavigationController。

4:现在分别向UINavigationController添加五个不同的UIViewControllers。

5:立即创建自定义标签栏:

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

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

答案 3 :(得分:0)

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

<强> CustomTabBarView.Xib insert uistackview in it

Set Stack view attributes like this

创建另一个视图CustomTabBarItem。

<强> CustomTabBarItem.xib enter image description here

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

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
}

}

在TabBarViewController中实现此代码

body {
  font-family: Arial, Helvetica, sans-serif;
  font-size: 16px;
  margin: 0;
  padding: 0;
  line-height: 50px
}

header {
  background-color: #191919;
  position: fixed;
  z-index: 4;
  width: 100%;
  color: #edf9ff;
  min-height: 70px;
  border-bottom: #0fe216 3px solid;
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 20px;
  margin-top:0;
}

header a {
  text-decoration: none;
  text-transform: uppercase;
  color: #edf9ff;
}
a:hover {
  color:blue;
}

header ul {
  margin: 0;
}

header li {
  list-style-type: none;
  float: left;
  padding-right: 20px;
}
#showtime {
  position:relative;
  top:100px;
  width:80%;
  margin: 0 auto;
  margin-bottom: 50px;
  background-color: #f2f2f2;
}
#showtime img {
  width:300px;
  height:300px;
}
/*Image Repz*/
.showright {
  clear:both;
}

.highlight {
  font-size:125%;
  color:blue;
}
.showright img {
  float:right;
  clear:both;
}
.boxes:first-child {
  padding-top:50px;
}
.boxes:not(:first-child) {
  padding-top:100px;
  
}
.showright > p, .showright > h2 {
  text-align: center;
}
.showleft img {
  float:left;
  clear:both;
}
.showleft > p, .showleft > h2 {
  text-align: center;
}
footer {
  position: relative;
  margin-top:30px;
  background-color:#191919;
  height: 100px;
  display: flex;
  align-items: center;
  justify-content: center;
  clear:both;
}
footer p{
  text-align: center;
  color: white;
}