IOS 7中的表格视图单元格扩展

Posted

技术标签:

【中文标题】IOS 7中的表格视图单元格扩展【英文标题】:Table view cell expanding in IOS 7 【发布时间】:2013-10-01 09:08:04 【问题描述】:

我正在开发一个 ios 应用程序。我使用了表格视图。当用户单击任何单元格时,该单元格就会展开。但有些单元格在 iOS 7 中没有扩展。其他版本运行正常。下面是示例代码。我该如何纠正?

- (BOOL)cellIsSelected:(NSIndexPath *)indexPath 
    // Return whether the cell at the specified index path is selected or not
    NSNumber *selectedIndex = [selectedIndexes objectForKey:indexPath];
    return selectedIndex == nil ? FALSE : [selectedIndex boolValue];



#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

    return 1;


- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

    if([self cellIsSelected:indexPath])
        
            return 111;
        
        // Cell isn't selected so return single height
        return 41;


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

    return  [self.filteredItineraries count];


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

    static NSString *simpleTableIdentifier = @"FlightTracker";

    CellFlightTracker *cell = (CellFlightTracker *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];


    if(cell == nil)
    
        NSArray *nib=nil;

        nib = [[NSBundle mainBundle] loadNibNamed:@"CellFlightTracker" owner:self options:nil];

        cell = [nib objectAtIndex:0];
     




        if([self cellIsSelected:indexPath])
        
            cell.backgroundColor=[UIColor blackColor];
        else
        
            cell.backgroundColor=[UIColor darkGrayColor];
        


    return cell;


- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath

     if([self cellIsSelected:indexPath])
             cell.backgroundColor= [UIColor blackColor];
         else
             cell.backgroundColor= [UIColor darkGrayColor];


-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

    [tableView deselectRowAtIndexPath:indexPath animated:TRUE];

        // Toggle 'selected' state
        BOOL isSelected = ![self cellIsSelected:indexPath];

        // Store cell 'selected' state keyed on indexPath
        NSNumber *selectedIndex = [NSNumber numberWithBool:isSelected];
        [selectedIndexes setObject:selectedIndex forKey:indexPath];


        // This is where magic happens...
        [tableView1 beginUpdates];
        CellFlightTracker *selectedCell = (CellFlightTracker*)[tableView cellForRowAtIndexPath:indexPath];



        if(selectedCell.lblDepartureAirportStatus.hidden)
            [selectedCell.lblDepartureAirportStatus setHidden:NO];
        else
            [selectedCell.lblDepartureAirportStatus setHidden:YES];


        [tableView1 endUpdates];

【问题讨论】:

看看 cellIsSelected 的实现会很有用:... 作为一个测试,你能把[tableView deselectRowAtIndexPath:indexPath animated:TRUE]注释掉或者换成[tableView deselectRowAtIndexPath:indexPath animated:NO]吗?我在表格视图单元格中遇到了堆叠动画的问题。 @JefferyThomas 我试过但没用:/ 【参考方案1】:

如果你把UITableViewCell子类化并在调整单元格大小时使用layoutSubviews来调整会更好。

//In SMTableViewCell.h

@interface SMTableViewCell : UITableViewCell

@property (weak, nonatomic) IBOutlet UILabel *statusLabel;
@property (weak, nonatomic) IBOutlet UIButton *seeMoreButton;

//SMTableViewCell.m

- (void)layoutSubviews

    CGRect labelFrame = self.statusLabel.frame;
    labelFrame.size.height = self.frame.size.height - 55.0f;
    self.statusLabel.frame = labelFrame;

    CGRect buttonFrame = self.seeMoreButton.frame;
    buttonFrame.origin.y = labelFrame.origin.y+labelFrame.size.height+10.0f;
    self.seeMoreButton.frame = buttonFrame;

保留一个数组来存储 selectedIndexPaths

@property (nonatomic, strong) NSMutableArray *selectedIndexPaths;

计算单元格的高度

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;

    BOOL isSelected = [self.selectedIndexPaths containsObject:indexPath];

    CGFloat maxHeight = MAXFLOAT;
    CGFloat minHeight = 40.0f;

    CGFloat constrainHeight = isSelected?maxHeight:minHeight;
    CGFloat constrainWidth  = tableView.frame.size.width - 20.0f;

    NSString *text       = self.items[indexPath.row];
    CGSize constrainSize = CGSizeMake(constrainWidth, constrainHeight);
    CGSize labelSize     = [text sizeWithFont:[UIFont systemFontOfSize:15.0f]
                            constrainedToSize:constrainSize
                                lineBreakMode:NSLineBreakByCharWrapping];

    return MAX(labelSize.height+75, 100.0f);


初始化自定义显示更多TableViewCell

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

    static NSString *cellIdentifier = @"CellIdentifier";

    SMTableViewCell *cell= (SMTableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    if (cell == nil)
    
        cell = [[[NSBundle mainBundle]loadNibNamed:NSStringFromClass([SMTableViewCell class])
                                             owner:nil
                                           options:nil] lastObject];
    

    BOOL isSelected = [self.selectedIndexPaths containsObject:indexPath];
    cell.statusLabel.numberOfLines = isSelected?0:2;

    NSString *text = self.items[indexPath.row];
    cell.statusLabel.text = text;


    NSString *buttonTitle = isSelected?@"See Less":@"See More";
    [cell.seeMoreButton setTitle:buttonTitle forState:UIControlStateNormal];
    [cell.seeMoreButton addTarget:self action:@selector(seeMoreButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
    [cell.seeMoreButton setTag:indexPath.row];

    cell.selectionStyle = UITableViewCellSelectionStyleNone;

    return cell;

按钮点击事件方法

- (void)seeMoreButtonPressed:(UIButton *)button

    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:button.tag inSection:0];
    [self addOrRemoveSelectedIndexPath:indexPath];


- (void)addOrRemoveSelectedIndexPath:(NSIndexPath *)indexPath

    if (!self.selectedIndexPaths) 
        self.selectedIndexPaths = [NSMutableArray new];
    

    BOOL containsIndexPath = [self.selectedIndexPaths containsObject:indexPath];

    if (containsIndexPath) 
        [self.selectedIndexPaths removeObject:indexPath];
    else
        [self.selectedIndexPaths addObject:indexPath];
    

    [self.tableView reloadRowsAtIndexPaths:@[indexPath]
                     withRowAnimation:UITableViewRowAnimationFade];


如果单元格被选中,则会给出相同的事件

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

    [tableView deselectRowAtIndexPath:indexPath animated:YES];

    [self addOrRemoveSelectedIndexPath:indexPath];


样本Demo project link.

【讨论】:

谢谢@Vivek,您的代码正在运行。但我不明白我能做什么:/ 修复 iOS 8 中的分隔符,SMTableViewCell.m 中的call super in layoutSubviews

以上是关于IOS 7中的表格视图单元格扩展的主要内容,如果未能解决你的问题,请参考以下文章

ios的可扩展单元格表格视图最佳实践

表格视图单元格可扩展 iOS

如何在 ios 中创建可扩展的表格视图?

自动大小表格视图单元格扩展高度中的嵌套水平集合视图使集合视图滚动重置当重新加载单元格以累积行

iOS 8 中的表格视图单元格自动布局

根据iOS中的UIWebView内容计算表格单元格高度?