Dears,
Is it possible to change the space between letters while using UILabel?
I would like to expand it a little bit... for example:
As is: EXAMPLE
I would like to have it like: E X A M P L E
How can I do it?
Thanks
Themes.swift
First of all, you have no need to enclose two structs inside a class.
Second, if you want to apply extra spacing using `kern` (though I'm not sure if it is the best way for you) only for menuOption,
`LabelTheme` needs to be modified, just touching a very limited part of `LabelContent` is not sufficient.
import UIKit
struct LabelTheme {
let color: UIColor
let font: UIFont
let extraAttributes: [NSAttributedStringKey: Any]?
init(color: UIColor, font: UIFont, extraAttributes: [NSAttributedStringKey: Any]? = nil) {
self.color = color
self.font = font
self.extraAttributes = extraAttributes
}
static let menuOption = LabelTheme(color: .red, font: UIFont.boldSystemFont(ofSize: 26), extraAttributes: [.kern: 26])
static let type2 = LabelTheme(color: .yellow, font: UIFont.italicSystemFont(ofSize: 26))
static let type3 = LabelTheme(color: .black, font: UIFont.systemFont(ofSize: 26))
func set(to label: UILabel, with text: String = "") {
if var attributes = extraAttributes {
attributes[.font] = font
attributes[.foregroundColor] = color
label.attributedText = NSAttributedString(string: text, attributes: attributes)
} else {
label.textColor = color
label.font = font
}
}
}
struct LabelContent {
let text: String
let theme: LabelTheme
func set(to label: UILabel) {
theme.set(to: label, with: text)
}
}
Contents.swift
The class `Contents` has no reason to inherit `Themes`, if you make `LabelTheme` and `LabelContent` global as above.
And the class has no instance properties or states. Your `apply(content:to:)` method can be static.
import UIKit
class Contents {
static let navContent = [
LabelContent(text: "NAV IDENT", theme: .menuOption),
LabelContent(text: "WPT LIST", theme: .menuOption),
LabelContent(text: "FPL LIST", theme: .menuOption),
LabelContent(text: "POS SENSORS", theme: .menuOption),
LabelContent(text: "FIX INFO", theme: .menuOption),
LabelContent(text: "DEPARTURE", theme: .menuOption),
LabelContent(text: " ", theme: .menuOption),
LabelContent(text: "DATALINK", theme: .menuOption),
LabelContent(text: "FLT SUM", theme: .menuOption),
LabelContent(text: " ", theme: .menuOption),
LabelContent(text: "HOLD", theme: .menuOption),
LabelContent(text: "ARRIVAL", theme: .menuOption),
LabelContent(text: "POS INIT", theme: .menuOption),
LabelContent(text: "DATA LOAD", theme: .menuOption),
LabelContent(text: "PATTERNS", theme: .menuOption),
LabelContent(text: " ", theme: .menuOption),
LabelContent(text: " ", theme: .menuOption),
LabelContent(text: " ", theme: .menuOption),
LabelContent(text: "CONVERSION", theme: .menuOption),
LabelContent(text: "MAINTENANCE", theme: .menuOption),
LabelContent(text: "CROSS PTS", theme: .menuOption),
]
public static func apply(contents: ArraySlice<LabelContent>, to labels: [UILabel]) {
for index in 0..<labels.count {
labels[index].text = ""
}
for (offset, content) in contents.enumerated() {
labels[offset * 2 + 1].text = " "
content.set(to: labels[offset * 2 + 2])
}
}
}
(I do not understand why you need to do such complex things in your `apply(content:to:)` method, so I kept the basic structure as-is. But it may be improved or may need some fix.)
ViewController.swift
import UIKit
class ViewController: UIViewController {
@IBOutlet var uiTextLabels: [UILabel]!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func btnNav(_ sender: UIButton) {
Contents.apply(contents: Contents.navContent[0..<12], to: uiTextLabels)
}
}
You may need some more fixes as I do not understand some parts of your code, but please try and see what you get.