简体   繁体   English

为什么我不能从UITableViewCell的子类初始化UITextField?

[英]Why can't I initialize a UITextField from a subclass of UITableViewCell?

I've created a subclass of UITableViewCell for an iPad app. 我为iPad应用程序创建了UITableViewCell的子类。 I need to dynamically generate text fields, take input from the user, and then store that information in an array. 我需要动态生成文本字段,从用户那里获取输入,然后将该信息存储在数组中。 I thought of asking the UITableViewCell for the UITextField.text object, which would hold whatever the user wrote before my View Controller's segue (I'm saving the NSString objects upon the segue being called). 我想到要向UITableViewCell请求UITextField.text对象,该对象将保存用户在View Controller进行Segue之前写的所有内容(在调用Segue时保存NSString对象)。 So I've got an array of UITableViewCells which I ask for the UITextField .text object. 因此,我有一个UITableViewCells数组,我需要UITextField .text对象。 But for some reason while my UITableViewCell subclass is being created, my UITextField is not. 但是由于某种原因,在创建UITableViewCell子类时,没有创建UITextField I can call UITableViewSubclass and it's initialized, but UITableViewSubclass.UITextField is nil. 我可以调用UITableViewSubclass并将其初始化,但是UITableViewSubclass.UITextField为nil。

Here's my UITableViewCell Subclass header (Yes, the UITextField is connected in the storyboard): 这是我的UITableViewCell子类标头(是的, UITextField连接在情节提要中):

#import <UIKit/UIKit.h>

@interface ConditionCell : UITableViewCell 

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

@end

Here's my implementation file: 这是我的实现文件:

#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

This here is the Table View Controller handling the table that contains the cells: 这是Table View Controller,用于处理包含单元格的表:

.h file: .h文件:

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

@interface ConditionsTableViewController : UITableViewController

@property (strong, nonatomic) NSMutableArray *conditionCellArray;

- (void)addNewConditionCell;

@end

.m file: .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

This Table View Controller lives inside a UIView Controller as the table view does not take up the whole screen. 该表视图控制器位于UIView控制器内部,因为表视图不会占据整个屏幕。 When the user presses an 'ok' button there is a segue that is triggered and it is here that I ask this Table View Controller for the array containing the UITableViewCells , which I then run through a foreach to get their .text properties. 当用户按下“确定”按钮时,会触发一个选择,正是在这里我向此表视图控制器询问包含UITableViewCells的数组,然后我通过一个foreach来获取其.text属性。 Unfortunately I can't seem to get anything I input into the text fields, hence the .text's are always nil. 不幸的是,我似乎无法在文本字段中输入任何内容,因此.text始终为零。 If anyone could help me with this issue it would be greatly appreciated! 如果有人可以帮助我解决这个问题,将不胜感激!

You might find this much easier to do using the free Sensible TableView framework. 使用免费的Sensible TableView框架,您可能会发现这样做更容易。 The framework has these text field cells out of the box, and can even create them automatically from your array. 该框架具有开箱即用的这些文本字段单元格,甚至可以从您的数组自动创建它们。

I figured out a better way to do what I wanted to do here that works. 我想出了一种更好的方法来做自己想做的事。 Turns out that the way iOS's UITableView works is totally different from what I wanted to do. 事实证明,iOS的UITableView的工作方式与我想要的完全不同。 UITableView works by looking at your storyboard and given the identifiers for the cells, it creates them and allows you to set their properties within the cellForRowAtIndexPath method. UITableView通过查看情节提要和给定的单元格标识符来工作,创建它们并允许您在cellForRowAtIndexPath方法内设置其属性。 However, when the cell goes offscreen, it is not retained as it's own separate object; 但是,当单元离开屏幕时,它不会保留,因为它是自己的单独对象。 it is reused. 它被重用。 So, you can think of it as if when you scroll a table view, the cells that disappear to one end reappear on the other end with new information. 因此,您可以认为它就像在滚动表格视图时,消失到一端的单元格在另一端再次出现新信息。 This is key - UITableView want YOU to provide the cell's information. 这是关键-UITableView希望您提供单元格的信息。 It was not made for input of information directly on a UITableViewCell, which is what I wanted to do. 我不是想直接在UITableViewCell上输入信息。

So what I ended up doing was copy-pasting my cells into their own .xib file, and in the subclass initWithStyle:reuseIdentifier method, do: 因此,我最终要做的是将单元格复制粘贴到自己的.xib文件中,并在子类initWithStyle:reuseIdentifier方法中执行以下操作:

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

And that creates the cell with whatever style - setup - UI elements you want. 这样就可以创建具有任何样式的单元格-设置-所需的UI元素。

Next, I want to hold on to a reference to the cell, because that cell has a textbox, and I need to save what's on the textbox when the user presses a "done" button. 接下来,我要保留对该单元格的引用,因为该单元格具有一个文本框,并且当用户按下“完成”按钮时,我需要保存该文本框上的内容。 However, testing revealed the reuse problem I explained above. 但是,测试发现了我上面解释的重用问题。 So how to do this? 那么该怎么做呢? In my Table's view controller, whenever the user wants to add a new textbox (and presses the button to do so) I have a method which does 在我的表格的视图控制器中,每当用户想要添加一个新的文本框(并按下按钮来这样做)时,我都有一个方法

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

This adds a new cell to an array - this is important because I need to have a reference to ALL cells at all times. 这会向数组中添加新的单元格-这很重要,因为我需要始终引用所有单元格。 (It is adding the cell at index 0 because I want to insert it at the top). (它正在将单元格添加到索引0,因为我想将其插入顶部)。 Then, in the cellForRowAtIndexPath method, I did 然后,在cellForRowAtIndexPath方法中,我做了

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

Which will return the corresponding cell. 它将返回相应的单元格。 Bear in mind, from what I have read this whole thing about keeping a reference to each and every cell in the table is contrary to Apple's stated best practices when using UITableView. 请记住,从我读到的所有有关保持对表中每个单元格的引用的内容来看,这与苹果公司使用UITableView时所说的最佳做法背道而驰。 However, as I said before, UITableView is meant to display information, not to gather it from user input. 但是,正如我之前说的,UITableView用于显示信息,而不是从用户输入中收集信息。 So this is why I had to break the rules, if you will, to achieve the desired effect (that I wanted). 因此,这就是为什么我必须违反规则才能达到预期的效果(我想要的)。 I hope this helps others who are looking to do the same thing; 我希望这对其他希望做同样事情的人有所帮助; and if there is a better way don't be shy about telling me. 如果有更好的方法,请不要羞于告诉我。

EDIT: Oh by the way, when you copy paste the cells created in storyboard to their own .xib file make sure to disconnect any IBOutlets and change their class back to UITableViewCell. 编辑:哦,顺便说一句,当您将在情节提要中创建的单元格复制粘贴到其自己的.xib文件中时,请确保断开所有IBOutlet的连接并将其类更改回UITableViewCell。 That way there won't be any problems or conflicts when you connect your .xib file cell. 这样,在连接.xib文件单元时就不会有任何问题或冲突。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 无法将值从 UITextField 返回到 UITableViewCell 中的 UILabel 作为子视图 - Can't return a value from UITextField to UILabel in UITableViewCell as subviews 将UITextField链接到UITableViewCell子类时遇到麻烦 - Troubling linking UITextField to UITableViewCell subclass 为什么我必须删除UITableViewCell的已添加子视图,而不要删除UITableViewCell的子类中的子视图? - Why do I have to remove added subviews for UITableViewCell but not in a Subclass of UITableViewCell? 如何将UITextField或UITextView添加到UItableViewCell并编辑内容? - How can I add a UITextField or a UITextView to a UItableViewCell and edit the content? 如何在UITableViewCell内的UITextField中编辑文本? - How can I edit text in a UITextField when its inside a UITableViewCell? 如何创建自定义TextCell和TextRow,其中包含UITextField的子类? - How can I create a custom TextCell and TextRow that has a subclass of UITextField in it? 为什么我不能为UITableViewCell的contentView添加掩码? - Why can't I add a mask to UITableViewCell's contentView? 似乎无法向我的UITableViewCell子类添加子层 - Can't seem to add a sublayer to my UITableViewCell subclass 为什么我不能将图像设置为UITableViewCell? - Why can't I set an image to my UITableViewCell? 我如何使用@IBDesignable和@IBInspectable创建uitextfield的自定义子类,并且可以在左侧设置placholder padding - How can I make a custom subclass of uitextfield and over there using @IBDesignable & @IBInspectable I can set placholder padding from left
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM