Iphone 自定义UITableViewCells

Iphone 自定义UITableViewCells,iphone,objective-c,cocoa-touch,uitableview,Iphone,Objective C,Cocoa Touch,Uitableview,我真的很惊讶,在做iphone应用程序的时候,要保持代码的良好结构和可读性是多么困难。。。但可能是因为我做错了什么 我有一个注册页面,包含不同类型的内联可编辑数据:生日、性别、姓名、密码、电话号码。我将该页面作为自定义单元格的表视图,其中每个单元格都是UITableViewCell子类的实例,并从其自己的nib文件中读取。这是因为我认为我以后可以在其他表视图页面中重用这些不同类型的单元格 但是,将不同的自定义单元格封装在各自位置的方法并没有起到很好的作用: 谁将成为GenderCell内性别采集

我真的很惊讶,在做iphone应用程序的时候,要保持代码的良好结构和可读性是多么困难。。。但可能是因为我做错了什么

我有一个注册页面,包含不同类型的内联可编辑数据:生日、性别、姓名、密码、电话号码。我将该页面作为自定义单元格的表视图,其中每个单元格都是UITableViewCell子类的实例,并从其自己的nib文件中读取。这是因为我认为我以后可以在其他表视图页面中重用这些不同类型的单元格

但是,将不同的自定义单元格封装在各自位置的方法并没有起到很好的作用:

  • 谁将成为GenderCell内性别采集器等的控制者

  • 当我必须将SignUpController作为cell nib文件的文件所有者时,如何在不同的表视图控制器中重用这些单元格

  • 我不知道除了我自己,是否有人理解我刚才写的内容,但如果是这样,我将非常感谢任何关于如何以不同方式构造代码的建议

    非常感谢,
    斯汀

    为了让事情更清楚(?!),让我将一些代码粘贴到这里:

    可编辑标签.h

    @interface EditableLabel : UILabel {   
        UIView *inputView, *inputAccessoryView; 
    }
    
    @property (nonatomic, retain) UIView *inputView, *inputAccessoryView; 
    
    - (void) setInputView:(UIView *)aView andToolbar:(UIToolbar *)aToolbar;
    
    @end
    
    EditableLabel.m

    @implementation EditableLabel
    
    @synthesize inputView, inputAccessoryView;
    
    - (void) dealloc {
        [inputView release];
        [inputAccessoryView release];
        [super dealloc];
    }
    
    - (void) setInputView:(UIView *)aView andToolbar:(UIToolbar *)aToolbar {
        self.inputAccessoryView = aToolbar;
        self.inputView = aView;
    }
    
    - (BOOL) canBecomeFirstResponder {
        return YES;
    }
    
    - (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
        [self becomeFirstResponder];
    }
    
    @end
    
    可编辑单元格.h

    typedef enum {
        USERNAME, PASSWORD, MOBILE, BIRTHDAY, GENDER, DESCRIPTION, CATEGORY
    } CellTag;
    
    @interface EditableCell : UITableViewCell {
        CellTag tag;    
        UIView *editPoint;
        IBOutlet UILabel *headerLabel;
    }
    
    - (void) setTag:(CellTag)aTag andHeader:(NSString *)aHeader andEditPoint:(UIView *)aView;
    
    @property (nonatomic) CellTag tag;
    @property (nonatomic, retain) UIView *editPoint;
    @property (nonatomic, retain) UILabel *headerLabel;
    
    - (IBAction) editingDone:(id)sender;
    
    - (void) showInputView;
    - (void) hideInputView;
    
    @end
    
    可编辑细胞

    @implementation EditableCell
    
    @synthesize tag, editPoint, headerLabel;
    
    - (void) dealloc {
        [editPoint release];
        [headerLabel release];
        [super dealloc];
    }
    
    - (void) setTag:(CellTag)aTag andHeader:(NSString *)aHeader andEditPoint:(UIView *)aView {
        self.tag = aTag;
        self.headerLabel.text = aHeader;
        self.editPoint = aView;
    }
    
    - (IBAction) editingDone:(id)sender {
        [self hideInputView];
    }
    
    - (void) showInputView {   
        [self.editPoint becomeFirstResponder];
    }
    
    - (void) hideInputView {
        [self.editPoint resignFirstResponder];    
    }
    
    @end
    
    可编辑的labelcell.h

    @interface EditableLabelCell : EditableCell {
        IBOutlet UILabel *placeHolderLabel;
        IBOutlet EditableLabel *editableLabel;
    }
    
    @property (nonatomic, retain) UILabel *placeHolderLabel;
    @property (nonatomic, retain) EditableLabel *editableLabel;
    
    - (void) setTag:(CellTag)aTag 
          andHeader:(NSString *)aHeader 
     andPlaceHolder:(NSString *)aPlaceHolder
       andInputView:(UIView *)aView
         andToolbar:(UIToolbar *)aToolbar;
    
    - (void) setValue:(NSString *)aValue;
    
    @end
    
    可编辑的labelcell.m

    @implementation EditableLabelCell
    
    @synthesize placeHolderLabel, editableLabel;
    
    - (void) dealloc {
        [placeHolderLabel release];
        [editableLabel release];
        [super dealloc];
    }
    
    - (void) setTag:(CellTag)aTag andHeader:(NSString *)aHeader andPlaceHolder:(NSString *)aPlaceHolder andInputView:(UIView *)aView andToolbar:(UIToolbar *)aToolbar {
        [super setTag:aTag andHeader:aHeader andEditPoint:self.editableLabel];
        self.placeHolderLabel.text = aPlaceHolder;
        [self.editableLabel setInputView:aView andToolbar:aToolbar];    
    }
    
    - (void) setValue:(NSString *)aValue {
        if (aValue && aValue != @"") {                
            self.placeHolderLabel.hidden = YES;
            self.editableLabel.text = aValue;        
        } else {
            self.editableLabel.text = nil;
            self.placeHolderLabel.hidden = NO;
        }
    }
    
    @end
    
    可编辑GenderCell.h

    @protocol EditableGenderCellDelegate <NSObject>
    @required
      - (NSString *) getTextForGender:(Gender)aGender;
      - (void) genderChangedTo:(Gender)aGender forTag:(CellTag)aTag;
    @end
    
    @interface EditableGenderCell : EditableLabelCell <UITableViewDataSource, UITableViewDelegate> {
        id<EditableGenderCellDelegate> delegate;    
        Gender gender;
        IBOutlet UITableView *genderTable;
        IBOutlet UIToolbar *doneBar;
    }
    
    - (void) setTag:(CellTag)aTag 
        andDelegate:(id<EditableGenderCellDelegate>)aDelegate 
          andHeader:(NSString *)aHeader 
          andGender:(Gender)aGender
     andPlaceHolder:(NSString *)aPlaceHolder;
    
    @property (nonatomic, retain) id<EditableGenderCellDelegate> delegate;
    @property (nonatomic) Gender gender;
    @property (nonatomic, retain) UITableView *genderTable;
    @property (nonatomic, retain) UIToolbar *doneBar;
    
    @end
    
    @协议可编辑GenderCellDelegate
    @必需的
    -(NSString*)getTextForGender:(性别)aGender;
    -(无效)性别变更为:(性别)代理forTag:(细胞标签)aTag;
    @结束
    @接口EditableGenderCell:EditableLabelCell{
    id代表;
    性别;
    IBUITableView*性别表;
    IBUIToolbar*doneBar;
    }
    -(void)setTag:(CellTag)aTag
    代理人:(id)代理人
    andHeader:(NSString*)标题
    andGender:(性别)aGender
    andPlaceHolder:(NSString*)空间持有者;
    @属性(非原子,保留)id委托;
    @财产(非原子)性别;
    @属性(非原子,保留)UITableView*genderTable;
    @属性(非原子,保留)UIToolbar*doneBar;
    @结束
    
    EditableGenderCell.m

    @implementation EditableGenderCell
    
    @synthesize delegate, gender, genderTable, doneBar;
    
    - (void) dealloc {
        [delegate release];
        [genderTable release];
        [doneBar release];
        [super dealloc];
    }
    
    - (void) setTag:(CellTag)aTag andDelegate:(id<EditableGenderCellDelegate>)aDelegate andHeader:(NSString *)aHeader andGender:(Gender)aGender andPlaceHolder:(NSString *)aPlaceHolder {
        [super setTag:aTag andHeader:aHeader andPlaceHolder:aPlaceHolder andInputView:self.genderTable andToolbar:self.doneBar];
        self.delegate = aDelegate;
        self.gender = aGender;
        [super setValue:[self.delegate getTextForGender:aGender]];
    }
    
    #pragma mark - Table view data source
    
    - (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
        return 1;
    }
    
    - (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
        return 2;
    }
    
    - (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        static NSString *CellIdentifier = @"Cell";
    
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) {
            cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
        }
    
        switch (indexPath.row) {
            case MALE:
                switch (self.gender) {
                    case MALE:
                        cell.accessoryType = UITableViewCellAccessoryCheckmark;    
                        break;
                    default:
                        cell.accessoryType = UITableViewCellAccessoryNone;  
                } 
                break;
            case FEMALE:
                switch (self.gender) {
                    case FEMALE:
                        cell.accessoryType = UITableViewCellAccessoryCheckmark;    
                        break;
                    default:
                        cell.accessoryType = UITableViewCellAccessoryNone; 
                }  
                break;
        }
    
        cell.textLabel.text = [self.delegate getTextForGender:indexPath.row];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
    
        return cell;
    }
    
    #pragma mark - Table view delegate
    
    - (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
        self.gender = indexPath.row;
        [super setValue:[self.delegate getTextForGender:self.gender]];
        [self.delegate genderChangedTo:self.gender forTag:self.tag];   
        [tableView reloadData];
    }
    
    @end
    
    @implementation-EditableGenderCell
    @综合代表、性别、性别表、doneBar;
    -(无效)解除锁定{
    [授权释放];
    [性别释放];
    [多尼巴释放];
    [super dealoc];
    }
    -(void)setTag:(CellTag)aTag和delegate:(id)aDelegate和header:(NSString*)header和Gender:(Gender)aGender和placeholder:(NSString*)aPlaceHolder{
    [super-setTag:aTag和header:aHeader和placeholder:aPlaceHolder和inputView:self.genderTable和toolbar:self.doneBar];
    self.delegate=aDelegate;
    self.gender=aGender;
    [超级设置值:[self.delegate gettextfegender:aGender]];
    }
    #pragma标记-表视图数据源
    -(NSInteger)表格视图中的节数:(UITableView*)表格视图{
    返回1;
    }
    -(NSInteger)表视图:(UITableView*)表视图行数节:(NSInteger)节{
    返回2;
    }
    -(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath{
    静态NSString*CellIdentifier=@“Cell”;
    UITableViewCell*单元格=[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    如果(单元格==nil){
    cell=[[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault重用标识符:CellIdentifier]自动释放];
    }
    开关(indexPath.row){
    个案男:
    切换(自我性别){
    个案男:
    cell.accessoryType=UITableViewCellAccessoryCheckmark;
    打破
    违约:
    cell.accessoryType=UITableViewCellAccessoryNone;
    } 
    打破
    案例女性:
    切换(自我性别){
    案例女性:
    cell.accessoryType=UITableViewCellAccessoryCheckmark;
    打破
    违约:
    cell.accessoryType=UITableViewCellAccessoryNone;
    }  
    打破
    }
    cell.textlab.text=[self.delegate gettextfegender:indexPath.row];
    cell.selectionStyle=UITableViewCellSelectionStyleNone;
    返回单元;
    }
    #pragma标记-表视图委托
    -(void)tableView:(UITableView*)tableView未选择RowatineXpath:(NSIndexPath*)indexPath{
    self.gender=indexath.row;
    [super-setValue:[self.delegate-getTextForGender:self.gender];
    [self.delegate genderChangedTo:self.gender forTag:self.tag];
    [tableView重新加载数据];
    }
    @结束
    
    这是可用于弹跳的代码:

     -(IBAction)textFieldDidBeginEditing:(UITextField *)textField { //Keyboard becomes visible
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationDuration:0.3];
    self.view.frame = CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y - 50, self.view.frame.size.width, self.view.frame.size.height);
    [UIView commitAnimations];
    
    }


    只需相应地设置y,并在编辑开始时调用它。

    看看我的答案

    您应该使用表示单元格的自定义类备份自定义tableviewcell nib文件,并在其中封装逻辑,例如性别选择器。如果您需要将性别告知外部控制者,您可以使用委托模式

    TableViewCell中的自定义性别选择器 好的,让我们从nib文件开始,如下所示:

    查看层次结构,不设置文件的所有者

    …改为设置自定义类的表视图单元格的类:

    自定义类 如您所见,该类几乎为空,只提供分段控件作为属性

    GenderPickerTableViewCell.h

    @interface GenderPickerTableViewCell : UITableViewCell 
    {
        UISegmentedControl *genderPickerSegmentedControl;
    }
    
    @property (nonatomic, retain) IBOutlet UISegmentedControl *genderPickerSegmentedControl;
    
    @end
    
    GenderPickerTableViewCell.m

    #import "GenderPickerTableViewCell.h"
    
    
    @implementation GenderPickerTableViewCell
    
    @synthesize genderPickerSegmentedControl;
    
    #pragma mark -
    #pragma mark memory management
    
    - (void)dealloc 
    {   
        [genderPickerSegmentedControl release];
        
        [super dealloc];
    }
    
    #pragma mark -
    #pragma mark initialization
    
    - (void)awakeFromNib
    {
        // initialization goes here, for example preselect a specific gender
    }
    
    @end
    
    使用新单元格的表视图 我将只提供必要的方法,使这项工作。TableViewCellFactory类只是一个nib加载器,就像我在上面的文章中发布的那样。genderPickerTableViewCellWithTableView只是一个方便的类方法,用于返回这种特殊类型的单元格,而无需太多样板代码

    最后要注意的是单元的配置,这很简单,我只需直接访问分段控件并向其添加一个目标,其中
    #pragma mark -
    #pragma mark view lifecycle
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        tableView.rowHeight = 100.0;
        tableView.dataSource = self;
        tableView.delegate = self;
    }
    
    #pragma mark -
    #pragma mark UITableView methods
    
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        return 1;
    }
    
    - (UITableViewCell *) tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)anIndexPath
    {
        GenderPickerTableViewCell *cell = [TableViewCellFactory genderPickerTableViewCellWithTableView:aTableView];
    
        [cell.genderPickerSegmentedControl addTarget:self 
                                              action:@selector(genderPicked:) 
                                    forControlEvents:UIControlEventValueChanged];
        
        return cell;
    }
    
    #pragma mark -
    #pragma mark UISegmentedControl action
    
    - (void)genderPicked:(id)sender
    {
        UISegmentedControl *segmentedControl = (UISegmentedControl *)sender;
        
        NSLog(@"selected index: %d", [segmentedControl selectedSegmentIndex]);
    }