iPhone:如何构建类似于联系地址单元格的自定义tableview单元格

时间:2011-01-23 23:03:26

标签: iphone uitableview street-address

这可能已经讨论过但我找不到问题。

我需要在表格视图中显示/编辑地址。查看iPhone联系人应用程序中的地址单元格,看起来他们使用单个单元格来显示和编辑地址。

我首先想到的是通过使用4个自定义单元格来编辑地址,但我看不到地址类型字段如何跨越4行,此外,选中时,它选择了所有4行。这让我觉得它是用一个表视图单元格完成的,它有一个UItextFields的自定义排列。

目前我正走这条路。让我陷入困境的是处理细胞之间的灰线。我最初打开了UItextField边框,但这看起来并不是很好。所以我正在考虑做自定义绘图。但这似乎并没有在细胞之上绘制。

有没有人知道苹果如何构建这个地址单元?

由于

3 个答案:

答案 0 :(得分:2)

执行以下操作:

  • 使用单元格的UITableViewCellStyleValue2样式
  • numberOfLines的{​​{1}}属性设置为您选择的号码
  • 实施cell.detailsTextLabel方法并返回使用以下公式计算的高度:-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

我在互联网上的某个地方读到这个,但不记得来源。今天就试过这个,它完美无瑕。

答案 1 :(得分:1)

如果要在表视图中的每个单元格之间使用一条线,然后使用“已分组”样式 - 请参阅Interface Builder中“属性”检查器中的“表视图”选项卡。每个小组的成员之间都有一条线。

您是否考虑过使用UITableViewCells而不是以编程方式添加UIViews?您可以轻松地向这样的XIB添加标签和文本字段+垂直线。这对我来说非常适合使用以下代码:

@protocol PersonDetailCellViewControllerDelegate

-(void)didUpdateTextField:(int)index withText:(NSString*)text;

@end


@interface PersonDetailCellViewController : UITableViewCell <UITextFieldDelegate> {

    IBOutlet UILabel* keyLabel;
    IBOutlet UITextField* valueTextField;

    int index;
    id<PersonDetailCellViewControllerDelegate> delegate;

}

@property (nonatomic, retain) IBOutlet UILabel* keyLabel;
@property (nonatomic, retain) IBOutlet UITextField* valueTextField;
@property (nonatomic, retain) id<PersonDetailCellViewControllerDelegate> delegate;
@property (nonatomic, assign) int index;

@end

@implementation PersonDetailCellViewController

@synthesize keyLabel, valueTextField, delegate, index;

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if(delegate) {
    [delegate didUpdateTextField:index withText:[textField.text stringByReplacingCharactersInRange:range withString:string]];
}
return YES;
}

- (BOOL)textFieldShouldClear:(UITextField *)textField {
    return YES;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    return YES;
}

@end

使用相应的UITableView方法

// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    PersonDetailCellViewController *cell = (PersonDetailCellViewController*)[aTableView dequeueReusableCellWithIdentifier:CELL_KEY_VALUE_ID];

    if(cell == nil) {
        NSArray* topLevelObjects = [[NSBundle mainBundle]loadNibNamed:@"PersonDetailCellView" owner:nil options:nil];

        for(id currentObject in topLevelObjects) {
            if([currentObject isKindOfClass:[UITableViewCell class]]) {
                cell = (PersonDetailCellViewController*)currentObject;

                cell.valueTextField.backgroundColor = [UIColor clearColor];
                cell.valueTextField.borderStyle = UITextBorderStyleNone;
                cell.selectionStyle = UITableViewCellSelectionStyleGray;

                if([Language sharedLanguage].rightToLeft) {
                    // set the alignment right because we are flipping the whole available text field, not just the area which actually has text
                    cell.keyLabel.textAlignment = UITextAlignmentRight;
                    cell.valueTextField.textAlignment = UITextAlignmentLeft;

                    // flip cell contents
                    cell.contentView.layer.transform = CATransform3DMakeRotation(M_PI, 0.0f, 1.0f, 0.0f); 
                    // flip text back so that readable
                    cell.keyLabel.layer.transform = CATransform3DMakeRotation(M_PI, 0.0f, 1.0f, 0.0f);
                    cell.valueTextField.layer.transform = CATransform3DMakeRotation(M_PI, 0.0f, 1.0f, 0.0f);
                }

                cell.selectionStyle = UITableViewCellSelectionStyleGray;

                break;
            }
        }
    }

    cell.keyLabel.text = [keys objectAtIndex:indexPath.section];
    cell.valueTextField.placeholder = [hints objectAtIndex:indexPath.section];
    cell.valueTextField.delegate = cell;

    if(indexPath.section == 0) {
        cell.valueTextField.text = self.name;
    } else if(indexPath.section == 1) {
        cell.valueTextField.text = self.mobile;
    } else if(indexPath.section == 2) {
        cell.valueTextField.text = self.home;
    }

    if(indexPath.section == 1) {
        cell.valueTextField.keyboardType = UIKeyboardTypePhonePad;
    } else {
        cell.valueTextField.keyboardType = UIKeyboardTypeDefault;
    }

    // open keyboard
    if(indexPath.section == 0) {
        [cell.valueTextField becomeFirstResponder];
    } else {
        [cell.valueTextField resignFirstResponder];
    }

    cell.delegate = self;
    cell.index = indexPath.section;

    return cell;
}

最好的问候,托马斯。

答案 2 :(得分:0)

我有一些工作,但我不确定它是否构建得那么好。我基本上创建了一个UIView,它为地址的各个字段保存UITextFields。我为它构建了一个自定义控制器,用于管理数据并在字段之间绘制灰线,就像在联系人中一样。

然后我将这个自定义UIView添加到UITableView单元格。我的理解是,这是建议的方法,因为drawRect中的任何绘图:然后保持在UITableViewCell的边界内。我使用drawRect的实验:在UITableView单元类中绘制了UITableView背景上的线条,而不是单元格。

这基本上有效,但有一件事我不喜欢。为了让灰色线条延伸到UITableViewCell的边框,我必须确保放在其中的UIView大小完全相同,以便在drawRect:中完成的任何绘图都可以直接扩展到UITableViewCell的边缘。

但是如果我使用不透明的背景,我会松开细胞的漂亮圆角,因为它是在顶部绘制的。所以我不得不使用透明背景。我的理解是出于性能原因推荐使用不透明背景,所以我不确定我是否真的正确地构建了这个控件。幸运的是,屏幕上不再有2或3个。