In a UICollectionView
within a UISplitViewController
layout, I have a UICollectionView.CellRegistration
that shows under certain conditions a warning badge as UICellAccessory
.
This warning badge accessory is based on the following code:
func warningBadge(cell: UICollectionViewListCell) -> UICellAccessory {
return UICellAccessory.customView(configuration:
.init(customView: UIImageView(image: UIImage(systemName: "exclamationmark.triangle")),
placement: .trailing(),
reservedLayoutWidth: .custom(18),
tintColor: UIColor(dynamicProvider: { collection in
if cell.isSelected {
return .lightText
}
else {
return .systemRed
}
})))
}
This works fine, except when the focus in the app moves to another part in the Split View control.
In that case the selected cell show a light grey background, instead of a tintColor background (which is correct), but the warning badge still has a selected appearance, which makes it hard to see (lightText on top of light grey background).
In case when the cell is selected but not focused, the image should have the non selected tintColor (.systemRed
in this example code).
I tried to use cell.isFocused
instead of, or in addition to cell.isSelected
, but this doesn't work.
Interestingly, cell.isFocused
does work correctly for UICellAccessory.label
accessories, but apparently not for a UICellAccessory.customView
with an image control.
How to give a custom accessory the correct tintColor when the cell is selected, but not focused?
The solution turned out to make a custom view based on UILabel
instead of UIImageView
. Normally you don't need a custom view for a label accessory, but I already have a UICellAccessory.label
in my cell registration, and you're not allowed to use system accessory twice.
This is the working code I now use:
func warningBadge(cell: UICollectionViewListCell) -> UICellAccessory {
let label = UILabel()
let attachment = NSTextAttachment()
attachment.image = UIImage(systemName: "exclamationmark.triangle")?.withTintColor( UIColor(dynamicProvider: { collection in
return cell.isFocused ? .lightText : .systemRed
}))
label.attributedText = NSAttributedString(attachment: attachment)
return UICellAccessory.customView(configuration: .init(customView: label, placement: .trailing(), reservedLayoutWidth: .custom(18)))
}