2009-01-13 45 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) 
} 

} 
相關問題