【问题标题】:iPhone: Howto build a custom table view cell similar to contact address celliPhone:如何构建类似于联系人地址单元格的自定义表格视图单元格
【发布时间】:2013-07-03 02:57:37
【问题描述】:

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

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

I first thought it was done by using 4 custom cells to edit the address, but I could not see how the address type field could span the 4 rows, in addition, when selected, it selected all 4 rows.这让我觉得它是使用单个表格视图单元格完成的,该单元格具有 UItextFields 的自定义排列。

目前我正在走这条路。目前让我陷入困境的事情是处理单元格之间的灰线。我最初打开了 UItextField 边框,但这看起来不太好。所以我正在研究做自定义绘图。但这似乎没有在单元格顶部绘制。

有人知道苹果是如何构造这个地址单元的吗?

谢谢

【问题讨论】:

    标签: iphone uitableview street-address


    【解决方案1】:

    执行以下操作:

    • 为您的单元格使用UITableViewCellStyleValue2 样式
    • cell.detailsTextLabelnumberOfLines 属性设置为您选择的数字
    • 实现-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath方法并返回使用此公式计算的高度:44.0f + (numberOfLines - 1) * 19.0f

    我在 Internet 的某个地方读到过这篇文章,但不记得出处。今天刚试了一下,效果很好。

    【讨论】:

    • 谢谢。当我格式化地址的只读显示时,这将非常有用。这是给我问题的编辑模式显示:-)
    【解决方案2】:

    如果您想在表格视图中的每个单元格之间有一条线,请使用“分组”样式 - 请参阅 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;
    }
    

    最好的问候,托马斯。

    【讨论】:

    • 谢谢托马斯。我已经在使用分组单元格了。我正在尝试模拟地址单元在联系人中的工作方式。使用联系地址表明正在使用单个单元格。另外 - 就像联系人地址编辑一样 - 我在每一行使用多个字段。
    【解决方案3】:

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-10
      • 2014-08-01
      • 2017-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多