iPhone - 使用自定义单元格扩展 UITableView 并在选择时隐藏/显示标签

发布于 2024-11-16 17:40:29 字数 3368 浏览 4 评论 0原文

  • 我在 UIView 中有一个 UITableView
  • 表格视图的单元格是自定义的,因此由 UITableViewCell 类管理

我需要在选择时展开/收缩单元格,这是我使用很棒的教程 此处。但是,我还需要在选择时显示/隐藏 UILabels - 就像详细视图一样,当您展开单元格时,会显示更多标签;将其收缩回原来的大小,并且这些标签再次被隐藏。

基本上:
点击
延长细胞长度
显示标签

再次单击
合同细胞
隐藏标签

一次仅打开 1 个单元格

这一切听起来很简单,但是网络上普遍使用的方法(我上面链接到的教程)会在第一次触摸时自动取消选择其单元格,这意味着我隐藏的 UILabels 永远没有机会出现。

如果我

[tableView deselectRowAtIndexPath:indexPath animated:TRUE];

从 didSelectRowAtIndexPath 中删除,我可以让隐藏标签出现,但它当然不会消失,因为在我选择不同的单元格之前,该单元格不会被取消选择。

我怎样才能使单元格在用户第二次单击它后返回到其常规高度后自动取消选择?另外,有没有一种方法可以将表格一次限制为只能展开一个单元格,因为现在您可以完全展开所有单元格。我希望扩展 Cell2 能够自动将 Cell1 缩小回原来的高度。

谢谢大家;有时不知道如果没有 Stack Overflow 我会做什么。

TableViewController.h

@interface TableViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> {
    IBOutlet UITableView *tableView;
    NSMutableDictionary *selectedIndexes;
}
@end

TableViewController.m 中的相关代码

@interface TableViewController (private)

- (BOOL)cellIsSelected:(NSIndexPath *)indexPath;

@end

@implementation TableViewController

#define kCellHeight 50.0

- (void)viewDidLoad {
    [super viewDidLoad];

    selectedIndexes = [[NSMutableDictionary alloc] init];
}


- (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];
}


- (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];

    }

    return cell;
}

#pragma mark -
#pragma mark Tableview Delegate Methods

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    // Deselect cell
    [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...
    [tableView beginUpdates];
    [tableView endUpdates];
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    // If our cell is selected, return double height
    if([self cellIsSelected:indexPath]) {
        return kCellHeight * 2.0;
    }

    // Cell isn't selected so return single height
    return kCellHeight;
}

@end

此外,UITableCell 类中的 UILabels:

    - (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];
    if (selected == YES){
        date.hidden = NO;   
    }   
    else if (selected == NO) {
        date.hidden = YES;
    }
}
  • I have a UITableView within a UIView
  • The table view's cells are custom, and thus managed by a UITableViewCell class

I need to expand/contract cells upon selection, which I have done using the awesome tutorial here. However, I also need to show/hide UILabels upon selection--like a detail view, as you expand the cell, more labels are shown; contract it back to its original size, and those labels are again hidden.

Basically:
Click
Extend length of cell
Show labels

Click again
Contract cell
Hide labels

Only 1 cell open at a time

This all sounds easy enough, but the method prevalently used across the web (the tutorial I linked to above) automatically deselects its cells upon the first touch, which means my hidden UILabels never get a chance to show up.

If I remove

[tableView deselectRowAtIndexPath:indexPath animated:TRUE];

from didSelectRowAtIndexPath, I can get the hidden label to appear, but it does not disappear of course, as the cell does not get deselected until I select a different cell.

How might I make it so that the cell automatically deselects once it returns to its regular height after a user clicks it for the second time? Also, is there a way to limit the table to only one expanded cell at a time because right now, you can fully expand all cells. I'd like it if expanding Cell2 automatically shrunk Cell1 back to its original height.

Thanks all; don't know what I'd do without Stack Overflow at times.

TableViewController.h

@interface TableViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> {
    IBOutlet UITableView *tableView;
    NSMutableDictionary *selectedIndexes;
}
@end

Relevant code from TableViewController.m

@interface TableViewController (private)

- (BOOL)cellIsSelected:(NSIndexPath *)indexPath;

@end

@implementation TableViewController

#define kCellHeight 50.0

- (void)viewDidLoad {
    [super viewDidLoad];

    selectedIndexes = [[NSMutableDictionary alloc] init];
}


- (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];
}


- (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];

    }

    return cell;
}

#pragma mark -
#pragma mark Tableview Delegate Methods

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    // Deselect cell
    [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...
    [tableView beginUpdates];
    [tableView endUpdates];
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    // If our cell is selected, return double height
    if([self cellIsSelected:indexPath]) {
        return kCellHeight * 2.0;
    }

    // Cell isn't selected so return single height
    return kCellHeight;
}

@end

Also, the UILabels from the UITableCell class:

    - (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];
    if (selected == YES){
        date.hidden = NO;   
    }   
    else if (selected == NO) {
        date.hidden = YES;
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

唐婉 2024-11-23 17:40:29

我是个白痴。最简单的解决方案总是最好的,这就是一行代码:

 self.contentView.clipsToBounds = YES;

当您设置单元格并将其布局时。

呃。

And I'm an idiot. The simplest solution is always the best, and this one is one line of code:

 self.contentView.clipsToBounds = YES;

when you setup your cell and lay it out.

Duh.

时光磨忆 2024-11-23 17:40:29
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
if (selected == YES){
    date.hidden = NO;   
}   
else if (selected == NO) {
    date.hidden = YES;
}

无法正常工作,因为您取消选择单元格,因此选择的 BOOL 始终为 NO ;)
所以,data.hidden = YES,永远......

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
if (selected == YES){
    date.hidden = NO;   
}   
else if (selected == NO) {
    date.hidden = YES;
}

Does not works correctly, because you deselect cell, so BOOL selected is always NO ;)
So, data.hidden = YES, forever...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文