-2

I have used NSMutableAttributedString/NSAttributedString here and there but don't have extensive experience with them. I have a code block that repeats itself and was wondering how would I go about refactoring it? I've been working on a few extensions to refactor this but haven't had any luck.

The attributes goes into a UILabel variable closure.

let attributes = NSMutableAttributedString(string: "ID: \n",
                                               attributes: [NSAttributedString.Key.foregroundColor : UIColor.black,
                                                            NSAttributedString.Key.backgroundColor : UIColor.clear,
                                                            NSAttributedString.Key.font : UIFont(name: "Helvetica", size: 15)!])
    attributes.append(NSMutableAttributedString(string: "\(nameID)",
                                                attributes: [NSAttributedString.Key.foregroundColor : UIColor.white,
                                                             NSAttributedString.Key.backgroundColor : UIColor.customBlue(),
                                                             NSAttributedString.Key.font : UIFont(name: "Helvetica", size: 15)!]))
    attributes.append(NSMutableAttributedString(string: "\nDate Created: \n",
                                                attributes: [NSAttributedString.Key.foregroundColor : UIColor.black,
                                                             NSAttributedString.Key.backgroundColor : UIColor.clear,
                                                             NSAttributedString.Key.font : UIFont(name: "Helvetica", size: 15)!]))
    attributes.append(NSMutableAttributedString(string: "TEST",
                                                attributes: [NSAttributedString.Key.foregroundColor : UIColor.white,
                                                             NSAttributedString.Key.backgroundColor : UIColor.customBlue(),
                                                             NSAttributedString.Key.font : UIFont(name: "Helvetica", size: 15)!]))
    attributes.append(NSMutableAttributedString(string: "\nDate Last Used: \n",
                                                attributes: [NSAttributedString.Key.foregroundColor : UIColor.black,
                                                             NSAttributedString.Key.backgroundColor : UIColor.clear,
                                                             NSAttributedString.Key.font : UIFont(name: "Helvetica", size: 15)!]))
    attributes.append(NSMutableAttributedString(string: "TEST",
                                                attributes: [NSAttributedString.Key.foregroundColor : UIColor.white,
                                                             NSAttributedString.Key.backgroundColor : UIColor.customBlue(),
                                                             NSAttributedString.Key.font : UIFont(name: "Helvetica", size: 15)!]))
Anjali Shah
  • 720
  • 7
  • 21
syds
  • 322
  • 3
  • 12
  • 1
    You can atleast avoid repeating the code of attributes array. Just move out the attributes array and assign it a constant and then reuse it in the parameters – Anil Arigela Dec 24 '19 at 09:02

1 Answers1

1

Try looking at your code and seeing if there's a pattern. What I see is creating multiple NSAttributedStrings with String values, setting foreground and background, and the same font over and over. So this is ripe for the refactor picking.

First, set up your data:

// one note here is that you actually have a newline char for every entry, so it's probably better practice t simply drop them and apply them in your loop which we'll get to
let values = ["ID:", nameID /*I assume this is already a `String`*/, "Date Created: ", "TEST", "Date Last Used:", "Test"]

Colors seem to follow their own pattern: titles are black on clear and values are white on custom blue. We can use this in our loop, too. Let's set up our attributes so they're easy to reference:

let titleAttributes: [NSAttributedString.Key: Any] = [
  .foregroundColor: UIColor.black,
  .backgroundColor: UIColor.clear,
  .font: UIFont(name: "Helvetica", size: 15)!
]

let valueAttributes: [NSAttributedString.Key: Any] = [
  .foregroundColor: UIColor.white,
  .backgroundColor: UIColor.customBlue(),
  .font: UIFont(name: "Helvetica", size: 15)!
]

Now, let's loop:

let mutableString = NSMutableAttributedString()

for (index, currentValue) in values.enumerated() {
  // if we're on an even number, we have a title. If it's odd, it's a value
  let attributes = index % 2 == 0 ? titleAttributes : valueAttributes

  // if we aren't on the last index, add a newline to the value
  let value = index < values.count - 1 ? "\(currentValue)\n" : currentValue

  mutableString.appendAttributedString(string: value, attributes: attributes)
}
Procrastin8
  • 4,193
  • 12
  • 25
  • Thank you! I did some tweaking to your answer and it works flawlessly, really appreciate your help! – syds Dec 24 '19 at 20:55