代码之家  ›  专栏  ›  技术社区  ›  Ian1971

自定义选项卡栏上的“更多”菜单

  •  20
  • Ian1971  · 技术社区  · 17 年前

    我正在我的应用程序上使用选项卡栏(UITabBarController),我希望自定义单击“更多”按钮时显示的表格的外观。 我已经研究出如何通过设置来改变更多屏幕上导航栏的外观

    self.moreNavigationController.navigationBar.barStyle
    

    self.moreNavigationController.topViewController.view.backgroundColor
    

    ,但我无法确定如何更改表格上显示的单元格中的字体颜色。 我希望我能用

    self.moreNavigationController.topViewController.view.visibleCells 
    

    但这似乎总是空的。我尝试在viewDidLoad、ViewWillDisplay和ViewDidDisplay中执行此操作,但没有成功。对象self.moreNavigationController.topViewController的类型为UIMoreListController,它似乎没有文档记录,我在界面中看不到任何明显的帮助。

    有什么想法吗?

    5 回复  |  直到 7 年前
        1
  •  26
  •   Community Mohan Dere    15 年前

    根据Stephan关于替换moreNavigationController的数据源的建议,下面是我实现的代码的快速概览。

    -(MoreTableViewDataSource *) initWithDataSource:(id<UITableViewDataSource>) dataSource
    {
        self = [super init];
        if (self)
        {
                self.originalDataSource = dataSource;
        }
    
        return self;
    }
    
    - (void)dealloc
    {
        self.originalDataSource = nil;
        [super dealloc];
    }
    
    - (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section
    {
        return [originalDataSource tableView:table numberOfRowsInSection:section];
    }
    
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        UITableViewCell *cell = [originalDataSource tableView:tableView cellForRowAtIndexPath:indexPath];
        cell.textColor = [UIColor whiteColor];
        return cell;
    }
    

    然后在CustomTabBarController类中,我覆盖viewDidLoad,如下所示:

    - (void)viewDidLoad {
    
        [super viewDidLoad];
    
        UINavigationController *moreController = self.moreNavigationController;
        moreController.navigationBar.barStyle = UIBarStyleBlackOpaque;
    
        if ([moreController.topViewController.view isKindOfClass:[UITableView class]])
        {
    
            UITableView *view = (UITableView *)moreController.topViewController.view;
            view.backgroundColor = [UIColor blackColor];
            moreTableViewDataSource = [[MoreTableViewDataSource alloc] initWithDataSource:view.dataSource];
            view.dataSource = moreTableViewDataSource;
    
        }
    }
    

    @interface MoreTableViewDataSource : NSObject <UITableViewDataSource>
    {
        id<UITableViewDataSource> originalDataSource;
    }
    
    @property (retain) id<UITableViewDataSource> originalDataSource;
    
    -(MoreTableViewDataSource *) initWithDataSource:(id<UITableViewDataSource>) dataSource;
    
    @end
    

    和

    #import "MoreTableViewDataSource.h"
    
    @interface CustomTabBarController : UITabBarController 
    {
        MoreTableViewDataSource *moreTableViewDataSource;
    }
    
        2
  •  21
  •   Stephan Burlot    17 年前

    而且这些单元格是在运行时创建的,因此即使您更改了单元格的内容,它们在显示时也会被替换。

    要尝试的一件事是替换moreNavigationController表视图的数据源,调用原始数据源的CellForRowatineXpath,并在返回它之前更改其内容。

    使用下面的代码,在显示moreNavigationController以对其进行初始化后,您将看到当您返回moreNavigationController时,单元格为红色,但立即返回白色背景。

    UITableView *view = (UITableView *)self.tabBarController.moreNavigationController.topViewController.view;
    if ([[view subviews] count]) {
      for (UITableViewCell *cell in [view visibleCells]) {
        cell.backgroundColor = [UIColor redColor];
      }
    }
    
        3
  •  4
  •   rudald    10 年前

    您应该做的只是创建MoreTableViewCell类并对其进行处理。你不必使用故事板。如果要修改tableView,可以在CustomizeMemoreTableView方法中进行。

    class TabBarMenuController: UITabBarController, UITableViewDelegate, UITableViewDataSource{
    
    var tabBarItems: [UIViewController] = []
    var areMessagesVisible: Bool = false
    
    var titleForTabBars: [String] = ["resources", "events", "training", "my profile", "news", "contacts"]
    var iconNames: [String] = ["film", "calendar", "classroom", "profile", "news", "Phone"]
    var controllersStoryboardId: [String] = ["resourcesNavController", "eventsNavController", "enablementNavController", "profileNavController", "newsNavController", "contactsNavController"]
    
    // to manage moreTableView
    var moreTableView: UITableView = UITableView()
    var currentTableViewDelegate: UITableViewDelegate?
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        self.customizeMoreTableView()
        //to REMOVE
        areMessagesVisible = true
    
        if !areMessagesVisible{
            self.titleForTabBars.removeAtIndex(4)
            self.controllersStoryboardId.removeAtIndex(4)
            self.iconNames.removeAtIndex(4)
        }
    
        for i in 0 ..< controllersStoryboardId.count{
            tabBarItems.append(UIStoryboard(name: "Main", bundle: NSBundle.mainBundle()).instantiateViewControllerWithIdentifier(controllersStoryboardId[i]) as? UINavigationController ?? UINavigationController())
        }
        self.moreNavigationController.navigationBar.tintColor = UIColor.blackColor()
    }
    
    override func viewWillAppear(animated: Bool) {
    
        for i in 0 ..< tabBarItems.count{
            tabBarItems[i].tabBarItem = UITabBarItem(title: titleForTabBars[i], image: UIImage(named: iconNames[i]), selectedImage: UIImage(named: iconNames[i]))
        }
        self.viewControllers = tabBarItems
    }
    
    func customizeMoreTableView(){
        moreTableView = self.moreNavigationController.topViewController!.view as? UITableView ?? UITableView()
        currentTableViewDelegate = moreTableView.delegate;
        moreTableView.delegate = self
        moreTableView.dataSource = self;
        moreTableView.registerClass(MoreTableViewCell.self, forCellReuseIdentifier: "MoreTableViewCell")
    
    }
    
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    
        let moreCell  = tableView.dequeueReusableCellWithIdentifier("MoreTableViewCell", forIndexPath: indexPath) as? MoreTableViewCell ?? MoreTableViewCell()
    
        moreCell.textLabel?.text = titleForTabBars[indexPath.row + 4]
        moreCell.imageView?.image = UIImage(named: iconNames[indexPath.row + 4])
    
        /*let testLabel: UILabel = UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 40))
        testLabel.backgroundColor = UIColor.yellowColor()
        moreCell.addSubview(testLabel)
        */
        return moreCell
    }
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return titleForTabBars.count - 4
    }
    
    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        currentTableViewDelegate?.tableView!(tableView, didSelectRowAtIndexPath: indexPath)
    }
    
     }
    
        4
  •  2
  •   wickning1    15 年前

    我按照Ian的实现自定义了“更多”菜单,但在内存警告后保留自定义设置时遇到了问题。didReceiveMemoryWarning似乎破坏了UITableView,当它重新生成时,它会将其旧数据源取回。以下是我的解决方案:

    - (void)viewDidLoad {
        [super viewDidLoad];
        UINavigationController* moreController = self.moreNavigationController;
        if ([moreController.topViewController.view isKindOfClass:[UITableView class]]) {
            moreController.delegate = self;
            self.moreControllerClass = [moreController.topViewController class];
            UITableView* view = (UITableView*) moreController.topViewController.view;
            self.newDataSource = [[[MoreDataSource alloc] initWithDataSource:view.dataSource] autorelease];
        }
    }
    

    - (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
        if ([viewController isKindOfClass:self.moreControllerClass]) {
            UIView* view = self.moreNavigationController.topViewController.view;
            if ([view isKindOfClass:[UITableView class]]) {
                UITableView* tview = (UITableView*) view;
                tview.dataSource = self.newDataSource;
                tview.rowHeight = 81.0;
            }
        }
    }
    

        5
  •  1
  •   Cyklet    10 年前
    @interface TabBarViewController () <UITableViewDelegate,UITableViewDataSource>
    
    @property (nonatomic,strong) UITableView* tabBarTableView;
    @property (nonatomic,weak) id <UITableViewDelegate> currentTableViewDelegate;
    
    @end
    
    @implementation TabBarViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        [self costumizeMoreTableView];
    
    }
    
    -(void)costumizeMoreTableView{
        _tabBarTableView = (UITableView *)self.moreNavigationController.topViewController.view;
        _currentTableViewDelegate = _tabBarTableView.delegate;
        _tabBarTableView.delegate = self;
        _tabBarTableView.dataSource = self;
        [_tabBarTableView registerNib:[UINib nibWithNibName:@"MoreTabBarTableViewCell" bundle:nil] forCellReuseIdentifier:@"MoreTabBarTableViewCell"];
    
    }
    
    -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
        return 120;
    }
    
    -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
        return 2;
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
        MoreTabBarTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MoreTabBarTableViewCell" forIndexPath:indexPath];
        [cell setMoreTableValues];
        return cell;
    }
    
    -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath: (NSIndexPath *)indexPath{
          [_currentTableViewDelegate tableView:tableView didSelectRowAtIndexPath:indexPath];
     }
    
     @end
    
        6
  •  1
  •   TvNuland    6 年前

    extension MyTabBarController: UITabBarControllerDelegate {
        // handle a select of the More tab
        func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
            // style all the tab bar windows and the More tab bar tableview
            if viewController == moreNavigationController,
                let moreTableView = moreNavigationController.topViewController?.view as? UITableView {
                view.tintColor = .systemOrange
                moreNavigationController.navigationBar.tintColor = .systemOrange
                moreTableView.tintColor = .systemOrange
                moreTableView.backgroundColor = UIColor(named: "Your Color")
                moreTableView.visibleCells.forEach {
                    $0.backgroundColor = UIColor(named: "Your Color")
                }
            }
        }
    }
    
    推荐文章