UIView backgroundColor disappears when UITableView

2019-01-08 04:03发布

I have a simple tableViewCell build in interface builder. It contains a UIView which contains an image. Now, when I select the cell, the default blue selection background is shown, but the backgroundColor of my UIView is gone.

My UITableViewCell's implementation file doesn't do anything special. It just init's & returns self and all I do in setSelected is call super.

How do I get my UIView backgroundColor to show when the tableView is selected?

16条回答
\"骚年 ilove
2楼-- · 2019-01-08 04:48

Summary

This solution let's you lock some of a cell's background colors, while the remainder are controlled by system behaviour.


Based on mientus' answer, I have created a solution which allows you to specify which views should keep their background color.

This still allows other cell subviews to have their background removed on highlighting/selection, and is the only solution which works in our case (two views needing a permanent background).

I used a protocol-oriented approach, with a BackgroundLockable protocol containing the list of views to lock, and running a closure while keeping the colors:

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
        }
    }
}

Then I have a subclass of UITableViewCell, which overrides highlighting and selection to run the protocol's closure around calling the default (super) behaviour:

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)
       }
    }
}

Now I just have to subclass LockableBackgroundTableViewCell or use the BackgroundLockable protocol in a cell class to easily add locking behaviour to some cells!

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]
    }
}
查看更多
放荡不羁爱自由
3楼-- · 2019-01-08 04:49

Ok, loosing the background color of a UIView class is normal behavior when its in a selected tableviewcell. I couldn't figure out how to prevent that. Now I've just replaced the UIView with an UIImageView containing a stretched 1x1 white pixel. Ugly imo, but it works.

查看更多
我欲成王,谁敢阻挡
4楼-- · 2019-01-08 04:51

Brooks has a great explanation for why this happens, but I think I have a better solution.

In your subview, override setBackgroundColor: to what ever color you want. The setter will still be called, but only your color specified will be enforced.

- (void)setBackgroundColor:(UIColor *)backgroundColor {
    [super setBackgroundColor:[UIColor whiteColor]];
}
查看更多
相关推荐>>
5楼-- · 2019-01-08 04:52

Add this to your 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()
        })
    }
}
查看更多
登录 后发表回答