UIView backgroundColor disappears when UITableViewCell is selected

前端 未结 17 1107
谎友^
谎友^ 2020-11-30 17:49

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

17条回答
  •  北荒
    北荒 (楼主)
    2020-11-30 18:28

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

提交回复
热议问题