2012-04-29 57 views
1

我已經制作了簡單的可可觸摸應用程序,但是我從未使用UINavigationControllers,任何建議都將不勝感激。在基於標籤欄的應用程序上使用UINavigationController將數組添加到UITableView

我想向UITableView添加一個存儲名稱列表的數組。 UITableView通過標籤欄上的選項卡通過UINavigation控制器進行訪問。

我有一個TabBarController.xib文件,其中包含標籤欄。 我也有一個保存UINavigationController的AtoZNavigationController.xib。 我有一個保存UITableView的AtoZTableController.xib文件。

這是我AppDelegate.h:

#import <UIKit/UIKit.h> 
@class AtoZNavigationController; 

@interface AppDelegate : UIResponder <UIApplicationDelegate> 

@property (strong, nonatomic) UIWindow *window; 
@property (strong, nonatomic) IBOutlet UITabBarController *rootController; 
@property (strong, nonatomic) IBOutlet AtoZNavigationController *navController; 

@end 

的AppDelegate.m

#import "AppDelegate.h" 
#import "AtoZNavigationController.h" 

@implementation AppDelegate 

@synthesize window = _window; 
@synthesize rootController; 
@synthesize navController; 

#pragma mark - 
#pragma mark Application lifecycle 

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:  (NSDictionary *)launchOptions 
{ 
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 
// Override point for customization after application launch. 

[[NSBundle mainBundle] loadNibNamed:@"TabBarController" owner:self options:nil]; 
    [self.window addSubview:rootController.view]; 
    self.window.backgroundColor = [UIColor whiteColor]; 
    [self.window makeKeyAndVisible]; 

return YES; 
} 
@end 

的AtoZNavigationController.h

#import <UIKit/UIKit.h> 

@interface AtoZNavigationController : UINavigationController 

@end 

的AtoZNavigationController.m

#import "AtoZNavigationController.h" 

@interface AtoZNavigationController() 

@end 

@implementation AtoZNavigationController 

-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 
{ 
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 
    if (self) { 
     // Custom initialization 
    } 
    return self; 
} 

-(void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view from its nib. 
} 

-(void)viewDidUnload 
{ 
    [super viewDidUnload]; 
    // Release any retained subviews of the main view. 
    // e.g. self.myOutlet = nil; 
} 

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{ 
    return (interfaceOrientation == UIInterfaceOrientationPortrait); 
} 

@end 

的AtoZTableController.h

#import <UIKit/UIKit.h> 

@interface AtoZTableController : UITableViewController <UITableViewDelegate,  UITableViewDataSource> 
{ 
    IBOutlet UITableView *AtoZTableView; 
    NSMutableArray *AtoZArray; 
} 

@property (nonatomic, retain) IBOutlet UITableView *AtoZTableView; 
@end 

的AtoZTableController.h

#import "AtoZTableController.h" 

@interface AtoZTableController() 

@end 

@implementation AtoZTableController 
@synthesize AtoZTableView; 

-(id)initWithStyle:(UITableViewStyle)style 
{ 
    self = [super initWithStyle:style]; 
    if (self) { 
     // Custom initialization 
    } 
    return self; 
} 

-(void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    self.title = NSLocalizedString(@"A to Z", @"An A to Z List of Stores"); 

    AtoZArray = [[NSMutableArray alloc] init]; 

    [AtoZArray addObject:@"Apple"]; 
    [AtoZArray addObject:@"Boots"]; 
    [AtoZArray addObject:@"Topman"]; 
} 

-(void)viewDidUnload 
{ 
    [super viewDidUnload]; 
    // Release any retained subviews of the main view. 
    // e.g. self.myOutlet = nil; 
} 

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{ 
    return (interfaceOrientation == UIInterfaceOrientationPortrait); 
} 

#pragma mark - Table view data source 

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
{ 
    // Return the number of sections. 
    return 0; 
} 

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
    // Return the number of rows in the section. 
    return [AtoZArray count]; 
} 

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *CellIdentifier = @"Cell"; 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

    // Configure the cell... 

    NSInteger row = [indexPath row]; 
    cell.textLabel.text = [AtoZArray objectAtIndex:row]; 
    return cell; 
} 
#pragma mark - Table view delegate 

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    // Navigation logic may go here. Create and push another view controller. 
    /* 
    <#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:@"<#Nib name#>" bundle:nil]; 
    // ... 
    // Pass the selected object to the new view controller. 
    [self.navigationController pushViewController:detailViewController animated:YES]; 
    */ 
} 
@end 

回答

2

在你AtoZTableController.h,你有問題。

問題出在你的'tableView:cellForRowAtIndexPath:'方法。 這裏是你擁有的一切:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *CellIdentifier = @"Cell"; 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

    // Configure the cell... 

    NSInteger row = [indexPath row]; 
    cell.textLabel.text = [AtoZArray objectAtIndex:row]; 
    return cell; 
} 

的問題是,你永遠不會處理從dequeueReusableCellWithIdentifier:CellIdentifiernil返回值。

嘗試了這一點:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *CellIdentifier = @"Cell"; 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

    // What happens if you don't get a cell to use? 
    // This is the way to create a new, default UITableViewCell 
    if (!cell) {    
     // You can look at the UITableViewCell class reference to see the 4 available styles 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; 
    } 

    // Configure the cell... 
    NSInteger row = [indexPath row]; 
    cell.textLabel.text = [AtoZArray objectAtIndex:row]; 
    return cell; 
} 

編輯/更新:

OK,所以這是一個有點難以確切地知道你的錯誤,所以我會成立/爲你描述一個典型的情況(或者我會怎麼做你的鞋子)。

如果您創建一個新的應用程序並在Xcode中選擇「選項卡式應用程序」模板,您會在應用程序委託中獲得以下方法(或多或少;我將它縮小一點,「固定」點表示):

注:我相信你有推新視圖控制器具有問題將低於現在...... 注完

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
    [self setWindow:[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]]; 
    // Override point for customization after application launch. 
    UIViewController *vc1 = [[FirstViewController alloc] initWithNibName:@"FirstVC" bundle:nil]; 
    // New line... 
    UINavigationController *navC = [[UINavigationController alloc] initWithRootViewController:vc1]; 
    UIViewController *vc2 = [[SecondViewController alloc] initWithNibName:@"SecondVC" bundle:nil]; 
    [[self setTabBarController:[[UITabBarController alloc] init]]; 
    // Change here, too... 
    [[self tabBarController] setViewControllers:[NSArray arrayWithObjects:navC, vc2, nil]]; 
    [[self window] setRootViewController:[self tabBarController]]; 
    [[self window] makeKeyAndVisible]; 
    return YES; 
} 

此方法設置了啓動您的應用程序所需的全部功能,其中2個UIViewControllers創建並設置爲UITabBarController中的選項卡1和選項卡2。

現在,您可以使FirstViewController和SecondViewController成爲您想要的任何東西。對於這個問題,我們假設你想改變FirstViewController來託管一個UITableView,當用戶在屏幕上選擇一行時,它將推送一個詳細的UIViewController。

要求 無論是 FirstViewController必須的UITableViewController的子類(這是什麼默認模板提供)OR必須添加一個UITableView到FirstViewController的觀點,並設置所有連接。

假設您將FirstViewController作爲標準的UIViewController子類繼承,並且您將在其視圖中添加一個UITableView。 (我可能將其更改爲一個UITableViewController子類,但可能是在這一點上比較混亂。)

首先,在FirstViewController.h,改變這種:

@interface MMFirstViewController : UIViewController 
@end 

這樣:

@interface MMFirstViewController : UIViewController <UITableViewDataSource, UITableViewDelegate> { 
    UITableView *TableView; 
} 
@property (strong, nonatomic) IBOutlet UITableView *TableView; 
@end 

接下來,在FirstViewController.m中,合成TableView屬性(@synthesize TableView)。 接下來,單擊Xco​​de中的FirstViewController.xib,將其加載到Interface Builder中(我假設您使用的是Xcode 4)。 現在,從控制面板拖動一個UITableView到你的UIViewController的視圖。 請在Interface Builder以下連接:

  1. 右鍵單擊File's Owner和財產的TableView連接到你掉在FirstViewController的視圖中的UITableView。
  2. 右鍵單擊的UITableView並連接BOTHdatasourcedelegate屬性File's Owner

現在,您發佈的代碼初始化和填充AtoZArray應該可以正常工作。不要忘記複製你以前擁有的3個UITableView方法,numberOfSectionsInTableView:,tableView:numberOfRowsInSection:tableView:cellForRowAtIndexPath:

這些步驟應該讓你工作,也應該讓你看看你的設置可能出錯了。請注意,爲了推入新的UIViewController,您仍然必須自己計算出tableView:didSelectRowAtIndexPath:

這裏是一個玩笑話,讓你開始:

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    // Navigation logic may go here. Create and push another view controller. 
    ThirdViewController *detailVC = [[ThirdViewController alloc] initWithNibName:@"ThirdViewController" bundle:nil]; 
    [[self navigationController] pushViewController:detailVC animated:YES]; 
} 
+0

感謝您的快速回復。我試過你的方法,但UITableView仍然顯示空白單元格。我認爲這可能是與.xib文件中的連接有關的問題。我試圖張貼一些圖像,但因爲我是一個新成員,我不能。我會盡力解釋我能做的最好的: – robbiecutting

+0

好吧,只要確保你已經在IB中設置了「數據源」和「委託」連接。 – mbm29414

+0

感謝您的快速回復。我試過你的方法,但UITableView仍然顯示空白單元格。我認爲這可能是與.xib文件中的連接有關的問題。我試圖張貼一些圖像,但因爲我是一個新成員,我不能。我需要鏈接所有3個.xib文件嗎? TabBarController.xib,AtoZNavigationController.xib和AtoZTableController?我試過一些變化,但我不確定代碼或鏈接是否有錯誤。應用程序構建O.K和UITableView的標題可以在AtoZTableController.m文件中修改。再次感謝您的建議。 – robbiecutting

1

我不得不創建navigationController的實例,並傳遞到子視圖我appDelegate.m與tabBarController一起。它可以稍後在我的UITableViewController中引用。

這是我添加的代碼:

navigationController = [[UINavigationController alloc] initWithRootViewController:_tabBarController]; 
[self.window addSubview:_tabBarController.view]; 
[self.window addSubview:navigationController.view]; 
[self.window makeKeyAndVisible]; 

哪裏navigationController僅僅是要麼的UITableViewController或的UIViewController的子類的實例,這取決於你想要什麼類型的屏幕顯示。

相關問題