Last active
March 26, 2024 17:51
-
-
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
This file contains hidden or 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
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