0

在开始的 iOS 5 开发中探索 iOS sdk 第 11 章“iPad 注意事项”,“创建自己的弹出框”段落,我自己尝试,但只是给出错误输出“由于未捕获的异常而终止应用程序 'NSInternalInconsistencyException ',原因: ' UITableView dataSource 必须从 tableView 返回一个单元格:cellForRowAtIndexPath: '" 代码如下:(因为我首先在stackoverflow网站上提问,而且我的英语很差,所以请原谅我在表达上的错误) 1.PrLanguageListController.h

#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.PrLanguageListContrler.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 _CreatePreparedCellfellBlobalrow:hydindexpath:] , /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)终止叫做抛出异常(LLDB)

我该如何解决这个问题?感恩节...

4

1 回答 1

1

您需要在 PrLanguageListContrller.m 中添加单元格的 alloc/init

- (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;
}
于 2012-08-12T13:01:29.607 回答