2012-05-27 47 views
0

開始探索iOS sdk第11章「iPad注意事項」,「創建你自己的Popover」段落,我嘗試它我自己,但只是給錯誤輸出「終止應用程序由於未捕獲異常'NSInternalInconsistencyException',原因:'UITableView dataSource必須從tableView返回一個單元格:cellForRowAtIndexPath:'「 代碼如下:(因爲我首先在stackoverflow網站上提出問題,而我的英文很差,所以只是原諒我的錯誤表達) 1.PrLanguageListController.hpopovercontroller tableview controller cell null

#import <UIKit/UIKit.h> 
@class PrDetailViewController; 
@interface PrLanguageListController : UITableViewController 
@property (weak, nonatomic) PrDetailViewController *detailViewController; 
@property (strong, nonatomic) NSArray *languageNames; 
@property (strong, nonatomic) NSArray *languageCodes; 
@end 

2.PrLanguageListContrller.m

#import "PrLanguageListController.h" 
#import "PrDetailViewController.h" 
@interface PrLanguageListController() 
@end 

@implementation PrLanguageListController 
@synthesize detailViewController; 
@synthesize languageCodes; 
@synthesize languageNames; 
- (id)initWithStyle:(UITableViewStyle)style 
{ 
    self = [super initWithStyle:style]; 
    if (self) { 
     // Custom initialization 
    } 
    return self; 
} 
- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    self.languageNames = [NSArray arrayWithObjects:@"English", @"French", 
          @"German", @"Spanish", nil]; 
    self.languageCodes = [NSArray arrayWithObjects:@"en", @"fr", @"de", @"es", nil]; 
    self.clearsSelectionOnViewWillAppear = NO; 
    self.contentSizeForViewInPopover = CGSizeMake(320.0, 
                [self.languageCodes count] * 44.0); 
} 

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

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

#pragma mark - Table view data source 
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
{ 
    // Return the number of sections. 
    return 1; 
} 

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

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *CellIdentifier = @"Cell"; 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    // Configure the cell... 
    cell.textLabel.text = [languageNames objectAtIndex:[indexPath row]]; 
    return cell; 
} 
#pragma mark - Table view delegate 
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    detailViewController.languageString = [self.languageCodes objectAtIndex: 
             [indexPath row]]; 
} 
@end 

3.PrDetailViewController.h

#import <UIKit/UIKit.h> 
@interface PrDetailViewController : UIViewController <UISplitViewControllerDelegate> 
@property (strong, nonatomic) id detailItem; 
@property (strong, nonatomic) IBOutlet UILabel *detailDescriptionLabel; 
@property (weak, nonatomic) IBOutlet UIWebView *webView; 
@property (strong, nonatomic) UIBarButtonItem *languageButton; 
@property (strong, nonatomic) UIPopoverController *languagePopoverController; 
@property (copy, nonatomic) NSString *languageString; 
- (IBAction)touchLanguageButton; 
@end 

4.PrDetailViewController.m

#import "PrDetailViewController.h" 
#import "PrLanguageListController.h" 
@interface PrDetailViewController() 
@property (strong, nonatomic) UIPopoverController *masterPopoverController; 
- (void)configureView; 
@end 
@implementation PrDetailViewController 
@synthesize detailItem = _detailItem; 
@synthesize detailDescriptionLabel = _detailDescriptionLabel; 
@synthesize masterPopoverController = _masterPopoverController; 
@synthesize webView; 
@synthesize languageButton; 
@synthesize languagePopoverController; 
@synthesize languageString; 
#pragma mark - Managing the detail item 
//rewrite url for different languages.eg.www.wekipak.com/us--ch...etc 
static NSString * modifyUrlForLanguage(NSString *url, NSString *lang) { 
    if (!lang) { 
     return url; 
    } 
// We're relying on a particular Wikipedia URL format here. This 
// is a bit fragile! 
NSRange languageCodeRange = NSMakeRange(7, 2); 
if ([[url substringWithRange:languageCodeRange] isEqualToString:lang]) { 
    return url; 
    } else { 
     NSString *newUrl = [url stringByReplacingCharactersInRange:languageCodeRange 
                withString:lang]; 
     return newUrl; 
    } 
} 
- (void)setDetailItem:(id)newDetailItem 
{ 
    if (_detailItem != newDetailItem) { 
     //_detailItem = newDetailItem; 
     _detailItem = modifyUrlForLanguage(newDetailItem, languageString); 
     // Update the view. 
     [self configureView]; 
    } 
if (self.masterPopoverController != nil) { 
    [self.masterPopoverController dismissPopoverAnimated:YES]; 
    }   
} 
- (void)configureView 
{ 
    // Update the user interface for the detail item. 
    NSURL *url = [NSURL URLWithString:self.detailItem]; 
    NSURLRequest *request = [NSURLRequest requestWithURL:url]; 
    [self.webView loadRequest:request]; 
    if (self.detailItem) { 
     self.detailDescriptionLabel.text = [self.detailItem description]; 
    } 
} 
- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
// Do any additional setup after loading the view, typically from a nib. 
    self.languageButton = [[UIBarButtonItem alloc] init]; 
    languageButton.title = @"Choose Language"; 
    languageButton.target = self; 
    languageButton.action = @selector(touchLanguageButton); 
    self.navigationItem.rightBarButtonItem = self.languageButton; 
    [self configureView]; 
} 

- (void)viewDidUnload 
{ 
    [super viewDidUnload]; 
    // Release any retained subviews of the main view. 
    self.detailDescriptionLabel = nil; 
    self.webView = nil; 
    self.languageButton = nil; 
    self.languagePopoverController = nil; 
} 
- (void)setLanguageString:(NSString *)newString { 
    if (![newString isEqualToString:languageString]) { 
     languageString = [newString copy]; 
     self.detailItem = modifyUrlForLanguage(_detailItem, languageString); 
    } 
    if (languagePopoverController != nil) { 
     [languagePopoverController dismissPopoverAnimated:YES]; 
     self.languagePopoverController = nil; 
    } 
} 
- (IBAction)touchLanguageButton { 
    if (self.languagePopoverController == nil) { 
    PrLanguageListController *languageListController = 
    [[PrLanguageListController alloc] init]; 
    languageListController.detailViewController = self; 
    UIPopoverController *poc = [[UIPopoverController alloc] 
           initWithContentViewController:languageListController]; 
    [poc presentPopoverFromBarButtonItem:languageButton 
       permittedArrowDirections:UIPopoverArrowDirectionAny 
           animated:YES]; 
    self.languagePopoverController = poc; 
    } else { 
    if (languagePopoverController != nil) { 
     [languagePopoverController dismissPopoverAnimated:YES]; 
     self.languagePopoverController = nil; 
     } 
    } 
} 
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{ 
    return YES; 
} 
#pragma mark - Split view 
- (void)splitViewController:(UISplitViewController *)splitController willHideViewController:(UIViewController *)viewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController:(UIPopoverController *)popoverController 
{ 
    barButtonItem.title = NSLocalizedString(@"Presidents", @"Presidents"); 
    //barButtonItem.title = NSLocalizedString(@"Master", @"Master"); 
    [self.navigationItem setLeftBarButtonItem:barButtonItem animated:YES]; 
    self.masterPopoverController = popoverController; 
} 
- (void)splitViewController:(UISplitViewController *)splitController willShowViewController:(UIViewController *)viewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem 
{ 
    // Called when the view is shown again in the split view, invalidating the button  and popover controller. 
[self.navigationItem setLeftBarButtonItem:nil animated:YES]; 
self.masterPopoverController = nil; 
} 
@end 

時選擇語言水龍頭按鈕將其向下運行的變化,並給出終端異常... 輸出: 2012-05-27 19:20:37.803總裁[4864:f803] *斷言失敗 - [UITableView _createPreparedCellForGlobalRow:withIndexPath:],/SourceCache/UIKit_Sim/UIKit-1914.84/UITableView.m:6061 2012-05-27 19:20:37.804總裁[4864:f803] 終止應用到期未捕獲的異常 'NSInternalInconsistencyException',理由是: 'UITableView的數據源必須的tableView返回細胞:的cellForRowAtIndexPath:' * *第一擲調用堆棧: (0x13ce022 0x155fcd6 0x1376a48 0x9af2cb 0xb2d28 0xb33ce 0x9ecbd 0xad6f1 0x56d21 0x13cfe42 0x1d86679 0x1d90579 0x1d90674 0x50967 0x4b84e9 0x4b9548 0x3ee9 0x13cfe99 0x1b14e 0x259a0e 0x13cfe99 0x1b14e 0x1b0e6 0xc1ade 0xc1fa7 0xc1266 0x403c0 0x405e6 0x26dc4 0x1a634 0x12b8ef5 0x13a2195 0x1306ff2 0x13058da 0x1304d84 0x1304c9b 0x12b77d8 0x12b788a 0x18626 0x23dd 0x2345爲0x1) TERMIN吃了叫拋出例外(lldb)

我怎麼能解決這個問題?感恩

+0

你能減少你的問題中的代碼量?錯誤應該在Xcode中突出顯示,所以您可以向錯誤中顯示代碼,如有必要,我們可以要求更多。 – 2012-05-27 18:40:12

回答

1

您需要在PrLanguageListContrller.m添加細胞的分配/初始化

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

添加此

**if (cell == nil) cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];** 

...

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