1
\$\begingroup\$

iOS: prettify random color for debugging

I used to use random color to debug, from colors I like

extension CALayer{
 func debug(){
 let colors = [UIColor.blue, UIColor.magenta, UIColor.red,
 UIColor.green, UIColor.brown, UIColor.purple,
 UIColor.cyan]
 if let color = colors.randomElement().cgColor{
 borderColor = color
 }
 }
 }

The effect case:

The colors are not of regularity. Not very pretty.

111

I want to prettify it. Do some color alignment. The same color for the same UI hierarchy.

achieve something like this.

000

In order to not make colors repeat, and to show more colors in a page. I use ring buffer.

In order to do some color alignment, the same color for the same UI hierarchy,I use call stack trace. Use the call function as the key for its color.

Here is the code:

// the color ring buffer
struct ColorCluster {
 static var shared = ColorCluster()
 let colors = [UIColor.blue, UIColor.magenta, UIColor.red,
 UIColor.green, UIColor.brown, UIColor.purple,
 UIColor.cyan]
 var colorRegister = [String: Int]()
 var count = -1
 mutating func get(_ k: String) -> CGColor{
 var index = 0
 if let idx = colorRegister[k]{
 index = idx
 }
 else{
 count += 1
 if count >= colors.count{
 count = 0
 }
 index = count
 colorRegister[k] = count
 }
 return colors[index].cgColor
 }
}
extension CALayer{
 func debug(){
 // call stack trace, remove methods of the system 
 let libs: Set<String> = ["UIKitCore", "QuartzCore", "CoreFoundation"]
 var methods = [String]()
 Out: for symbol in Thread.callStackSymbols{
 for lib in libs {
 if symbol.contains(lib){
 break Out
 }
 }
 methods.append(symbol)
 }
 var edgeColor = UIColor.black.cgColor // color place holder
 if let name = methods.last{
 edgeColor = ColorCluster.shared.get(name)
 }
 borderColor = edgeColor
 borderWidth = 1
 }
}

Usage:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
 let cell = tableView.dequeue(for: PracticeDetailCell.self, ip: indexPath)
 cell.layer.debug()
 return cell
}

more code on github

asked Dec 29, 2019 at 16:55
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

I've had a look, and think it should be possible to trim down the ColorCluster-logic quite a bit, mostly by tightening up the get(: function a bit. Avoiding some if-elsing and only manipulating the index and count once.

struct ColorCluster {
 static var shared = ColorCluster()
 private init() { }
 
 private let colors: [UIColor] = [.blue, .magenta, .red, .green, .brown, .purple, .cyan]
 private var colorRegister = [String: Int]()
 private var count = 0
 mutating func getColor(for key: String) -> CGColor {
 let countIsOutOfBounds = count >= colors.count
 let nextAvailableIndex = countIsOutOfBounds ? 0 : count
 
 let index = colorRegister[key] ?? nextAvailableIndex
 count = countIsOutOfBounds ? 0 : count + 1
 
 return colors[index].cgColor
 }
}

I also had a quick look at the debug-extension. I haven't actually tested it, but the gist is to go down the functional route when creating the array of method-names:

extension CALayer {
 func debug() {
 // call stack trace, remove methods of the system
 let libs: Set<String> = ["UIKitCore", "QuartzCore", "CoreFoundation"]
 
 let methodNames = Thread.callStackSymbols.reduce([String]()) { names, symbol in
 let containingSymbol = libs.filter({ symbol.contains(0ドル) })
 if containingSymbol.isEmpty {
 return names
 }
 return names + [symbol]
 }
 
 var edgeColor = UIColor.black.cgColor // color place holder
 if let name = methodNames.last {
 edgeColor = ColorCluster.shared.getColor(for: name)
 }
 borderColor = edgeColor
 borderWidth = 1
 }
} 
answered Dec 6, 2020 at 11:15
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.