【问题标题】:UITableViewCell with a lot of subviews or with a single viewUITableViewCell 有很多子视图或单个视图
【发布时间】:2013-06-20 06:56:00
【问题描述】:

我是 iOS 编程新手,这就是为什么我正在寻找最有效的解决方案来解决我的问题。 我想要实现的是在UITableViewCell 中显示一个名称(一些文本),并在每个名称下显示一些带有数字的填充小矩形,类似于徽章。

我的第一个想法是创建一个代表徽章的UIView,并在自定义UITableViewCell 中添加这些矩形为subviews。 第二个想法是只创建一个UIView 来绘制所有的小矩形。

我的问题是,知道以下哪一个是性能更好的解决方案:

  • 单元格数将达到最大值。 20个,矩形总数不超过50个
  • 一个单元格中显示的矩形数量不同
  • 我想重复使用单元格,所以我必须更新/重绘每一行的单元格内容
  • 我想避免“隐藏”子视图的单元格选择视图问题

当然欢迎任何其他解决方案。

提前致谢, hxx

【问题讨论】:

    标签: ios objective-c uitableview subview


    【解决方案1】:

    我的建议是将 UITableViewCell 子类化并在其中进行您需要的自定义。自定义视图可以在其下方有一个标签和矩形。

    矩形可以是小的自定义按钮,带有背景图像(如果有或给它一个背景颜色)和标题作为你的数字。你必须,但是根据你的桌子的宽度计算它们的宽度以适应最大矩形数。

    您可以禁用 xib 中的表格选择,也可以像 cell.selectionStyle = UITableViewCellSelectionStyleNone; 那样以编程方式执行此操作,并且不实现 didSelectRowAtIndexPath

    我已经按照为我的表格子类化单元格的方法来自定义它们的外观和感觉,并且效果很好。我希望这会有所帮助。

    在这里可以找到一个很好的子类化教程

    http://howtomakeiphoneapps.com/how-to-design-a-custom-uitableviewcell-from-scratch/1292/

    【讨论】:

    • 所以,您说要将矩形添加为子视图。但是内存消耗呢?我不需要在单元格中包含 UI 对象,因为我只需要显示带有彩色背景的数字。
    • 为了在任何视图上显示任何类型的文本,您需要一个标签。此标签必须是给定视图的子视图。在任何给定时间,在您的表格中,只有可见单元格会在内存中.这就是“dequeueReusableCellWithIdentifier”的作用。如果需要显示文本,添加标签作为子视图是不可避免的。
    • 通常是的,我需要一个 UILabel 对象,但是如果我将 UIView 子类化,在 drawRect 方法中我可以使用 NSString 的 drawAtPoint 在其上绘制文本。所以我不需要总是标签来在单元格上显示文本。但我的问题是,如果一个单元格被重用,它的 drawRect 方法会在每次分配一个新值时调用,或者只有在创建单元格对象时调用一次。
    • 哦,是吗!!,谢谢你,我今天学到了一个新东西。我不知道这一点。抱歉,错误地创建一个标签是不可避免的。如果我理解正确,你需要打电话如果你愿意,你可以尝试 drawRect,也许你可以尝试 [self.view setNeedsDisplay],这会调用 drawRect。
    【解决方案2】:

    为什么您不在-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 中创建单元格在这里您可以定义您的自定义类型单元格,该单元格也将重用,并且您可以随时将不同的内容添加到单元格中。

    static NSString *CellIdentifier = @"Cell";
    UILabel *RequestSentTo;
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] ;
        cell.selectionStyle=UITableViewCellSelectionStyleNone;
        RequestSentTo = [[UILabel alloc] initWithFrame:CGRectMake(11, 2, 286, 40)];
        RequestSentTo.backgroundColor = [UIColor clearColor];
        RequestSentTo.tag = 200;
        RequestSentTo.numberOfLines = 3;
        RequestSentTo.font=[UIFont boldSystemFontOfSize:15.0];
        RequestSentTo.textColor = [UIColor blackColor];
        RequestSentTo.lineBreakMode=UILineBreakModeWordWrap;
        [cell.contentView addSubview:RequestSentTo];
    } else {
        RequestSentTo=(UILabel*)[cell.contentView viewWithTag:200];
    }
    NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:@"Shift Request for "];
    [string appendAttributedString:[[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@ by ",dateStr] attributes:nil]];
    [string appendAttributedString:[[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"Dr. %@",notificationsObj.doctorName] attributes:purpleTextAttributes]];//purpl
    RequestSentTo.attributedText=string;
    RequestSentTo.lineBreakMode=UILineBreakModeWordWrap;
    RequestSentTo.numberOfLines = 3;
    

    您可以随时通过重用单元添加您想要的东西。希望这会有所帮助

    【讨论】:

    • 感谢您的快速回答。正如我所写,单元格中的矩形数量不同,因此我无法用单个 UILabel 替换它们。按照您的解决方案,我需要根据单元格中矩形的数量添加动态标签(视图)。还可以,就是怕内存太大。
    • 你可以拥有多少个矩形取决于你可以动态创建uilabels并在其上添加标签。
    【解决方案3】:

    我想到了两种方法。

    1. 您可以将组件作为子视图放在UITableViewCell 中(通过XIB 或以编程方式子类化UITableViewCell)并在UITableView 中使用它。

    2. 您可以继承UITableViewCell,并覆盖-(void)drawRect 方法并绘制您希望在单元格上显示的所有组件。

    【讨论】:

    • 是的,您的第二种方法几乎是我想象的,以便在视图上绘制矩形,但作为 UITableViewCell 子类的子视图。我不清楚的是,如何强制单元格刷新自身并在单元格被重用时绘制相应的矩形。
    • UITableViewCell 有强制绘制的方法(setNeedsLayout 方法)
    【解决方案4】:

    看看能不能帮上忙。 您可以创建一个新的类扩展至 UITableViewCell,这意味着将 UITableViewCell 重写为您自己的单元格,命名为 MyTestCell。 在这个单元格中,您调用创建您的属性,如标签和视图,并将它们添加到您的新单元格中。 喜欢把这个添加到 MyTestCell.h

    @property (nonatomic, retain) UILable *myLable1;
    @property (nonatomic, retain) UIView *mySubview1;
    
    MyTestCell.m
    _myLable1 = .....
    _mySubview = .....
    
    [self addSubview: _myLbale1];
    [self addSubview: _mySubview1];
    
    
    And when use, u can work like this
    
    static NSString *CellIdentifier = @"MyCell";
    MyTableViewCell *cell = [tableview dequeReuseID:CellIdentifier]; 
    if (cell == nil) {
      cell = [MyTableViewCell alloc] init.........
    } 
    
    //And you can sign your property here in your cell
    cell.myLable1 = ....
    cell.myView1 = .....
    
    return cell;
    
    }
    

    如果您添加到标签的字符串不同,请使标签.高度不同。你可以使用这样的代码

     CGSize labelSize = [str sizeWithFont:[UIFont boldSystemFontOfSize:17.0f]
                       constrainedToSize:CGSizeMake(280, 100)
                       lineBreakMode:UILineBreakModeCharacterWrap];   //check your lableSize
     UILabel *patternLabel = [[UILabel alloc] initWithFrame:CGRectMake(35, 157, labelSize.width, labelSize.height)];   
     patternLabel.text = str;
     patternLabel.backgroundColor = [UIColor clearColor];
     patternLabel.font = [UIFont boldSystemFontOfSize:17.0f];
     patternLabel.numberOfLines = 0;// must have
     patternLabel.lineBreakMode = UILineBreakModeCharacterWrap;// must have
    

    将此添加到您的单元格中,并使其动态调整您的标签以及您的单元格的大小!而且您还必须为您的 tableView 行高度动态设置高。(知道什么是动态调整大小吗?) 看到这个: 重写MyTableViewCell.m中的setMyLable1方法

     -(void)setMyLable1:(UILable*)aLable
     {
       //in here when never your sign your alabel to your cell (like this : cell.myLable1) this method will be call and u can get the size of your string and set this label's height
       //get string size  StringSzie
    
       [_myLable1 setFrame:CGRectMake(10,10,stringSize.width,stringSize.height)];
    
       //And resize your cell as well
       [self setFrame:CGRectMake(0,0,_myLable1.frame.size.width+20,_myLable1.frame.size.height+20)];
    
       //done!!!
    
     } 
    

    好的,你会为自己获得一个自动重新调整的单元格,你也必须在 tableView 中为你的行动态重置高度!!!!!!

    【讨论】:

      【解决方案5】:

      你需要什么叫做自定义单元格

      这里有很好的教程

      customize table view cells for uitableview

      【讨论】:

      • 是的,我知道,但问题是要在自定义单元格中添加什么。绘制矩形的单个视图还是每个矩形的单独视图?
      • 这个容器UIView里面最好有容器UIView和矩形的单独视图
      猜你喜欢
      • 1970-01-01
      • 2011-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-24
      • 1970-01-01
      • 2015-01-14
      相关资源
      最近更新 更多