2013-05-03 19 views
6

Pracuję nad aplikacją, która jest bardziej prawdopodobna niż aplikacja tabBarController. Ale nie mogę użyć tabBarController, ponieważ potrzebuję niestandardowej obsługina dole również potrzebuję niestandardowej przestrzeni między elementami. Tak więc tworzę niestandardowy tabBarController.Jakie jest najlepsze podejście do tworzenia niestandardowego kontrolera paska kart?

Chciałbym poznać najlepsze podejście. Obecnie moje podejście jest w ten sposób (przy użyciu storyboard i iOS6): - Wziąłem UIToolbar na ViewController, który będzie działać jako dolny pasek tab (CustomTabBarViewController). Wziąłem ContainerViews dla każdej karty. Gdy użytkownik wybierze element na toolbar, pokażę, że containerView.

Proszę, powiedz mi, czy idę źle lub prowadzę najlepszy sposób. Dzięki.

Odpowiedz

0

Oto krokiem, jaki należy wykonać w celu uczynienia następujący pogląd: -

1: Weź UITabBarController i ustawić go jako rootViewController swojego okna aplikacji.

2: Teraz dodaj Pięć Tab do tego UITabbarController.

3: Dodaj pięć osobnych kontrolerów UINavigationController do każdej Tabki pojedynczo.

4: Teraz dodaj kolejno pięć różnych kontrolerów UIView do kontrolera UINavigationController.

5: Tworzenie niestandardowej umieszczenie zakładek teraz:

5.1: Jeden sposób tworzenia niestandardowych umieszczenie zakładek ma podjąć UIView z wysokości umieszczenie zakładek i dodać UIButtons jako zakładkę, aby na umieszczenie zakładek.

6: Dodaj zakładkę CustomBar do MainWindow. Wybierając różne przyciski na niestandardowym pasku zakładek zmień setSelectedIndex swojej aplikacji UITabbarController.

15

Robisz to bardzo źle. Nie twórz niestandardowej hierarchii widoków, kiedy możesz po prostu użyć domyślnej.

Co chcesz zrobić, to stworzyć podklasę UITabBarController, a także utworzyć plik .xib, który będzie zawierać niestandardowy pasek kart - po prostu obraz i dowolną liczbę UIButtons (przypuszczam, że 5).

enter image description here

Zestaw tagów dla wszystkich z nich, zaledwie 1-5 tagi, można ewentualnie zrobić z niestandardowych UIView podklasy, ale to byłoby zbędne w tym scenariuszu, więc to będzie kontroluje tylko rozróżniając z tagami.

Utwórz podklasę UITabBarController. Będziesz musiał mieć odniesienia do wszystkich tych przycisków, a także właściwość, aby zobaczyć, który przycisk został naciśnięty jako ostatni, abyś mógł odpowiednio zaktualizować interfejs. Możesz także przypisać różne obrazy lub tytuły dla różnych stanów sterowania, używam domyślnego i wybranego w tym przypadku.

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

Przede wszystkim tworzyć kontrolerów widzenia (które są UINavigationController podklasy w tym przypadku) i przypisać je do podklasy twoi UITabBarController „S jako własność viewControllers.

- (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 
} 

dodać metodę przetwarzania::

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

I wreszcie nadpisania -setSelectedViewController:

- (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; 
} 

Następny Grab już utworzone wcześniej i przypisać do nich działania w metodzie -viewDidLoad przyciski metoda:

- (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]; 
    } 
} 

Zakładam, że programujesz z włączonym ARC i masz klasę, która zarządza twoimi scenariuszami, ale to całkiem proste.

+0

To powinna być wybrana odpowiedź, ponieważ działa idealnie. Dzięki! –

+3

Co oznacza ta linia w viewDidLoad: '[self.view _tabbarView];' - wygląda jak literówka. – inorganik

0

dla iOS 9.0+ użycie UIStackView w kierunku poziomym i stworzyć XIb i nazwał ją CustomTabBarView

CustomTabBarView.Xibinsert uistackview in it

Set Stack view attributes like this

Tworzenie innego widoku CustomTabBarItem.

CustomTabBarItem.xib enter image description here

tworzyć CustomTabBarItem.swift plik do wdrożenia funkcjonalność 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) { 

} 

}

W TabBarViewController Wdrożenie ten kod

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 
} 
2

Poniższy kod działa doskonale w moim projekcie.

Użyłem swift3 wersji jak poniżej:

I dodaje plik MyTabBar.xib który zawiera UIView z 4 przyciskami. W pliku Xib Ustaw klasę UIView. class = "MyTabBar"
otrzymując 4 przyciski Tag 1,2,3,4 odpowiednio ..

i poniżej myTabBarController złożyć

kod myTabBarController.swift jak poniżej:

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() 
} 

}

W ten sposób można zaprojektować niestandardowy pasek zakładek zgodnie z potrzebami.

Dzięki

Powiązane problemy