Skip to content

Instantly share code, notes, and snippets.

@lukaskubanek
Last active March 26, 2024 17:51
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lukaskubanek/b3950c99405838f4972a2a79fb07040e to your computer and use it in GitHub Desktop.
Save lukaskubanek/b3950c99405838f4972a2a79fb07040e to your computer and use it in GitHub Desktop.
A workaround for fixing SwiftUI’s list row highlighting behavior by preventing unwanted delays
import InterposeKit
import SwiftUI
/// A workaround for an issue in SwiftUI related to delayed highlighting of list rows upon user
/// interaction, rendering it inconsistent with UIKit.
///
/// This fix implements the solution proposed by Léo Natan and utilizes `InterposeKit` by Peter
/// Steinberger to modify the behavior of `UICollectionViewCell` instances used internally
/// by SwiftUI.
///
/// Please be aware that this patch uses private API and might lead to rejections when used
/// in production on the App Store.
///
/// ### Usage
///
/// ```
/// @main
/// internal struct MyApp: App {
/// internal var body: some Scene {
/// WindowGroup {
/// MyView()
/// .onAppear {
/// SwiftUIListRowHighlightFix.apply()
/// }
/// }
/// }
/// }
/// ```
///
/// ### Further Resources
///
/// - [The actual workaround shared by Léo Natan](https://twitter.com/LeoNatan/status/1709222793672347809)
/// - Lukas Petr’s reports of this issue on [Mastodon](https://mastodon.social/@luksape/111141902041183627)
/// and [Twitter](https://twitter.com/luksape/status/1707113201656115342)
public enum SwiftUIListRowHighlightFix {
public static func apply() {
do {
_ = try Interpose(UICollectionViewCell.self) {
try $0.prepareHook(
Selector(("_setHighlighted:animated:")),
methodSignature: (@convention(c) (UICollectionViewCell, Selector, Bool, Bool) -> Void).self,
hookSignature: (@convention(block) (UICollectionViewCell, Bool, Bool) -> Void).self
) { hook in
return { `self`, highlighted, animated in
var animated = animated
if NSStringFromClass(type(of: self)).hasPrefix("SwiftUI.") {
animated = true
}
hook.original(self, hook.selector, highlighted, animated)
}
}
}
} catch {
assertionFailure(
"""
\(SwiftUIListRowHighlightFix.self): Unable to apply fix for SwiftUI’s list row
highlight behavior.
"""
)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment