0

UITableViewCell为 iPad 应用程序创建了一个子类。我需要动态生成文本字段,从用户那里获取输入,然后将该信息存储在一个数组中。我想询问对象,它将保存用户在我的视图控制器的 segue 之前写UITableViewCellUITextField.text任何内容(我在NSString调用 segue 时保存对象)。所以我有一组 UITableViewCells 我要求UITextField.text 对象。但是由于某种原因,UITableViewCell在创建我的子类时,我UITextField的不是。我可以打电话UITableViewSubclass,它已初始化,但UITableViewSubclass.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 控制器中,因为表视图不占据整个屏幕。当用户按下“确定”按钮时,会触发一个 segue,在这里我向这个 Table View Controller 询问包含UITableViewCells. 不幸的是,我似乎无法在文本字段中输入任何内容,因此 .text 始终为零。如果有人可以帮助我解决这个问题,将不胜感激!

4

2 回答 2

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 元素。

接下来,我想保留对单元格的引用,因为该单元格有一个文本框,当用户按下“完成”按钮时,我需要保存文本框上的内容。然而,测试揭示了我上面解释的重用问题。那么如何做到这一点呢?在我的表的视图控制器中,每当用户想要添加一个新的文本框(并按下按钮这样做)我有一个方法

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

这会在数组中添加一个新单元格 - 这很重要,因为我需要始终引用所有单元格。(它在索引 0 处添加单元格,因为我想将它插入到顶部)。然后,在 cellForRowAtIndexPath 方法中,我做了

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

这将返回相应的单元格。请记住,从我所读到的关于保持对表中每个单元格的引用的整个内容,这与 Apple 在使用 UITableView 时声明的最佳实践相反。然而,正如我之前所说,UITableView 旨在显示信息,而不是从用户输入中收集信息。所以这就是为什么我必须打破规则,如果你愿意的话,以达到预期的效果(我想要的)。我希望这可以帮助其他想要做同样事情的人;如果有更好的方法,请不要羞于告诉我。

编辑:哦,顺便说一句,当您将故事板中创建的单元格复制粘贴到它们自己的 .xib 文件时,请确保断开任何 IBOutlets 并将它们的类更改回 UITableViewCell。这样,当您连接您的 .xib 文件单元时,就不会有任何问题或冲突。

于 2013-03-25T07:55:33.823 回答
0

您可能会发现使用免费的 Sensible TableView 框架更容易做到这一点。该框架具有开箱即用的这些文本字段单元格,甚至可以从您的数组中自动创建它们。

于 2013-03-23T21:58:04.687 回答