我在接口构建器中有一个简单的tableViewCell构建。它包含一个UIView,其中包含一个图像。现在,当我选择单元格时,将显示默认的蓝色选择背景,但是UIView的backgroundColor消失了。
我的UITableViewCell的实现文件没有做任何特殊的事情。它只是init的&返回self,而我在setSelected中所做的就是调用super。
如何让我的UIView的backgroundColor时选择的tableView时,说明了什么?
我在接口构建器中有一个简单的tableViewCell构建。它包含一个UIView,其中包含一个图像。现在,当我选择单元格时,将显示默认的蓝色选择背景,但是UIView的backgroundColor消失了。
我的UITableViewCell的实现文件没有做任何特殊的事情。它只是init的&返回self,而我在setSelected中所做的就是调用super。
如何让我的UIView的backgroundColor时选择的tableView时,说明了什么?
Answers:
这里的问题是[super]实现
- (void) setSelected:(BOOL) selected animated:(BOOL) animated;
将UITableViewCell中的所有背景色设置为rgba(0,0,0,0)。为什么?也许让我们都汗流sweat背?
并不是整个视图都会消失(事实证明,如果您更改视图图层边框属性,这些属性将保留)
这是触摸单元格所产生的函数调用顺序
所以你的选择是
不幸的是,在setHighlighted中重新声明背景色没有任何作用,因为在第一次调用setSelected之前将所有背景色设置为[r:0 b:0 g:0 a:0]之前会调用setHighlighted。
// TODO:给出有关如何覆盖setSelected(敬请期待)的详细说明
selectionStyle
为UITableViewCellSelectionStyleNone
,并且不会清除背景。唯一的缺点是它将忽略该selectedBackgroundView
属性。
- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated
{
UIColor *backgroundColor = self.channelImageView.backgroundColor;
[super setHighlighted:highlighted animated:animated];
self.channelImageView.backgroundColor = backgroundColor;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
UIColor *backgroundColor = self.channelImageView.backgroundColor;
[super setSelected:selected animated:animated];
self.channelImageView.backgroundColor = backgroundColor;
}
UITableViewCell
选择您的状态时,应注意两种状态:Highlighted
和Selected
。
因此,对于您具有作为的子类的自定义单元格类的方案UITableViewCell
,您可以轻松地覆盖这两种方法来避免这种情况(快速):
class MyCell: UITableViewCell {
@IBOutlet var myView: UIView!
override func setHighlighted(highlighted: Bool, animated: Bool) {
let myViewBackgroundColor = myView.backgroundColor
super.setHighlighted(highlighted, animated: animated)
myView.backgroundColor = myViewBackgroundColor
}
override func setSelected(selected: Bool, animated: Bool) {
let myViewBackgroundColor = myView.backgroundColor
super.setSelected(selected, animated: animated)
myView.backgroundColor = myViewBackgroundColor
}
}
以前我已经按照@ P5ycH0所说的进行操作(拉伸了1x1图像),但是在@Brooks之后,我发现-(void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated
在自定义UITableViewCell
实现中进行覆盖并在调用后重置背景颜色会在[super setHighlighted:highlighted animated:animated];
选中/突出显示单元格时保持我的背景颜色
-(void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated {
[super setHighlighted:highlighted animated:animated];
myView.backgroundColor = myColor;
}
setHighlighted
是创建函数选定单元格时添加自定义行为,顺便说一句好工作
这个问题可以(最终)在iOS 13中得到解决。在iOS 13 beta 3发行说明中找到了这一甜蜜的段落。
当单元格变为突出显示或选中状态时,UITableViewCell类不再更改contentView及其任何子视图的backgroundColor或isOpaque属性。如果要在contentView内部(包括其中)的单元格的任何子视图上设置不透明的backgroundColor,则该单元格变为突出显示或选定状态时的外观可能会受到影响。解决子视图问题的最简单方法是确保将其backgroundColor设置为nil或clear,并且其opaque属性为false。但是,如果需要,您可以覆盖setHighlighted(:animated :)和setSelected(:animated :)方法,以在移入或移出突出显示和选定状态时手动更改子视图上的这些属性。(13955336)
selectedBackgroundView
过时:(因为它可能会留隐患
好的,在选定的tableviewcell中,失去UIView类的背景色是正常现象。我不知道如何防止这种情况。现在,我刚刚将UIView替换为包含拉伸的1x1白色像素的UIImageView。丑陋的imo,但它可以工作。
您需要在自定义单元格中覆盖以下两个方法:
- (void) setSelected:(BOOL)selected animated:(BOOL)animated;
- (void) setHighlighted:(BOOL)highlighted animated:(BOOL)animated;
注意:
[super setSelected:animated:]
和[super setHighlighted:animated:]
;UITableViewCellSelectionStyleNone
为自定义单元格设置selectionStyle,以禁用任何默认UITableViewCell
样式;这里是实现的例子:
- (void) setHighlighted:(BOOL)highlighted animated:(BOOL)animated
{
[super setHighlighted:highlighted animated:animated];
[self setHighlightedSelected:highlighted animated:animated];
}
- (void) setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
[self setHighlightedSelected:selected animated:animated];
}
- (void) setHighlightedSelected:(BOOL)selected animated:(BOOL)animated
{
void(^selection_block)(void) =
^
{
self.contentView.backgroundColor = selected ? SELECTED_BACKGROUND_COLOR : NORMAL_BACKGROUND_COLOR;
};
if(animated)
{
[UIView animateWithDuration:SELECTION_ANIMATION_DURATION
delay:0.0
options:UIViewAnimationOptionBeginFromCurrentState
animations:selection_block
completion:NULL];
}
else
selection_block();
}
该contentView
是的财产UITableViewCell
是出现在iOS的7需要注意的是,你可以用自己的细胞的子视图或观点,而不是它。
将此添加到您的UITableViewCell
override func setHighlighted(highlighted: Bool, animated: Bool) {
super.setHighlighted(false, animated: animated)
if highlighted {
self.backgroundColor = UIColor.blueColor()
}else{
UIView.animateWithDuration(0.2, animations: {
self.backgroundColor = UIColor.clearColor()
})
}
}
与@Brooks的答案相关,这是我为使其在Swift和iOS8 / iOS9中工作所做的工作。
setSelected
和setHighlighted
contentView.backgroundColor
,因为它不必跨越单元格(即附件)的整个宽度。使用backgroundColor
单元格本身的,并进行相应设置。
class AwesomeTableViewCell: UITableViewCell {
private struct Constants {
static var highlightedColor = UIColor.greenColor()
static var selectedColor = UIColor.redColor()
static let animationTime = NSTimeInterval(0.2)
}
override func awakeFromNib() {
super.awakeFromNib()
contentView.backgroundColor = UIColor.clearColor()
backgroundColor = AppContext.sharedInstance.theme.colors.background
}
override func setHighlighted(highlighted: Bool, animated: Bool) {
if animated {
UIView.animateWithDuration(Constants.animationTime, animations: { () -> Void in
self.setHighlighted(highlighted)
})
} else {
self.setHighlighted(highlighted)
}
}
override func setSelected(selected: Bool, animated: Bool) {
if animated {
UIView.animateWithDuration(Constants.animationTime, animations: { () -> Void in
self.setSelected(selected)
})
} else {
self.setSelected(selected)
}
}
private func setHighlighted(highlighted: Bool) {
backgroundColor = highlighted ? Constants.highlightedColor : UIColor.whiteColor()
}
private func setSelected(selected: Bool) {
backgroundColor = selected ? Constants.selectedColor : UIColor.whiteColor()
}
}
概要
此解决方案使您可以锁定单元格的某些背景色,而其余部分则由系统行为控制。
根据mientus的回答,我创建了一个解决方案,可让您指定哪些视图应保留其背景色。
这仍然允许其他单元格子视图在突出显示/选择时移除其背景,并且是在我们的情况下唯一可行的解决方案(两个视图需要永久的背景)。
我使用了一种面向协议的方法,该BackgroundLockable
协议包含要锁定的视图列表,并在保持颜色的同时运行闭包:
protocol BackgroundLockable {
var lockedBackgroundViews: [UIView] { get }
func performActionWithLockedViews(_ action: @escaping () -> Void)
}
extension BackgroundLockable {
func performActionWithLockedViews(_ action: @escaping () -> Void) {
let lockedViewToColorMap = lockedBackgroundViews.reduce([:]) { (partialResult, view) -> [UIView: UIColor?] in
var mutableResult = partialResult
mutableResult[view] = view.backgroundColor
return mutableResult
}
action()
lockedViewToColorMap.forEach { (view: UIView, color: UIColor?) in
view.backgroundColor = color
}
}
}
然后,我有一个的子类UITableViewCell
,该子类将覆盖突出显示和选择,以围绕调用默认(超级)行为来运行协议的闭包:
class LockableBackgroundTableViewCell: UITableViewCell, BackgroundLockable {
var lockedBackgroundViews: [UIView] {
return []
}
override func setHighlighted(_ highlighted: Bool, animated: Bool) {
performActionWithLockedViews {
super.setHighlighted(highlighted, animated: animated)
}
}
override func setSelected(_ selected: Bool, animated: Bool) {
performActionWithLockedViews {
super.setSelected(selected, animated: animated)
}
}
}
现在,我只需要在单元格类中子类化LockableBackgroundTableViewCell
或使用BackgroundLockable
协议即可轻松地向某些单元格添加锁定行为!
class SomeCell: LockableBackgroundTableViewCell {
@IBOutlet weak var label: UILabel!
@IBOutlet weak var icon: UIImageView!
@IBOutlet weak var button: UIButton!
override var lockedBackgroundViews: [UIView] {
return [label, icon]
}
}
从您说过您使用IB构建了tableViewCell之后,我想检查您是否将视图添加contentView
为UITableViewCell的子视图,而不是添加view
。内容视图是单元格显示的内容的默认超级视图。
从参考:
UITableViewCell对象的内容视图是单元格显示的内容的默认超级视图。如果要仅通过添加其他视图来自定义单元格,则应将其添加到内容视图中,以便在单元格进入和退出编辑模式时它们的位置适当。
您可以通过重写UITableViewCell类中的setHighlighted函数来更改tableViewCell的行为(您需要从该类继承)。我的代码示例,其中我更改了单元格的背景图像:
// animate between regular and highlighted state
- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated; {
[super setHighlighted:highlighted animated:animated];
//Set the correct background Image
UIImageView* backgroundPicture = (UIImageView*)[self viewWithTag:HACK_BACKGROUND_VIEW_TAG];
if (highlighted) {
backgroundPicture.image = [UIImage imageNamed:@"FondSelected.png"];
}
else {
backgroundPicture.image = [UIImage imageNamed:@"Fond.png"];
}
}
您还可以在界面构建器中将选择模式更改为灰色,蓝色或不选择任何模式。
在iOS 7中,对我有用的是setSelected:animated:
在UITableViewCell
子类中进行覆盖,但与@Brooks的技巧相反,我叫[super setSelected:selected animated:animated]
。
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Reassert the background color of the color view so that it shows
// even when the cell is highlighted for selection.
self.colorView.backgroundColor = [UIColor blueColor];
}
这样,当用户点击单元格时,我就可以保留系统的默认选择动画,也可以在表视图委托的中取消选择它didSelectRowAtIndexPath:
。
只是花了一些时间在这个奇怪的问题上。选择行时,我不想设置UITableViewCellSelectionStyleNone样式来保留漂亮的动画。但是没有任何建议的想法对我有用-我试图覆盖setSelected和setHighlighted并在那里设置我的子视图backgroundColor-它一直由iOS重置并且仍然闪烁(新颜色->旧颜色)。对我来说,解决方法非常简单。当我的行被选中时,另一个视图控制器被推入,用户在该屏幕上选择某个选项,并在我根据用户选择更改颜色的地方调用了委托。在此代表中,我只为我的单元格执行[cell setSelected:NO animation:NO]。(我有静态的UITableViewController并有单元的出口)。您可能可以在didSelect方法中取消选择单元格,但就我而言,我使用的是segues。
这是我的看法。我有一个子类,我的所有单元格都继承自该子类,所以这就是避免UIImageViews背景更改的方式:
override func setHighlighted(highlighted: Bool, animated: Bool) {
var backgroundColors = [UIView: UIColor]()
for view in contentView.subviews as [UIView] {
if let imageView = view as? UIImageView {
backgroundColors[imageView] = imageView.backgroundColor
}
}
super.setHighlighted(highlighted, animated: animated)
for view in contentView.subviews as [UIView] {
if let imageView = view as? UIImageView {
imageView.backgroundColor = backgroundColors[imageView]
}
}
}
override func setSelected(selected: Bool, animated: Bool) {
var backgroundColors = [UIView: UIColor]()
for view in contentView.subviews as [UIView] {
if let imageView = view as? UIImageView {
backgroundColors[imageView] = imageView.backgroundColor
}
}
super.setSelected(selected, animated: animated)
for view in contentView.subviews as [UIView] {
if let imageView = view as? UIImageView {
imageView.backgroundColor = backgroundColors[imageView]
}
}
}
这将自动解决所有问题UIImageView
。