2

I have an array of labels for my buttons:

whenButtonArray = ["THURSDAY\nJUNE 5", "FRIDAY\nJUNE 6", "SATURDAY\nJUNE 7", "SUNDAY\nJUNE 8"]

What I'm trying to do is to use NSMutableAttributedString to make the text before the "\n" be a bigger font than the text after it.

I initialized my string like this:

myMutableString = NSMutableAttributedString(string: whenWhereButtonArray[i], attributes: [NSFontAttributeName:UIFont(name: "Tungsten-Book", size: 22.0)!])

But how can I make the second part of the string (after the \n) be a smaller font size? I know I can do something like this:

myMutableString.addAttribute(NSFontAttributeName, value: UIFont(name: "Tungsten-Book", size: 12.0)!, range: NSRange(location:3,length:4))

But I need the range to be dynamic based on the text for each button. Thanks!

codeman
  • 8,868
  • 13
  • 50
  • 79

2 Answers2

0

As long as there are no Unicode character representations/emojis within your string the following should work. Otherwise it's best to work with NSStrings as in rintaro's answer...

In order to update the location and length of the remaining string dynamically as needed for your sub attribute, you have to start by getting the position of "\n" (I've used the formula from this answer.):

let range = whenWhereButtonArray[i].rangeOfString("\n")
let newlineIndex : Int = distance(whenWhereButtonArray[i].startIndex, range.startIndex)

Then knowing the beginning index of "\n" you can calculate (1) the second string's index and then (2) the length of the second string. ex:

let secondStringIndex : Int = newlineIndex + countElements("\n")
let lengthOfSecondString : Int = countElements(whenWhereButtonArray[i]) - secondStringIndex

Then you can enter that info into the sub attribute formula like so:

myMutableString.addAttribute(NSFontAttributeName, value: UIFont(name: "Tungsten-Book", size: 12.0)!, range: NSRange(location:secondStringIndex,length:lengthOfSecondString))
Community
  • 1
  • 1
Lyndsey Scott
  • 37,080
  • 10
  • 92
  • 128
  • You should not use `String.Index` to make `NSRange` of Cocoa string types. Consider something like `"THURSDAY\nJUNE"`. – rintaro Dec 03 '14 at 17:01
  • @Rintaro where did I use String.Index to make an NSRange? – Lyndsey Scott Dec 03 '14 at 17:03
  • @rintaro Oh, you mean using an int facsimile of sting.index? Because I never actually used string.index... – Lyndsey Scott Dec 03 '14 at 17:03
  • Yes, for example, `"THURSDAY\nJUNE"` case, the range should be `NSRange(location:13, length:4)`, but with your method, that is `NSRange(location:11, length:4)`. – rintaro Dec 03 '14 at 17:06
  • Doesn't countElements also count ? – Lyndsey Scott Dec 03 '14 at 17:06
  • `countElements("" as String)` is `1`, but `("" as NSString).length` is `2` – rintaro Dec 03 '14 at 17:10
  • @rintaro I guess my confusion comes from the fact that I thought I was working with a String not an NSString... At what point are you saying it became an NSString? – Lyndsey Scott Dec 03 '14 at 17:11
  • I mean, `NSMutableAttributedString`'s range has same semantics as `NSString` one. – rintaro Dec 03 '14 at 17:14
  • @rintaro Oh, OK. Gotcha. So will this answer work in the case of no unicode character representations? If so, I can update it accordingly for future answer seekers. – Lyndsey Scott Dec 03 '14 at 17:17
  • Hmm, I think it's difficult. Maybe we should use `String.UTF16View`: something like `find(str.utf16, "\n".utf16[0]) `. – rintaro Dec 03 '14 at 17:25
  • @rintaro Hm... Yeah, the major issue is that initial formula. In order to continue using String in all scenarios we'd need to also identify the unicode characters in the String and factor them into the operation to make for seamless conversion to the NSString... You're saying `find(str.utf16, "\n".utf16[0])` can find those unicode characters? – Lyndsey Scott Dec 03 '14 at 17:33
  • @rintaro OK, well I've thought about it a bit and I think I'll go a different route with the formula. I'll probably separate the string into components before and after "\n" then use `component1.utf16Count` to get the length of the string before "\n" such that it lines up with the `NSString` length calculation. But I'm not feeling 100% today and my head's a bit fuzzy, so I'm going to try my hardest to back away from stack overflow for a bit haha. I'll check in with you to see what you think of the changes once I make them. – Lyndsey Scott Dec 03 '14 at 17:49
0

In this case, working with NSString is relatively easier than working with Swift String:

let whenButtonArray = ["THURSDAY\nJUNE 5", "FRIDAY\nJUNE 6", "SATURDAY\nJUNE 7", "SUNDAY\nJUNE 8"]

let str = whenButtonArray[0] as NSString // cast to `NSString`
let attributed = NSMutableAttributedString(string: str, attributes: [NSFontAttributeName:UIFont(name: "Arial", size: 22.0)!])
let nl = str.rangeOfString("\n")
if nl.location != NSNotFound {
    let range = NSMakeRange(NSMaxRange(nl), str.length - NSMaxRange(nl))
    attributed.addAttribute(NSFontAttributeName, value: UIFont(name: "Arial", size: 12.0)!, range: range)
}
rintaro
  • 51,423
  • 14
  • 131
  • 139