2

テーブル ビューを iPhone で動作させるのに苦労しています。奇妙なことに、私の iOS シミュレーターではまったく問題なく動作しているように見えます (つまり、配列にエントリを追加すると、そのエントリがテーブル ビューに表示されます)。ただし、iOS デバイスを使用しているときにエントリを追加しようとすると、コードが行で途切れますdequeueReusableCellWithIdentifier:。大文字と小文字の不一致、名前の不一致をチェックprepareForReuseし、カスタム UITableViewCell サブクラスで再実装し、IBOutlets v. タグを使用して UITableViewCell サブクラスでフィールドを定義しようとしました。

この質問は、私の以前の質問: UITableView のセルが読み込まれない場合のデバッグ戦略と接線方向に関連していますか?

プログラミングの難しい部分は、どの質問をするべきかを常に知っていることです。そのため、間違った質問をしていることが判明した場合は申し訳ありません。

更新 6: 問題は iOS 5 の UITableViewCell のカスタム レイアウトです

UITableViewCell と UITableViewCell のサブクラスをカスタム レイアウトで使用してテストしました。スタイル UITableViewCellStyleDefault で UITableViewCell のサブクラスを使用すると、iOS 5 と iOS 6 の両方の iPhone シミュレーターで機能しますただし、カスタム スタイルで一般的な UITableViewCell を使用すると、iOS 5 ではクラッシュしますが、iOS 6 ではクラッシュしません。興味深いことに、UITableViewCell のドキュメントにカスタム UITableViewCellStyle の宣言がありません...

更新 5: iOS 5 v. 6 + カスタム UITableViewCell サブクラス?

こんにちは: 今日も引き続きテストを行っていますが、iOS 5 と 6 でのカスタム UITableViewCell サブクラスの処理方法に問題があるようです。まだ解決策はありません:(

更新 4: iOS 5 対 iOS 6?

だから私が気づいたのは、これが iOS 5 と iOS 6 の問題であるように思われるということだけです。ラインを使用して iOS 6 でテストするとGlassboxCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]、以下のコードが機能します。ただし、その行もGlassboxCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]iOS 5 では動作しません。何かアイデアはありますか? 識別子をprotocell.

更新 3: GitHub を使用するようになりました。

関連するリポジトリは次のとおりです: https://github.com/kenmhaggerty/Glassbox

更新 2: その他の観察

どこかで役立つかもしれないという回答を読んだので追加しまし@synthesize tableView = _tableViewたが、iOSシミュレーターで実行している場合でも、テーブルビューにデータが読み込まれなくなったことに気付きました。そのコード行をコメントアウトすると、コードは上記で説明した方法に戻ります。iOS シミュレーターでは問題dequeueReusableCellWithIdentifier:なく動作しますが、指定されたエラーなしでThread 1: breakpoint 1.1.

更新 1: 関連コード

GlassboxTableViewController.h

//
//  GlassboxTableViewController.h
//  Glassbox
//
//  Created by Ken M. Haggerty on 10/22/12.
//  Copyright (c) 2012 Ken M. Haggerty. All rights reserved.
//

#pragma mark - // NOTES (Public) //

#pragma mark - // IMPORTS (Public) //

#import <UIKit/UIKit.h>

#pragma mark - // PROTOCOLS //

//@protocol GlassboxTableViewDatasource <NSObject>
//@property (nonatomic, weak) NSMutableArray *arrayOfPlayers;
//@end

#pragma mark - // DEFINITIONS (Public) //

@interface GlassboxTableViewController : UITableViewController
@property (nonatomic, strong) NSMutableArray *arrayOfPlayers;
- (IBAction)addPlayer:(UIBarButtonItem *)sender;
//@property (nonatomic, strong) id <GlassboxTableViewDatasource> datasource;
@end

GlassboxTableViewController.m

//
//  GlassboxTableViewController.m
//  Glassbox
//
//  Created by Ken M. Haggerty on 10/22/12.
//  Copyright (c) 2012 Ken M. Haggerty. All rights reserved.
//

#pragma mark - // NOTES (Private) //

#pragma mark - // IMPORTS (Private) //

#import "GlassboxTableViewController.h"
#import "GlassboxCell.h"
#import "Player.h"
#import <MobileCoreServices/MobileCoreServices.h>

#pragma mark - // DEFINITIONS (Private) //

#define SIDEBAR_WIDTH_PERCENT 0.75

@interface GlassboxTableViewController () <UITableViewDataSource, UITableViewDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate>
//@property (nonatomic, weak) IBOutlet UITableView *tableView;
- (void)setup;
@end

@implementation GlassboxTableViewController

#pragma mark - // SETTERS AND GETTERS //

@synthesize arrayOfPlayers = _arrayOfPlayers;
@synthesize tableView = _tableView;
//@synthesize datasource = _datasource;

- (void)setArrayOfPlayers:(NSMutableArray *)arrayOfPlayers
{
    _arrayOfPlayers = arrayOfPlayers;
}

- (NSMutableArray *)arrayOfPlayers
{
    if (!_arrayOfPlayers) _arrayOfPlayers = [[NSMutableArray alloc] init];
//    [_arrayOfPlayers addObject:[[Player alloc] initWithUsername:@"Ken H.:"]];
    return _arrayOfPlayers;
}

#pragma mark - // INITS AND LOADS //

- (void)setup
{
    self.tableView.dataSource = self;
    self.tableView.delegate = self;
}

- (id)initWithStyle:(UITableViewStyle)style
{
    NSLog(@"[initWithStyle]");
    self = [super initWithStyle:style];
    if (self) {
        [self setup];
    }
    return self;
}

- (void)viewDidLoad
{
    NSLog(@"[viewDidLoad]");
    [super viewDidLoad];
    [self setup];

    // Uncomment the following line to preserve selection between presentations.
    // self.clearsSelectionOnViewWillAppear = NO;

    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem;
}

//- (void)viewDidAppear:(BOOL)animated
//{
//    [super viewDidAppear:animated];
//    [self.view setFrame:CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, self.view.frame.size.width*SIDEBAR_WIDTH_PERCENT, self.view.frame.size.height)];
//}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - // PUBLIC FUNCTIONS //

- (IBAction)addPlayer:(UIBarButtonItem *)sender
{
    [self alertAddPlayer];
}

#pragma mark - // PRIVATE FUNCTIONS //

- (void)alertAddPlayer
{
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Add New Player" message:@"Please type player name:" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK",nil];
    alert.alertViewStyle = UIAlertViewStylePlainTextInput;
    alert.tag = 1;
    [alert show];
}

- (void)alertInvalidPlayer
{
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Invalid Name" message:@"Please type another name:" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK",nil];
    alert.alertViewStyle = UIAlertViewStylePlainTextInput;
    alert.tag = 1;
    [alert show];
}

- (void)alertAddPhoto
{
    NSLog(@"[TEST] alertAddPhoto");
    if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
    {
        NSArray *mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];
        if ([mediaTypes containsObject:(NSString *)kUTTypeImage])
        {
            UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
            imagePickerController.delegate = self;
            imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
            imagePickerController.allowsEditing = YES;
//            imagePickerController.cameraDevice = UIImagePickerControllerCameraDeviceFront;
//            imagePickerController.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;
            imagePickerController.mediaTypes = [NSArray arrayWithObject:(NSString *)kUTTypeImage];
//            [self presentViewController:imagePickerController animated:YES completion:nil];
        imagePickerController.cameraDevice = UIImagePickerControllerCameraDeviceFront;
            [self presentModalViewController:imagePickerController animated:YES];
            return;
        }
    }
    NSLog(@"[TEST] No camera available");
    [self.tableView reloadData];
}

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    UIImage *image = [info objectForKey:UIImagePickerControllerEditedImage];
    if (!image) image = [info objectForKey:UIImagePickerControllerOriginalImage];
    if (image)
    {
        [[self.arrayOfPlayers lastObject] setPhoto:[[UIImageView alloc] initWithImage:image]];
    }
    [self dismissImagePicker];
}

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
    [self dismissImagePicker];
}

- (void)dismissImagePicker
{
//    [self dismissViewControllerAnimated:YES completion:^{
//        [self.tableView reloadData];
//    }];
    [self dismissModalViewControllerAnimated:YES];
    [self.tableView reloadData];
}

- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
    if (buttonIndex == 0) NSLog(@"Cancel tapped");
    else
    {
        if (alertView.tag == 1)
        {
            if (buttonIndex == 1)
            {
                if ([[[alertView textFieldAtIndex:0] text] length] != 0)
                {
                    [self.arrayOfPlayers addObject:[[Player alloc] initWithUsername:[[alertView textFieldAtIndex:0] text]]];
                    [self alertAddPhoto];
                }
                else [self alertInvalidPlayer];
            }
        }
    }
}

#pragma mark - // PRIVATE FUNCTIONS (Miscellaneous) //

// TableView data source //

//- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
//{
//#warning Potentially incomplete method implementation.
//    // Return the number of sections.
//    return 0;
//}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
//    return self.datasource.arrayOfPlayers.count;
    return self.arrayOfPlayers.count;
}

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

    cell.name.text = [[self.arrayOfPlayers objectAtIndex:indexPath.row] username];
    cell.action.text = @"LOADED SUCCESSFULLY";
    cell.time.text = @"Just now";
    cell.photo = [[self.arrayOfPlayers objectAtIndex:indexPath.row] photo];

//    [((UILabel *)[cell viewWithTag:1]) setText:[[self.arrayOfPlayers objectAtIndex:indexPath.row] username]];
//    [((UILabel *)[cell viewWithTag:2]) setText:@"has been added."];
//    [((UILabel *)[cell viewWithTag:3]) setText:@"Just now"];
//    [((UIImageView *)[cell viewWithTag:4]) setImage:[[[self.arrayOfPlayers objectAtIndex:indexPath.row] photo] image]];

    [cell.contentView setFrame:CGRectMake(cell.contentView.frame.origin.x, cell.contentView.frame.origin.y, cell.contentView.frame.size.width, 120)];

    return cell;
}

/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Return NO if you do not want the specified item to be editable.
    return YES;
}
*/

/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        // Delete the row from the data source
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
    }   
    else if (editingStyle == UITableViewCellEditingStyleInsert) {
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
    }   
}
*/

/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/

/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Return NO if you do not want the item to be re-orderable.
    return YES;
}
*/

// TableView 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

もっと投稿する必要があるかどうか教えてください。

4

4 に答える 4

2

(あなたの github プロジェクトはコンパイルされない (Player.h/Player.m が見つからない) ため、問題を再現することは困難です。)

しかし、MainStoryboard ファイルで「Use Autolayout」がオンになっていることに気付きました。Autolayout は iOS 6 以降でのみ機能し、iOS 5 では機能しません!

于 2012-11-09T19:52:10.703 に答える
0

わかりました、あなたの代わりにこの関数を使用してみてください。

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

    if (cell == nil)
    {
        cell = [[GlassboxCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

    }

    cell.name.text = [[self.arrayOfPlayers objectAtIndex:indexPath.row] username];
    cell.action.text = @"LOADED SUCCESSFULLY";
    cell.time.text = @"Just now";
    cell.photo = [[self.arrayOfPlayers objectAtIndex:indexPath.row] photo];

    [cell.contentView setFrame:CGRectMake(cell.contentView.frame.origin.x, cell.contentView.frame.origin.y, cell.contentView.frame.size.width, 120)];

    return cell;
}
于 2012-10-25T11:14:24.867 に答える
0

コードを投稿してください。xib ファイルをそのままにして、もう一度やり直すことをお勧めしますuitableviewcell。使用する細胞は1種類ですか?または、いくつかの異なるスタイルを使用していますか?

===== 答え =====

セルを作成GlassboxCell *cellして dequeueReusableCellWIthIdentifier を使用する場合、セルが割り当てられているかどうかを確認する必要があります。

// use dequeueReusableCellWithIdentifier for init cell
if (cell == nil){
    cell = [[[GlassboxCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:yourIdentifier]] autorelease];
}
//rest your code for init properties for cell
于 2012-10-25T00:45:07.207 に答える
0

私は問題を見つけたと思います...少なくとも私のプロジェクトでは機能します。

古いバージョンの Xcode (たとえば 4) で UITableViewController クラスを作成すると、 cellForRowAtIndexPath の生成コードは次のようになります。

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

しかし、Xcode 4.5.2 (私のもの) で UITableViewController を作成すると、 cellForRowAtIndexPath の生成コードは次のようになります。

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

したがって、私の場合、「forIndexPath:indexPath」部分を削除するだけでうまくいきました!

(これは私の最初の回答ですので、私が何かを台無しにした場合は優しくしてください)

于 2012-11-14T23:13:31.563 に答える