When using NSKernAttributeName
it puts a space at the end of each line, is there any way to fix this? I can set the attributed to be in the range of:
NSRange(location: 0, length: self.text!.characters.count-1)
But I don't want to set this for every line.
This is the test code in the a playground I am using
//: Playground - noun: a place where people can play
import UIKit
import XCPlayground
var text = "Hello, playground\nhow are you?"
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.paragraphSpacing = 50
paragraphStyle.alignment = NSTextAlignment.Left
paragraphStyle.lineBreakMode = NSLineBreakMode.ByTruncatingTail
let attributes = [
NSParagraphStyleAttributeName: paragraphStyle
, NSKernAttributeName: 20
]
let attributedString = NSAttributedString(string: text, attributes: attributes)
let label = UILabel()
label.attributedText = attributedString
label.numberOfLines = 0
label.textColor = UIColor.greenColor()
label.backgroundColor = UIColor.orangeColor()
label.sizeToFit()
label.center = CGPoint(x: 500, y: 100)
var text2 = "What's up\nWhere are you?"
let attributedString2 = NSAttributedString(string: text2, attributes: attributes)
let label2 = UILabel()
label2.attributedText = attributedString2
label2.numberOfLines = 0
label2.textColor = UIColor.greenColor()
label2.backgroundColor = UIColor.orangeColor()
label2.sizeToFit()
label2.center = CGPoint(x: 500, y: 250)
var text3 = "Hello"
let attributedString3 = NSAttributedString(string: text3, attributes: attributes)
let label3 = UILabel()
label3.attributedText = attributedString3
label3.numberOfLines = 0
label3.textColor = UIColor.greenColor()
label3.backgroundColor = UIColor.orangeColor()
label3.sizeToFit()
label3.center = CGPoint(x: 500, y: 400)
let holderView = UIView(frame: CGRect(x: 0, y: 0, width: 1000, height: 500))
holderView.backgroundColor = UIColor.lightGrayColor()
holderView.addSubview(label)
holderView.addSubview(label2)
holderView.addSubview(label3)
XCPlaygroundPage.currentPage.liveView = holderView
With the result looking like this:
You can see the spaces at the end of each of the lines.
This is actually the definition of how kerning works; it adjusts the space between the kerned character and where the next character will be. Whether a next character proceeds to be drawn or not is irrelevant.
The kerning attribute indicates how much the following character should be shifted from its default offset as defined by the current character’s font; a positive kern indicates a shift farther along and a negative kern indicates a shift closer to the current character.
If it helps, think about doing this in a word processor. If kerning is on, and you type a character, where would you expect the insertion point to be then? The expected answer would be "offset from the just typed character by the amount of kern" as that's what happens in the default case of kern being 0, correct? Well, that's exactly what's happening here: if you kern the last character of a string, the string therefore includes the last kern.
So the correct thing to do here is to wrap up your dropLast() logic in an extension and call it a day.