0

UITableViewCelliPadアプリのサブクラスを作成しました。テキストフィールドを動的に生成し、ユーザーから入力を受け取り、その情報を配列に格納する必要があります。私は、View Controllerのセグエの前にユーザーが書いたものをすべて保持するオブジェクトを要求することを考えました(セグエが呼び出されたときにオブジェクトを保存していUITableViewCellます)。だから私は.textオブジェクトを要求するUITableViewCellsの配列を持っています。しかし、何らかの理由で、私のサブクラスが作成されている間、私はそうではありません。呼び出すことができ、初期化されていますが、nilです。UITextField.textNSStringUITextFieldUITableViewCellUITextFieldUITableViewSubclassUITableViewSubclass.UITextField

これが私のUITableViewCellサブクラスヘッダーです(はい、UITextFieldストーリーボードで接続されています):

#import <UIKit/UIKit.h>

@interface ConditionCell : UITableViewCell 

@property (strong, nonatomic) IBOutlet UITextField *condition;

@end

これが私の実装ファイルです:

#import "ConditionCell.h"

@implementation ConditionCell
@synthesize condition;

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        // Initialization code
        self.condition = (UITextField *)[self viewWithTag:10];
    }
    return self;
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    [super setSelected:selected animated:animated];

    // Configure the view for the selected state
}

@end

これは、セルを含むテーブルを処理するテーブルビューコントローラーです。

.hファイル:

#import <UIKit/UIKit.h>
#import "ConditionCell.h"

@interface ConditionsTableViewController : UITableViewController

@property (strong, nonatomic) NSMutableArray *conditionCellArray;

- (void)addNewConditionCell;

@end

.mファイル:

#import "ConditionsTableViewController.h"

@interface ConditionsTableViewController ()

@end

@implementation ConditionsTableViewController

@synthesize conditionCellArray = _conditionCellArray;


- (NSMutableArray *)conditionCellArray
{
    if (_conditionCellArray == nil) {
        // Create the array object
        _conditionCellArray = [[NSMutableArray alloc] init];
    }

    return _conditionCellArray;
}

- (void)addNewConditionCell
{
    ConditionCell *condCell = [[ConditionCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"conditionCell"];

    [self.conditionCellArray addObject:condCell];


    [self.tableView beginUpdates];

    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:self.conditionCellArray.count-1 inSection:0];
    [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationTop];

    [self.tableView endUpdates];
    [self.tableView reloadData];
}

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

- (void)viewDidLoad
{
    [super viewDidLoad];

    // 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)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#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.conditionCellArray.count;
}

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

    if (cell == nil) {
        cell = [[ConditionCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }
    // Configure the cell...
    //cell.condition = (UITextField *)[cell viewWithTag:1];

    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;
}
*/

#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

テーブルビューが画面全体を占めるわけではないため、このテーブルビューコントローラーはUIViewコントローラー内にあります。ユーザーが「ok」ボタンを押すと、トリガーされるセグエがあります。ここで、このTable View Controllerに、を含む配列を要求UITableViewCellsします。次に、foreachを実行して.textプロパティを取得します。残念ながら、テキストフィールドに入力したものを取得できないようです。そのため、.textは常にnilです。誰かがこの問題で私を助けることができればそれは大いにありがたいです!

4

2 に答える 2

0

無料の Sensible TableView フレームワークを使用すると、これがはるかに簡単になる場合があります。フレームワークには、すぐに使用できるこれらのテキスト フィールド セルがあり、配列から自動的に作成することもできます。

于 2013-03-23T21:58:04.687 に答える
0

ここでやりたいことをうまくやるより良い方法を見つけました。iOS の UITableView の動作は、私がやりたかったこととはまったく異なることがわかりました。UITableView は、ストーリーボードを見て、セルの識別子を指定することで機能し、それらを作成し、cellForRowAtIndexPath メソッド内でそれらのプロパティを設定できるようにします。ただし、セルがオフスクリーンになると、それ自体が別のオブジェクトとして保持されません。それは再利用されます。つまり、テーブル ビューをスクロールすると、一方の端に表示されなくなったセルが、もう一方の端に新しい情報とともに再び表示されるように考えることができます。これが重要です - UITableView はあなたにセルの情報を提供してもらいたいのです。私がやりたかったUITableViewCellに直接情報を入力するために作られたものではありません。

だから私がやったのは、自分のセルをコピーして独自の .xib ファイルに貼り付け、サブクラスの initWithStyle:reuseIdentifier メソッドで次のことを行うことでした。

NSArray *nibArray = [[NSBundle mainBundle] loadNibNamed:@"ConditionCell" owner:self options:nil];
        self = [nibArray objectAtIndex:0];

これにより、必要なスタイル - セットアップ - UI 要素でセルが作成されます。

次に、セルへの参照を保持したいと思います。そのセルにはテキストボックスがあり、ユーザーが「完了」ボタンを押したときにテキストボックスの内容を保存する必要があるためです。しかし、テストの結果、上で説明した再利用の問題が明らかになりました。では、これを行う方法は?私のテーブルのView Controllerでは、ユーザーが新しいテキストボックスを追加したい(そしてボタンを押してそうする)ときはいつでも、私はそれを行うメソッドを持っています

[self.conditionCellArray insertObject:[[ConditionCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"conditionCell"] atIndex:0];

これにより、配列に新しいセルが追加されます。常にすべてのセルを参照する必要があるため、これは重要です。(一番上に挿入したいので、インデックス0にセルを追加しています)。次に、cellForRowAtIndexPath メソッドで、

return [self.conditionCellArray objectAtIndex:indexPath.row];

対応するセルを返します。テーブル内のすべてのセルへの参照を保持することについて、このすべてを読んだことから、UITableViewを使用するときにAppleが述べたベストプラクティスに反していることに注意してください。ただし、前に述べたように、UITableView は情報を表示するためのものであり、ユーザー入力から情報を収集するためのものではありません。これが、望ましい効果 (私が望んでいた) を達成するために、ルールを破らなければならなかった理由です。これが同じことをしようとしている他の人に役立つことを願っています。もっと良い方法があれば、恥ずかしがらずに教えてください。

EDIT:ところで、ストーリーボードで作成されたセルをコピーして独自の.xibファイルに貼り付けるときは、IBOutletsをすべて切断し、クラスをUITableViewCellに戻してください。そうすれば、.xib ファイル セルを接続するときに問題や競合が発生することはありません。

于 2013-03-25T07:55:33.823 に答える