Last active
June 5, 2024 18:20
-
-
Save juanarzola/ca46d94f5ba6a884b697448e29ada31a to your computer and use it in GitHub Desktop.
Workaround for lack of `listRowSelectedBackground` or some way of defining an adaptive background style with your own color
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct ContentView: View { | |
var body: some View { | |
List { | |
SomeRow() | |
// set the background of the row | |
.listRowBackground(ListRowBackground()) | |
// .listRowSelectedBackground(ListRowSelectedBackground()) | |
// Oh no, `listRowSelectedBackground` above is not a real API, so list cells don't highlight when selected anymore. | |
// What do we do now? | |
// Traverse the UIKit hierarchy and configure cells in it within `ListRowBackground`. | |
} | |
} | |
} | |
// A background view that traverses the hierarchy to setup the underlying List's UIKit UICollectionViewCell | |
@MainActor | |
private struct ListRowBackground: UIViewRepresentable { | |
func makeUIView(context: Context) -> SelectableBackgroundView { | |
let selectableView = SelectableBackgroundView() | |
return selectableView | |
} | |
func updateUIView(_ selectableView: SelectableBackgroundView, context: Context) { | |
// theme has styles | |
let theme = context.environment.theme | |
selectableView.backgroundColor = UIColor(theme.groupedlListItemBackgroundColor) | |
selectableView.selectedBackgroundColor = UIColor(theme.groupedlListItemSelectedBackgroundColor) | |
} | |
} | |
private class SelectableBackgroundView: UIView { | |
var selectedBackgroundColor: UIColor? = nil { | |
didSet { | |
if selectedBackgroundColor != oldValue { | |
updateCellBackground() | |
} | |
} | |
} | |
override func didMoveToWindow() { | |
super.didMoveToWindow() | |
// the background view should be installed on the cell at this point | |
updateCellBackground() | |
} | |
func updateCellBackground() { | |
guard let cell = firstSuperview(of: UICollectionViewCell.self) else { | |
return | |
} | |
let selectedBackgroundView = UIView() | |
selectedBackgroundView.backgroundColor = selectedBackgroundColor | |
cell.backgroundColor = backgroundColor | |
cell.selectedBackgroundView = selectedBackgroundView | |
} | |
} | |
// hierarchy-traversal utility | |
extension UIView { | |
func firstSuperview<T: UIView>(of clazz: T.Type) -> T? { | |
guard let superview else { return nil } | |
if superview.isKind(of: clazz) { | |
return superview as? T | |
} | |
return superview.firstSuperview(of: clazz) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment