为什么 UITableViewCell 选择时所有背景都会消失?
我当前项目的 UITableViewCell 行为让我感到困惑。我有一个相当简单的 UITableViewCell 子类。它向基本视图添加了一些额外的元素(通过 [self.contentView addSubview:...]
并设置元素的背景颜色,使它们看起来像黑色和灰色的矩形框。
因为背景整个表格具有类似混凝土的纹理图像,每个单元格的背景都需要是透明的,即使在选择时也是如此,但在这种情况下,它应该变暗一点,以实现这种效果:
UIView *background = [[[UIView alloc] initWithFrame:self.bounds] autorelease];
background.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.6];
background.opaque = NO;
[self setSelectedBackgroundView:background];
尽管这会产生正确的背景外观,当我选择单元格时,会发生奇怪的副作用;所有其他背景都以某种方式关闭。下面的屏幕截图看起来应该是,但没有选择顶部单元格。显示黑色和灰色矩形区域,但它们消失了
谁知道发生了什么事更重要的是:我该如何纠正这个问题?
My current project's UITableViewCell behavior is baffling me. I have a fairly straightforward subclass of UITableViewCell. It adds a few extra elements to the base view (via [self.contentView addSubview:...]
and sets background colors on the elements to have them look like black and grey rectangular boxes.
Because the background of the entire table has this concrete-like texture image, each cell's background needs to be transparent, even when selected, but in that case it should darken a bit. I've set a custom semi-transparent selected background to achieve this effect:
UIView *background = [[[UIView alloc] initWithFrame:self.bounds] autorelease];
background.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.6];
background.opaque = NO;
[self setSelectedBackgroundView:background];
And although that yields the right look for the background, a weird side effect happens when I select the cell; all other backgrounds are somehow turnt off. Here's a screenshot. The bottom cell looks like it should and is not selected. The top cell is selected, but it should display the black and grey rectangular areas, yet they are gone!
Who knows what's going on here and even more important: how can I correct this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
发生的情况是 TableViewCell 内的每个子视图都将接收 setSelected 和 setHighlighted 方法。 setSelected 方法将删除背景颜色,但如果您将其设置为选定状态,它将被更正。
例如,如果这些 UILabels 作为子视图添加到您的自定义单元格中,那么您可以将其添加到 TableViewCell 实现代码的 setSelected 方法中:
其中 self.textLabel 将是上图中显示的任何标签,
我不是确定您添加所选视图的位置,我通常将其添加到 setSelected 方法中。
或者,您可以子类化 UILabel 并重写 setHighlighted 方法,如下所示:
What is happening is that each subview inside the TableViewCell will receive the setSelected and setHighlighted methods. The setSelected method will remove background colors but if you set it for the selected state it will be corrected.
For example if those are UILabels added as subviews in your customized cell, then you can add this to the setSelected method of your TableViewCell implementation code:
where self.textLabel would be whatever those labels are that are shown in the picture above
I'm not sure where your adding your selected view, I usually add it in the setSelected method.
Alternatively, you can subclass the UILabel and override the setHighlighted method like so:
如果您不知道发生了什么,那么单元格突出显示过程可能会显得复杂且令人困惑。我彻底困惑了,并做了一些广泛的实验。以下是我的发现的注释,可能会对某人有所帮助(如果有人有任何要添加或反驳的内容,请发表评论,我会尽力确认和更新)
在正常的“未选择”状态
selectedBackgroundView
是隐藏的backgroundView
是可见的(因此,只要您的 contentView 是透明的,您就会看到backgroundView
或(如果您尚未定义backgroundView
,您将看到UITableView
本身的背景颜色)选择了一个单元格,在没有任何动画的情况下立即发生以下情况:
backgroundColor
已清除(或设置为透明),标签等文本颜色更改为其选定的selectedBackgroundView
变得可见(此视图始终是单元格的完整大小(自定义框架将被忽略,如果需要,请使用子视图)。另请注意,subViews
的backgroundColor
由于某种原因未显示,可能它们像contentView
一样设置为透明)。如果您没有定义selectedBackgroundView
那么 Cocoa 将创建/插入蓝色(或灰色)渐变背景并为您显示它)backgroundView
不变当取消选择单元格,开始删除突出显示的动画:
backgroundView
再次保持不变(因此动画看起来像是selectedBackgroundView
和backgroundView
之间的交叉淡入淡出),contentView
在“未选择”状态下重绘,并且其子视图backgroundColor
再次变得可见(这可能会导致您的动画看起来很糟糕,因此建议您不要使用contentView
中的UIView.backgroundColor
)结论:
如果您需要
backgroundColor
在整个突出显示动画中持续存在,不要使用UIView
的backgroundColor
属性,而是可以尝试(可能在tableview:cellForRowAtIndexPath:
中):A CALayer和背景颜色:
或 CAGradientLayer:
我还使用了 CALayer.border 技术来提供自定义 UITableView 分隔符:
The cell highlighting process can seem complex and confusing if you don't know whats going on. I was thoroughly confused and did some extensive experimentation. Here's the notes on my findings that may help somebody (if anyone has anything to add to this or refute then please comment and I will endeavour to confirm and update)
In the normal “not selected” state
selectedBackgroundView
is HIDDENbackgroundView
is visible (so provided your contentView is transparent you see thebackgroundView
or (if you have not defined abackgroundView
you'll see the background colour of theUITableView
itself)A cell is selected, the following occurs immediately with-OUT any animation:
backgroundColor
cleared (or set to transparent), label etc text color's change to their selected colourselectedBackgroundView
becomes visible (this view is always the full size of the cell (a custom frame is ignored, use a subview if you need to). Also note thebackgroundColor
ofsubViews
are not displayed for some reason, perhaps they're set transparent like thecontentView
). If you didn't define aselectedBackgroundView
then Cocoa will create/insert the blue (or gray) gradient background and display this for you)backgroundView
is unchangedWhen the cell is deselected, an animation to remove the highlighting starts:
selectedBackgroundView
alpha property is animated from 1.0 (fully opaque) to 0.0 (fully transparent).backgroundView
is again unchanged (so the animation looks like a crossfade betweenselectedBackgroundView
andbackgroundView
)contentView
get redrawn in the "not-selected" state and its subviewbackgroundColor
's become visible again (this can cause your animation to look horrible so it is advisable that you don't useUIView.backgroundColor
in yourcontentView
)CONCLUSIONS:
If you need a
backgroundColor
to persist through out the highlight animation, don't use thebackgroundColor
property ofUIView
instead you can try (probably with-intableview:cellForRowAtIndexPath:
):A CALayer with a background color:
or a CAGradientLayer:
I've also used a CALayer.border technique to provide a custom UITableView seperator:
当您开始拖动 UITableViewCell 时,它会在其子视图上使用 0-alpha 颜色调用
setBackgroundColor:
。我通过子类化 UIView 并重写 setBackgroundColor: 来忽略 0-alpha 颜色的请求来解决这个问题。它感觉很hacky,但它比任何的其他 解决方案我已经遇到。然后,我向单元格添加一个
NonDisappearingView
并向其中添加其他子视图:或者,您可以将 cell.contentView 设为
NonDisappearingView
的实例。When you start dragging a UITableViewCell, it calls
setBackgroundColor:
on its subviews with a 0-alpha color. I worked around this by subclassing UIView and overridingsetBackgroundColor:
to ignore requests with 0-alpha colors. It feels hacky, but it's cleaner than any of the other solutions I've come across.Then, I add a
NonDisappearingView
to my cell and add other subviews to it:Alternatively, you could make cell.contentView an instance of
NonDisappearingView
.我的解决方案是保存
backgroundColor
并在 super 调用后恢复它。您还需要使用
-setHighlighted:animated:
执行相同的操作。My solution is saving the
backgroundColor
and restoring it after the super call.You also need to do the same thing with
-setHighlighted:animated:
.找到了一个非常优雅的解决方案,而不是弄乱 tableView 方法。您可以创建一个 UIView 的子类,忽略将其背景颜色设置为透明颜色。代码:
Obj-C版本类似,这里主要是想法
Found a pretty elegant solution instead of messing with the tableView methods. You can create a subclass of UIView that ignores setting its background color to clear color. Code:
Obj-C version would be similar, the main thing here is the idea
我创建了一个 UITableViewCell 类别/扩展,允许您打开和关闭此透明度“功能”。
您可以在 GitHub 上找到 KeepBackgroundCell
通过 CocoaPods 将以下行添加到 Podfile 中来安装它:
用法:
< Swift
Objective-C
I created a UITableViewCell category/extension that allows you to turn on and off this transparency "feature".
You can find KeepBackgroundCell on GitHub
Install it via CocoaPods by adding the following line to your Podfile:
Usage:
Swift
Objective-C
阅读完所有现有答案后,通过仅子类化 UITableViewCell,使用 Swift 提出了一个优雅的解决方案。
Having read through all the existing answers, came up with an elegant solution using Swift by only subclassing UITableViewCell.
我们需要做的就是重写 setSelected 方法并更改自定义 tableViewCell 类中 tableViewCell 的 selectedBackgroundView 。
我们需要在 cellForRowAtIndexPath 方法中为 tableViewCell 添加背景视图。
接下来,我重写了 setSelected 方法,如下所述。
另外需要注意的最重要的一点是更改 tableViewCell 选择样式。它不应该是 UITableViewCellSelectionStyleNone。
All we need is to override the setSelected method and change the selectedBackgroundView for the tableViewCell in the custom tableViewCell class.
We need to add the backgroundview for the tableViewCell in cellForRowAtIndexPath method.
Next I have overridden the setSelected method as mentioned below.
Also one of the most important point to be noted is to change the tableViewCell selection style. It should not be UITableViewCellSelectionStyleNone.