ios 选择单元格时 UITableViewCell 子视图消失

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6745919/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 20:49:05  来源:igfitidea点击:

UITableViewCell subview disappears when cell is selected

iphoneiosuitableview

提问by Cyrille

I'm implementing a color-chooser table view where the user can select amongst, say, 10 colors (depends on the product). The user can also select other options (like hard drive capacity, ...).

我正在实现一个颜色选择器表视图,用户可以在其中选择 10 种颜色(取决于产品)。用户还可以选择其他选项(如硬盘容量等)。

All color options are inside their own tableview section.

所有颜色选项都在它们自己的 tableview 部分中。

I want to display a little square on the left of the textLabel showing the actual color.

我想在显示实际颜色的 textLabel 左侧显示一个小方块。

Right now I'm adding a simple square UIView, give it the correct background color, like this :

现在我正在添加一个简单的方形 UIView,给它正确的背景颜色,如下所示:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:RMProductAttributesCellID];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:RMProductAttributesCellID] autorelease];
        cell.indentationWidth = 44 - 8;

        UIView *colorThumb = [[[UIView alloc] initWithFrame:CGRectMake(8, 8, 28, 28)] autorelease];
        colorThumb.tag = RMProductAttributesCellColorThumbTag;
        colorThumb.hidden = YES;
        [cell.contentView addSubview:colorThumb];
    }

    RMProductAttribute *attr = (RMProductAttribute *)[_product.attributes objectAtIndex:indexPath.section];
    RMProductAttributeValue *value = (RMProductAttributeValue *)[attr.values objectAtIndex:indexPath.row];
    cell.textLabel.text = value.name;
    cell.textLabel.backgroundColor = [UIColor clearColor];

    UIView *colorThumb = [cell viewWithTag:RMProductAttributesCellColorThumbTag];
    colorThumb.hidden = !attr.isColor;
    cell.indentationLevel = (attr.isColor ? 1 : 0);

    if (attr.isColor) {
        colorThumb.layer.cornerRadius = 6.0;
        colorThumb.backgroundColor = value.color;
    }

    [self updateCell:cell atIndexPath:indexPath];

    return cell;
}

This displays fine without problems.

这显示正常,没有问题。

My only problem is that when I select a "color" row, during the fade-to-blue selection animation, my custom UIView (colorThumb) is hidden. It gets visible again just after the selection/deselection animation ended, but this produces an ugly artifact.

我唯一的问题是,当我选择“颜色”行时,在淡入蓝色选择动画期间,我的自定义 UIView (colorThumb) 被隐藏。它在选择/取消选择动画结束后再次可见,但这会产生丑陋的工件。

What should I do to correct this? Don't I insert the subview at the right place?

我应该怎么做才能纠正这个问题?我不是在正确的位置插入子视图吗?

(There's nothing special in the didSelectRowAtIndexPath, I just change the cell's accessory to a checkbox or nothing, and deselect the current indexPath).

(在 didSelectRowAtIndexPath 中没有什么特别之处,我只是将单元格的附件更改为复选框或什么都没有,并取消选择当前的 indexPath)。

回答by Yatheesha B L

UITableViewCellchanges the background color of all sub views when cell is selected or highlighted ,You can Solve this problem by overriding Tableview cell's setSelected:animatedand setHighlighted:animatedand resetting view background color.

UITableViewCell选中或突出显示单元格时更改所有子视图的背景颜色,您可以通过覆盖 Tableview 单元格的setSelected:animatedsetHighlighted:animated并重置视图背景颜色来解决此问题。

In Objective C :

在目标 C 中:

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
   UIColor *color = self.yourView.backgroundColor;        
   [super setSelected:selected animated:animated];

    if (selected){
        self.yourView.backgroundColor = color;
    }
}

-(void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated{
    UIColor *color = self.yourView.backgroundColor;        
    [super setHighlighted:highlighted animated:animated];

    if (highlighted){
        self.yourView.backgroundColor = color;
    }
}

In Swift 3.1 :

在 Swift 3.1 中:

override func setSelected(_ selected: Bool, animated: Bool) {
    let color = yourView.backgroundColor         
    super.setSelected(selected, animated: animated)

    if selected {
        yourView.backgroundColor = color
    }
}

override func setHighlighted(_ highlighted: Bool, animated: Bool) {
    let color = yourView.backgroundColor
    super.setHighlighted(highlighted, animated: animated)

    if highlighted {
        yourView.backgroundColor = color
    }
}

回答by Andriy

It's because table view cell automatically changes background color of all views inside content view for highlighted state. You may consider subclassing UIViewto draw your color or using UIImageViewwith custom 1x1 px stretched image.

这是因为表格视图单元格会自动更改内容视图中所有视图的背景颜色以显示突出显示状态。您可以考虑子类化UIView以绘制颜色或使用UIImageView自定义 1x1 像素拉伸图像。

回答by Pavel Gurov

Found a pretty elegant solution instead of messing with the tableViewCell selection/highlighting methods. You can create a subclass of UIView that ignores setting its background color to clear color.

找到了一个非常优雅的解决方案,而不是搞乱 tableViewCell 选择/突出显示方法。您可以创建一个 UIView 的子类,它忽略将其背景颜色设置为清除颜色。

Swift 3/4:

斯威夫特 3/4:

class NeverClearView: UIView {
    override var backgroundColor: UIColor? {
        didSet {
            if backgroundColor != nil && backgroundColor!.cgColor.alpha == 0 {
                backgroundColor = oldValue
            }
        }
    }
}

Swift 2:

斯威夫特 2:

class NeverClearView: UIView {
    override var backgroundColor: UIColor? {
        didSet {
            if CGColorGetAlpha(backgroundColor!.CGColor) != 0 {
                backgroundColor = oldValue
            }
        }
    }
}

Obj-C version:

Obj-C 版本:

@interface NeverClearView : UIView

@end

@implementation NeverClearView

- (void)setBackgroundColor:(UIColor *)backgroundColor {
    if (CGColorGetAlpha(backgroundColor.CGColor) != 0) {
        [super setBackgroundColor:backgroundColor];
    }
}

@end

回答by swiftBoy

For Swift 2.2this works

对于Swift 2.2,这有效

cell.selectionStyle = UITableViewCellSelectionStyle.None

and reason is explained by @Andriy

@Andriy解释了原因

It's because table view cell automatically changes background color of all views inside content view for highlighted state.

这是因为表格视图单元格会自动更改内容视图中所有视图的背景颜色以显示突出显示状态。

回答by Agat

Another way to manage the problem is to fill the view with core-graphics gradient, like:

解决问题的另一种方法是使用核心图形渐变填充视图,例如:

CAGradientLayer* gr = [CAGradientLayer layer];
gr.frame = mySubview.frame;
gr.colors = [NSArray arrayWithObjects:
                     (id)[[UIColor colorWithRed:0 green:0 blue:0 alpha:.5] CGColor]
                     ,(id)[[UIColor colorWithRed:0 green:0 blue:0 alpha:.5] CGColor]
                     , nil];

gr.locations = [NSArray arrayWithObjects:[NSNumber numberWithFloat:0],[NSNumber numberWithFloat:1],nil];

[mySubview.layer insertSublayer:gr atIndex:0];

回答by Tim Bodeit

Inspired by Yatheesha B L's answerI created a UITableViewCell category/extension that allows you to turn on and off this transparency "feature".

灵感来自 Yatheesha BL答案我创建一个UITableViewCell类/扩展,使您可以打开和关闭这种透明度的‘功能’。

Swift

迅速

let cell = <Initialize Cell>
cell.keepSubviewBackground = true  // Turn  transparency "feature" off
cell.keepSubviewBackground = false // Leave transparency "feature" on

Objective-C

目标-C

UITableViewCell* cell = <Initialize Cell>
cell.keepSubviewBackground = YES;  // Turn  transparency "feature" off
cell.keepSubviewBackground = NO;   // Leave transparency "feature" on

KeepBackgroundCell is CocoaPods compatible. You can find it on GitHub

KeepBackgroundCell 与 CocoaPods 兼容。你可以在 GitHub 上找到它

回答by gumpwang

You can cell.selectionStyle = UITableViewCellSelectionStyleNone;, then set the backgroundColor at - (void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath *)indexPath

您可以cell.selectionStyle = UITableViewCellSelectionStyleNone;,然后将 backgroundColor 设置为- (void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath *)indexPath

回答by Milan Kamilya

Inspired by Yatheesha B L's answer.

灵感来自Yatheesha BL的回答。

If you call super.setSelected(selected, animated:animated), it will clear all background color you set. So, we will not callsuper method.

如果您调用 super.setSelected(selected,animated:animated),它将清除您设置的所有背景颜色。所以,我们不会调用超级方法。

In Swift :

在斯威夫特:

override func setSelected(selected: Bool, animated: Bool) {    
    if(selected)  {
        contentView.backgroundColor = UIColor.red 
    } else {
        contentView.backgroundColor = UIColor.white
    }
}

override func setHighlighted(highlighted: Bool, animated: Bool) {
    if(highlighted) {
        contentView.backgroundColor = UIColor.red 
    } else {
        contentView.backgroundColor = UIColor.white
    }
}

回答by Abo3atef

For may case, This is the Septs to avoid getting the gray color for all items in the cell (in case you are using custom table view cell):

对于可能的情况,这是避免为单元格中的所有项目获取灰色的 Septs(如果您使用自定义表格视图单元格):

  1. Set the selectionStyle to .none selectionStyle = .none

  2. Override this method.

    func setHighlighted(_ highlighted: Bool, animated: Bool)

  3. Call the super, to get the benefit of super setup.

    super.setHighlighted(highlighted, animated: animated)

  4. Do what ever highlighting logic you want.

    override func setHighlighted(_ highlighted: Bool, animated: Bool) {
          super.setHighlighted(highlighted, animated: animated)
          // Your Highlighting Logic goes here...
    }
    
  1. 将 selectionStyle 设置为 .none selectionStyle = .none

  2. 覆盖此方法。

    func setHighlighted(_highlighted: Bool, 动画: Bool)

  3. 调用超级,以获得超级设置的好处。

    super.setHighlighted(突出显示,动画:动画)

  4. 做任何你想要的突出逻辑。

    override func setHighlighted(_ highlighted: Bool, animated: Bool) {
          super.setHighlighted(highlighted, animated: animated)
          // Your Highlighting Logic goes here...
    }
    

回答by DylanVann

UITableViewCell changes the backgroundColor of all subviews on selection for some reason.

由于某种原因,UITableViewCell 会在选择时更改所有子视图的 backgroundColor。

This might help:

这可能有帮助:

DVColorLockView

DVColorLockView

Use something like that to stop UITableView from changing your view color during selection.

使用类似的东西来阻止 UITableView 在选择过程中改变你的视图颜色。