2009-01-13 120 views
19

我在我的应用程序上使用了一个标签栏(UITabBarController),我希望自定义当您单击更多按钮时出现的表格的外观。 我已经摸索出了如何更改导航栏,是更大的屏幕上通过的UITabBarController的子类设置自定义选项卡栏上的更多菜单

self.moreNavigationController.navigationBar.barStyle 

的外观和我设法通过修改

改变表格的背景颜色
self.moreNavigationController.topViewController.view.backgroundColor 

,但我不能解决如何更改表格中出现的单元格中的字体颜色。 我希望我可以用

self.moreNavigationController.topViewController.view.visibleCells 

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

任何想法?

回答

19

只有在显示moreNavigationController后,才会填充visibleCells。

并且单元格是在运行时创建的,所以即使您更改了单元格的内容,它们在显示时也会被替换。

有一点要尝试的是替换moreNavigationController tableView的数据源,调用原始数据源的cellForRowAtIndexPath并在返回之前更改其内容。

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

UITableView *view = (UITableView *)self.tabBarController.moreNavigationController.topViewController.view; 
if ([[view subviews] count]) { 
    for (UITableViewCell *cell in [view visibleCells]) { 
    cell.backgroundColor = [UIColor redColor]; 
    } 
} 
+0

好的建议。我会尝试它 – Ian1971 2009-01-13 13:03:25

+0

它的工作原理。我是这个网站的新手,应该将我的实现作为单独的答案发布吗?什么是正确的协议? – Ian1971 2009-01-13 13:07:56

26

继Stephan提出的替换moreNavigationController的dataSource的建议之后,下面快速浏览了我实现的代码。

我创建了一个名为MoreTableViewDataSource的新类,它实现了UITableViewDataSource协议。多页实际用于构建表的控制器称为UIMoreListControllerModern,它实现了UITableViewDataSource协议所需的部分。我的实现看起来像这样。

-(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 I类重写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

我跟着伊恩的暗示ementation来自定义“更多”菜单,但我遇到了内存警告后保留自定义的问题。 didReceiveMemoryWarning似乎破坏了UITableView,并且当它重新生成时,它恢复旧数据源。这里是我的解决方案:

我更换viewDidLoad中的CustomTabBarController本:

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

正如你所看到的,我增加了一些特性,用于存储东西,我需要的。那些必须被添加到标题并合成。我还在头文件中将CustomTabBarController设置为一个UINavigationControllerDelegate。这里的委托功能我补充说:

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

这样,我要确保我的自定义数据源始终使用,因为我设置这种方式之前,为了显示UIMoreListController,它显示每次。

1
@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 
3

感谢未知。 按照他的解决方案,我将把他的代码放入Swift中。 只有你应该做的更多的是创建MoreTableViewCell类,只是它。您不必使用Storyboard。如果你想修改tableView,你可以在customizeMoreTableView方法中完成。

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

}