I am using AsyndDisplayKit/Texture where:
ASTextNode has this function:
+ (CGColorRef)_highlightColorForStyle:(ASTextNodeHighlightStyle)style
{
return [UIColor colorWithWhite:(style == ASTextNodeHighlightStyleLight ? 0.0 : 1.0) alpha:1.0].CGColor;
}
Unfortunately, it's not exposed. So I am unable to change the highlight color. So I am trying to swizzle it using this:
extension ASTextNode {
@objc func swizzledHighlightColor() -> CGColor {
return UIColor.red.cgColor
}
static func swizzle() {
let originalSelector = NSSelectorFromString("_highlightColorForStyle:")
let swizzledSelector = #selector(ASTextNode.swizzledHighlightColor)
print("originalSelector: \(originalSelector)")
print("swizzledSelector: \(swizzledSelector)")
let originalMethod = class_getInstanceMethod(self, originalSelector)
let swizzledMethod = class_getInstanceMethod(self, swizzledSelector)
print("originalMethod: \(String(describing: originalMethod))")
print("swizzledMethod: \(String(describing: swizzledMethod))")
if let originalMethod = originalMethod, let swizzledMethod = swizzledMethod {
method_exchangeImplementations(originalMethod, swizzledMethod)
}
}
}
Here, method_exchangeImplementations
fails because the originalMethod
gotten by class_getInstanceMethod
is returning nil. The output of above is:
originalSelector: _highlightColorForStyle:
swizzledSelector: swizzledHighlightColor
originalMethod: nil
swizzledMethod: Optional(0x00000001046b5e09)
To debug, I printed this and it does work:
let selectorPerformed = ASTextNode.perform(originalSelector)
print("selectorPerformed: \(String(describing: selectorPerformed))")
prints:
selectorPerformed: Optional(Swift.Unmanaged<Swift.AnyObject>(_value: <CGColor 0x30333c8c0> [<CGColorSpace 0x303430120> (kCGColorSpaceICCBased; kCGColorSpaceModelMonochrome; Generic Gray Gamma 2.2 Profile; extended range)] ( 1 1 )))
So, the originalSelector
is correct. Why's class_getInstanceMethod
failing then?
EDIT: I figured out the problem. I posted solution below.
Nvm, I figured out the solution. I was mistakenly using class_getInstanceMethod
.
I needed to use class_getClassMethod
instead because it's not a instance method.
Here's the working solution:
extension ASTextNode {
@objc static func swizzledHighlightColor() -> CGColor {
return UIColor.red.cgColor
}
static func swizzle() {
let originalSelector = NSSelectorFromString("_highlightColorForStyle:")
let swizzledSelector = #selector(ASTextNode.swizzledHighlightColor)
print("originalSelector: \(originalSelector)")
print("swizzledSelector: \(swizzledSelector)")
let originalMethod = class_getClassMethod(self, originalSelector)
let swizzledMethod = class_getClassMethod(self, swizzledSelector)
print("originalMethod: \(String(describing: originalMethod))")
print("swizzledMethod: \(String(describing: swizzledMethod))")
if let originalMethod = originalMethod, let swizzledMethod = swizzledMethod {
method_exchangeImplementations(originalMethod, swizzledMethod)
}
let selectorPerformed = ASTextNode.perform(originalSelector)
print("selectorPerformed: \(String(describing: selectorPerformed))")
}
}