/
Font.swift
executable file
·130 lines (117 loc) · 5.03 KB
/
Font.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// Copyright 2018 Montana Floss Co. Ltd.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
// Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// Font.swift
// UISpecExampleFramework
//
// Created by Marc Palmer on 09/01/2018.
//
import Foundation
#if os(macOS)
import AppKit
public typealias FontType = NSFont
#else
import UIKit
public typealias FontType = UIFont
#endif
/// A representation of a font, including an optional color.
public struct Font<T: UISpec> {
public let font: FontType
public let face: String
public let size: GridDimension<T>
public let color: Color?
/// Create a new font metric using a custom font.
/// - note: Not recommended, use system fonts for Dynamic Text!
init(face: String, size: GridDimension<T>, color: Color? = nil) {
self.size = size
self.face = face
self.color = color
/// Note: we have to have a fallback here because iOS unit tests cannot load custom fonts through the normal
/// UIFont loader. We could rewrite all this to use a CGDataProvider for the font but... troll ourselves instead
font = FontType(name: face, size: size.points) ?? FontType.init(name: "Noteworthy", size: 30)!
}
/// Derive a font from this font instance, by changing only the color
func with(color newColor: Color) -> Font {
return Font<T>(face: face, size: size, color: newColor)
}
#if !os(macOS)
/// Create an system font of the given grid dimension size with an optional color
/// - param systemFontOfSize: The font size as a grid dimension
/// - param color: The optional color
init(systemFontOfSize size: GridDimension<T>, color: Color? = nil) {
font = UIFont.systemFont(ofSize: size.points)
face = font.fontName
self.size = size
self.color = color
}
/// Preferred initializer for when you support iOS Dynamic Type
/// - param preferredFontStyle: The Dynamic Type text style
/// - param color: The optional color
init(preferredFontStyle: UIFontTextStyle, color: Color? = nil) {
font = UIFont.preferredFont(forTextStyle: preferredFontStyle)
face = font.fontName
size = GridDimension<T>(fromPoints: font.pointSize)
self.color = color
}
/// Apply this font to the supplied `UIButton`.
/// This will set the font for the `titleLabel` and sets `titleColor` to the `color` for `UIControlStateNormal`.
/// if a `color` is set.
public func apply(to button: UIButton) {
button.titleLabel?.font = font
if let color = color {
button.setTitleColor(color.color, for: .normal)
}
}
/// Apply this font to all the supplied `UIButton`(s).
/// This will set the font for the `titleLabel` and sets `titleColor` to the `color` for `UIControlStateNormal`.
/// if a `color` is set.
public func apply(to buttons: [UIButton]) {
for button in buttons {
apply(to: button)
}
}
/// Apply this font to the supplied `UILabel`.
/// This will set the font on and sets `textColor` to the `color` if a `color` is set.
public func apply(to label: UILabel) {
label.font = font
if let color = color {
label.textColor = color.color
}
}
/// Apply this font to all the supplied `UILabel`s.
/// This will set the font on and sets `textColor` to the `color` if a `color` is set.
public func apply(to labels: [UILabel]) {
for label in labels {
apply(to: label)
}
}
#else
/// Apply this font to the supplied `NSTextField`.
/// This will set the font on and sets `textColor` to the `color` if a `color` is set.
public func apply(to field: NSTextField) {
field.font = font
if let color = color {
field.textColor = color.color
}
}
/// Apply this font to all the supplied `NSTextField`(s).
/// This will set the font on and sets `textColor` to the `color` if a `color` is set.
public func apply(to textFields: [NSTextField]) {
for field in textFields {
apply(to: field)
}
}
#endif
}