选择时将子视图添加到 UITableViewCell

Posted

技术标签:

【中文标题】选择时将子视图添加到 UITableViewCell【英文标题】:Add subview to UITableViewCell on selection 【发布时间】:2014-05-21 14:28:16 【问题描述】:

我正在尝试添加一个应该删除文本的 UIView(不要担心水平错位)。

但是,在选择行时,该行在下面添加了几行。为什么?

这是我的代码:

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

    NSLog(@"%@", indexPath);

    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    UILabel *label = cell.textLabel;

    CGSize textSize = [[label text] sizeWithAttributes:@NSFontAttributeName:[label font]];
    CGFloat strikeWidth = textSize.width;

    UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(self.view.bounds.size.height / 2, 200, strikeWidth, 2)];
    lineView.backgroundColor = [UIColor redColor];

    lineView.tag = 100;

    [cell.contentView addSubview:lineView];

【问题讨论】:

【参考方案1】:

您应该使用NSAttributedString 作为单元格文本并使用NSStrikethroughStyleAttributeName 删除,而不是使用 UIView 并向单元格添加子视图。删除线颜色使用NSStrikethroughColorAttributeName

【讨论】:

这只会在选择单元格时设置属性文本(当您的手指放在单元格上时)。移开手指后,删除线将被删除。我必须从使用cell.textLabel.text 切换到cell.textLabel.attributedText 吗? 是的,你应该设置你的 UILabel 的属性文本属性(大概在tableView:cellForRowAtIndexPath:,创建单元格的地方)。 我发现了问题。我没有更新核心数据,[tableView reloadData] 运行 cellForRowAtIndexPath 运行 [self configureCell] 我设置了 cell.textLabel.text :)【参考方案2】:

你的问题在这里:

UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(self.view.bounds.size.height / 2, 200, strikeWidth, 2)];

在这种情况下,“self”是 tableViewController,而不是标签或单元格。您正在做的是将视图的 x 原点设置为屏幕 height 的一半,y 原点向下 200 点,宽度为 strikeWidth 和高度2 个。

因为您要添加的线视图将成为单元格的子视图,所以您总是希望框架相对于它的超级视图,在本例中是单元格本身。您可能希望使用类似于以下内容的内容:

CGRectMake(CGRectGetMinX(cell.textLabel.frame), CGRectGetHeight(cell.contentView.frame) / 2, strikeWidth, 2)

您可能想要调整值以使其对齐,但您明白了...

编辑:添加了更好的框架,这里有更多代码可以很好地做到这一点:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
    [tableView deselectRowAtIndexPath:indexPath animated:YES];

    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    UILabel *label = cell.textLabel;

    CGSize textSize = [[label text] sizeWithAttributes:@NSFontAttributeName:[label font]];
    CGFloat strikeWidth = textSize.width;

    UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(CGRectGetMinX(label.frame), CGRectGetHeight(cell.contentView.frame) / 2, strikeWidth, 2)];
    lineView.backgroundColor = [UIColor redColor];
    [cell.contentView addSubview:lineView];

    [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];

【讨论】:

我认为你是对的,但 self 是 tableView 可能是错误的。 不,self 是 tableView。 真的吗?您认为这个 tableview 委托代码出现在哪个类中? 不,self绝对不是tableView,是视图控制器。 对不起,我的意思是表视图控制器。【参考方案3】:

我认为您的线条出现在您的单元格之外,因为您在框架中设置了 200 的 y 原点,这看起来相当高。

此外,如果您想在 UITableviewCell 中使用删除线,则最好不要这样做,因为在多选时,此“删除线视图”将被添加多次,并且永远不会被删除。同样在tableview上reloadData,或者滚动单元格被重用了,你不希望看到这些删除线视图随机显示。

这里有两种正确的方法:

使用 NSAttributedString 框架。基本上 if 允许你对一个字符串做各种各样的事情,比如设置颜色、背景颜色、段落样式,还可以删除。 这是我将在 didSelect 委托方法中写的内容:

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

UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSString *string = cell.textLabel.text;

NSDictionary *attributes = @NSStrikethroughStyleAttributeName: @(NSUnderlineStyleThick);
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:string attributes:attributes];
cell.textLabel.attributedText = attributedString; 

另一种解决方案是在 UICollectionViewCell 上添加一个类别并在其中实现“setStrikeTrough”方法。

希望对您有所帮助。

【讨论】:

很好的解决方案,我唯一要改变的是,我将在 UICollectionViewCell 上创建一个类别,而不是 UICollectionViewCell 的子类。 你说得对,因为它只是一种方法,所以要简单得多。我会进行编辑。

以上是关于选择时将子视图添加到 UITableViewCell的主要内容,如果未能解决你的问题,请参考以下文章

将子视图添加到视图控制器

将子视图添加到选定的表格视图单元格

将子视图添加到 UITableViewCell 问题

在 Swift 中选择时如何将子视图置于前面?

如何在不丢失导航栏的情况下将子视图添加到 UINavigation 控制器?

在Subview位置选择滚动视图子视图滚动