Last active
August 13, 2018 15:20
-
-
Save colejd/e41fc68f8335670999a7859df0d6fa93 to your computer and use it in GitHub Desktop.
Swizzles in a randomized color block in place of the cgColor getter on UIColor, randomizing every color throughout the app.
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
import Foundation | |
/* | |
██████╗ █████╗ ███╗ ██╗ ██████╗ ███████╗██████╗ ███████╗ ██████╗ ███╗ ██╗███████╗ | |
██╔══██╗██╔══██╗████╗ ██║██╔════╝ ██╔════╝██╔══██╗ ╚══███╔╝██╔═══██╗████╗ ██║██╔════╝ | |
██║ ██║███████║██╔██╗ ██║██║ ███╗█████╗ ██████╔╝ ███╔╝ ██║ ██║██╔██╗ ██║█████╗ | |
██║ ██║██╔══██║██║╚██╗██║██║ ██║██╔══╝ ██╔══██╗ ███╔╝ ██║ ██║██║╚██╗██║██╔══╝ | |
██████╔╝██║ ██║██║ ╚████║╚██████╔╝███████╗██║ ██║ ███████╗╚██████╔╝██║ ╚████║███████╗ | |
╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝ ╚══════╝ ╚═════╝ ╚═╝ ╚═══╝╚══════╝ | |
*/ | |
public extension UIColor { | |
private struct StaticVars { | |
static let randomColorBlock: @convention(block) (AnyObject?) -> CGColor = { _ -> (CGColor) in | |
return CGColor(colorSpace: CGColorSpaceCreateDeviceRGB(), components: [ | |
CGFloat(Float(arc4random()) / Float(UINT32_MAX)), // R | |
CGFloat(Float(arc4random()) / Float(UINT32_MAX)), // G | |
CGFloat(Float(arc4random()) / Float(UINT32_MAX)), // B | |
1.0, // A | |
])! | |
} | |
} | |
private static let rzl_swizzleImplementation: Void = { | |
func isClassSubclassOf(_ base: AnyClass?, superclass: AnyClass) -> Bool { | |
var _class: AnyClass? = base | |
while _class != nil && _class != superclass { | |
_class = class_getSuperclass(_class) | |
} | |
return _class == superclass | |
} | |
var classCount = objc_getClassList(nil, 0) | |
var allClasses = UnsafeMutablePointer<AnyClass?>.allocate(capacity: Int(classCount)) | |
var autoreleasingAllClasses = AutoreleasingUnsafeMutablePointer<AnyClass?>(allClasses) | |
classCount = objc_getClassList(autoreleasingAllClasses, classCount) | |
for i in 0 ..< classCount { | |
if let currentClass: AnyClass = allClasses[Int(i)], | |
isClassSubclassOf(currentClass, superclass: UIColor.self), | |
let originalMethod = class_getInstanceMethod(currentClass.self, #selector(getter: cgColor)) { | |
method_setImplementation(originalMethod, imp_implementationWithBlock( | |
unsafeBitCast(StaticVars.randomColorBlock, to: AnyObject.self))) | |
} | |
} | |
}() | |
/** | |
Swaps all UIColor.cgColor getter calls for a function block that returns a random color. This has the | |
effect of randomizing all UIColors every time their getter is called. | |
*/ | |
public static func rzl_swizzle() { | |
_ = self.rzl_swizzleImplementation | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
To use, just call
UIColor.rzl_swizzle()
somewhere (AppDelegate, for example). Once is enough.This will probably not get you rejected from the app store, but it is in poor taste.