Skip to content

Instantly share code, notes, and snippets.

@dchohfi
Created June 11, 2018 16:53
Show Gist options
  • Save dchohfi/eed0c804e94bb51681d31f53fdd0c498 to your computer and use it in GitHub Desktop.
Save dchohfi/eed0c804e94bb51681d31f53fdd0c498 to your computer and use it in GitHub Desktop.
Apple custom typography
import UIKit
// swiftlint:disable file_length
extension UIColor {
static var link: UIColor {
return UIColor(r: 0, g: 152, b: 238)
}
static var toastNotification: UIColor {
return .white
}
static var mapMarker: UIColor {
return .black
}
static var titleNavigationBar: UIColor {
return .white
}
static var title1: UIColor {
return .black
}
static var title2: UIColor {
return .black
}
static var title3: UIColor {
return .black
}
static var headline: UIColor {
return .black
}
static var body: UIColor {
return .black
}
static var callout: UIColor {
return .black
}
static var subheadline: UIColor {
return .darkGray
}
static var footnote: UIColor {
return .darkGray
}
static var caption1: UIColor {
return UIColor.nn.gray.warm
}
static var caption2: UIColor {
return .black
}
static var mainButton: UIColor {
return .black
}
}
// swiftlint:disable line_length
extension String {
func attributedOf(size: CGFloat = 12, color: UIColor = .black) -> NSAttributedString {
return NSAttributedString(string: self, attributes: [NSFontAttributeName: UIFont.systemFont(ofSize: size),
NSForegroundColorAttributeName: color])
}
var placeholder: NSAttributedString {
return self.body(weight: UIFontWeightLight,
color: .lightGray)
}
var link: NSAttributedString {
return NSAttributedString(string: self, attributes: [NSFontAttributeName: UIFont.link,
NSForegroundColorAttributeName: UIColor.link])
}
func link(_ color: UIColor = .link) -> NSAttributedString {
return NSAttributedString(string: self, attributes: [NSFontAttributeName: UIFont.link,
NSForegroundColorAttributeName: color])
}
var toastNotification: NSAttributedString {
return NSAttributedString(string: self, attributes: [NSFontAttributeName: UIFont.toastNotification,
NSForegroundColorAttributeName: UIColor.toastNotification])
}
var mapMarker: NSAttributedString {
return NSAttributedString(string: self, attributes: [NSFontAttributeName: UIFont.mapMarker,
NSForegroundColorAttributeName: UIColor.mapMarker])
}
func titleNavigationBar(_ color: UIColor = .titleNavigationBar) -> NSAttributedString {
return NSAttributedString(string: self, attributes: [NSFontAttributeName: UIFont.titleNavigationBar,
NSForegroundColorAttributeName: color])
}
func title1(minimumContentSizeCategory: UIContentSizeCategory = .extraSmall,
maximumContentSizeCategory: UIContentSizeCategory = .accessibilityExtraExtraExtraLarge,
weight: CGFloat = UIFontWeightLight,
color: UIColor = .title1) -> NSAttributedString {
return NSAttributedString(string: self, attributes: [NSFontAttributeName: UIFont.title1(minimumContentSizeCategory: minimumContentSizeCategory,
maximumContentSizeCategory: maximumContentSizeCategory,
weight: weight),
NSForegroundColorAttributeName: color])
}
func title2(minimumContentSizeCategory: UIContentSizeCategory = .extraSmall,
maximumContentSizeCategory: UIContentSizeCategory = .accessibilityExtraExtraExtraLarge,
weight: CGFloat = UIFontWeightSemibold,
color: UIColor = .title2) -> NSAttributedString {
return NSAttributedString(string: self, attributes: [NSFontAttributeName: UIFont.title2(minimumContentSizeCategory: minimumContentSizeCategory,
maximumContentSizeCategory: maximumContentSizeCategory,
weight: weight),
NSForegroundColorAttributeName: color])
}
func title3(minimumContentSizeCategory: UIContentSizeCategory = .extraSmall,
maximumContentSizeCategory: UIContentSizeCategory = .accessibilityExtraExtraExtraLarge,
weight: CGFloat = UIFontWeightSemibold,
color: UIColor = .title3) -> NSAttributedString {
return NSAttributedString(string: self, attributes: [NSFontAttributeName: UIFont.title3(minimumContentSizeCategory: minimumContentSizeCategory,
maximumContentSizeCategory: maximumContentSizeCategory,
weight: weight),
NSForegroundColorAttributeName: color])
}
func headline(minimumContentSizeCategory: UIContentSizeCategory = .extraSmall,
maximumContentSizeCategory: UIContentSizeCategory = .accessibilityExtraExtraExtraLarge,
weight: CGFloat = UIFontWeightSemibold,
color: UIColor = .headline) -> NSAttributedString {
return NSAttributedString(string: self, attributes: [NSFontAttributeName: UIFont.headline(minimumContentSizeCategory: minimumContentSizeCategory,
maximumContentSizeCategory: maximumContentSizeCategory,
weight: weight),
NSForegroundColorAttributeName: color])
}
func body(minimumContentSizeCategory: UIContentSizeCategory = .extraSmall,
maximumContentSizeCategory: UIContentSizeCategory = .accessibilityExtraExtraExtraLarge,
weight: CGFloat = UIFontWeightRegular,
color: UIColor = .body) -> NSAttributedString {
return NSAttributedString(string: self, attributes: [NSFontAttributeName: UIFont.body(minimumContentSizeCategory: minimumContentSizeCategory,
maximumContentSizeCategory: maximumContentSizeCategory,
weight: weight),
NSForegroundColorAttributeName: color])
}
func callout(minimumContentSizeCategory: UIContentSizeCategory = .extraSmall,
maximumContentSizeCategory: UIContentSizeCategory = .accessibilityExtraExtraExtraLarge,
weight: CGFloat = UIFontWeightSemibold,
color: UIColor = .callout) -> NSAttributedString {
return NSAttributedString(string: self, attributes: [NSFontAttributeName: UIFont.callout(minimumContentSizeCategory: minimumContentSizeCategory,
maximumContentSizeCategory: maximumContentSizeCategory,
weight: weight),
NSForegroundColorAttributeName: color])
}
func subheadline(minimumContentSizeCategory: UIContentSizeCategory = .extraSmall,
maximumContentSizeCategory: UIContentSizeCategory = .accessibilityExtraExtraExtraLarge,
weight: CGFloat = UIFontWeightRegular,
color: UIColor = .subheadline) -> NSAttributedString {
return NSAttributedString(string: self, attributes: [NSFontAttributeName: UIFont.subheadline(minimumContentSizeCategory: minimumContentSizeCategory,
maximumContentSizeCategory: maximumContentSizeCategory,
weight: weight),
NSForegroundColorAttributeName: color])
}
func footnote(minimumContentSizeCategory: UIContentSizeCategory = .extraSmall,
maximumContentSizeCategory: UIContentSizeCategory = .accessibilityExtraExtraExtraLarge,
weight: CGFloat = UIFontWeightRegular,
color: UIColor = .footnote) -> NSAttributedString {
return NSAttributedString(string: self, attributes: [NSFontAttributeName: UIFont.footnote(minimumContentSizeCategory: minimumContentSizeCategory,
maximumContentSizeCategory: maximumContentSizeCategory,
weight: weight),
NSForegroundColorAttributeName: color])
}
func caption1(minimumContentSizeCategory: UIContentSizeCategory = .extraSmall,
maximumContentSizeCategory: UIContentSizeCategory = .accessibilityExtraExtraExtraLarge,
weight: CGFloat = UIFontWeightRegular,
color: UIColor = .caption1) -> NSAttributedString {
return NSAttributedString(string: self, attributes: [NSFontAttributeName: UIFont.caption1(minimumContentSizeCategory: minimumContentSizeCategory,
maximumContentSizeCategory: maximumContentSizeCategory,
weight: weight),
NSForegroundColorAttributeName: color])
}
func caption2(minimumContentSizeCategory: UIContentSizeCategory = .extraSmall,
maximumContentSizeCategory: UIContentSizeCategory = .accessibilityExtraExtraExtraLarge,
weight: CGFloat = UIFontWeightBold,
color: UIColor = .caption2) -> NSAttributedString {
return NSAttributedString(string: self, attributes: [NSFontAttributeName: UIFont.caption2(minimumContentSizeCategory: minimumContentSizeCategory,
maximumContentSizeCategory: maximumContentSizeCategory,
weight: weight),
NSForegroundColorAttributeName: color])
}
func mainButton(minimumContentSizeCategory: UIContentSizeCategory = .extraSmall,
maximumContentSizeCategory: UIContentSizeCategory = .accessibilityExtraExtraExtraLarge,
weight: CGFloat = UIFontWeightSemibold) -> NSAttributedString {
return NSAttributedString(string: self, attributes: [NSFontAttributeName: UIFont.mainButton(minimumContentSizeCategory: minimumContentSizeCategory,
maximumContentSizeCategory: maximumContentSizeCategory,
weight: weight),
NSForegroundColorAttributeName: UIColor.mainButton])
}
}
extension UIFont {
static var link: UIFont {
return .systemFont(ofSize: 15, weight: UIFontWeightMedium)
}
static var toastNotification: UIFont {
return .systemFont(ofSize: 14, weight: UIFontWeightMedium)
}
static var mapMarker: UIFont {
return .systemFont(ofSize: 13, weight: UIFontWeightMedium)
}
static var titleNavigationBar: UIFont {
return .boldSystemFont(ofSize: 17)
}
static func title1(minimumContentSizeCategory: UIContentSizeCategory = .extraSmall,
maximumContentSizeCategory: UIContentSizeCategory = .accessibilityExtraExtraExtraLarge,
weight: CGFloat = UIFontWeightLight) -> UIFont {
let pointSize = UIFontDescriptor.currentPreferredSize(textStyle: .title1,
minimumContentSizeCategory: minimumContentSizeCategory,
maximumContentSizeCategory: maximumContentSizeCategory)
return .systemFont(ofSize: pointSize, weight: weight)
}
static func title2(minimumContentSizeCategory: UIContentSizeCategory = .extraSmall,
maximumContentSizeCategory: UIContentSizeCategory = .accessibilityExtraExtraExtraLarge,
weight: CGFloat = UIFontWeightSemibold) -> UIFont {
let pointSize = UIFontDescriptor.currentPreferredSize(textStyle: .title2,
minimumContentSizeCategory: minimumContentSizeCategory,
maximumContentSizeCategory: maximumContentSizeCategory)
return .systemFont(ofSize: pointSize, weight: weight)
}
static func title3(minimumContentSizeCategory: UIContentSizeCategory = .extraSmall,
maximumContentSizeCategory: UIContentSizeCategory = .accessibilityExtraExtraExtraLarge,
weight: CGFloat = UIFontWeightSemibold) -> UIFont {
let pointSize = UIFontDescriptor.currentPreferredSize(textStyle: .title3,
minimumContentSizeCategory: minimumContentSizeCategory,
maximumContentSizeCategory: maximumContentSizeCategory)
return .systemFont(ofSize: pointSize, weight: weight)
}
static func headline(minimumContentSizeCategory: UIContentSizeCategory = .extraSmall,
maximumContentSizeCategory: UIContentSizeCategory = .accessibilityExtraExtraExtraLarge,
weight: CGFloat = UIFontWeightSemibold) -> UIFont {
let pointSize = UIFontDescriptor.currentPreferredSize(textStyle: .headline,
minimumContentSizeCategory: minimumContentSizeCategory,
maximumContentSizeCategory: maximumContentSizeCategory)
return .systemFont(ofSize: pointSize, weight: weight)
}
static func body(minimumContentSizeCategory: UIContentSizeCategory = .extraSmall,
maximumContentSizeCategory: UIContentSizeCategory = .accessibilityExtraExtraExtraLarge,
weight: CGFloat = UIFontWeightRegular) -> UIFont {
let pointSize = UIFontDescriptor.currentPreferredSize(textStyle: .headline,
minimumContentSizeCategory: minimumContentSizeCategory,
maximumContentSizeCategory: maximumContentSizeCategory)
return .systemFont(ofSize: pointSize, weight: weight)
}
static func callout(minimumContentSizeCategory: UIContentSizeCategory = .extraSmall,
maximumContentSizeCategory: UIContentSizeCategory = .accessibilityExtraExtraExtraLarge,
weight: CGFloat = UIFontWeightSemibold) -> UIFont {
let pointSize = UIFontDescriptor.currentPreferredSize(textStyle: .callout,
minimumContentSizeCategory: minimumContentSizeCategory,
maximumContentSizeCategory: maximumContentSizeCategory)
return .systemFont(ofSize: pointSize, weight: weight)
}
static func subheadline(minimumContentSizeCategory: UIContentSizeCategory = .extraSmall,
maximumContentSizeCategory: UIContentSizeCategory = .accessibilityExtraExtraExtraLarge,
weight: CGFloat = UIFontWeightRegular) -> UIFont {
let pointSize = UIFontDescriptor.currentPreferredSize(textStyle: .subheadline,
minimumContentSizeCategory: minimumContentSizeCategory,
maximumContentSizeCategory: maximumContentSizeCategory)
return .systemFont(ofSize: pointSize, weight: weight)
}
static func footnote(minimumContentSizeCategory: UIContentSizeCategory = .extraSmall,
maximumContentSizeCategory: UIContentSizeCategory = .accessibilityExtraExtraExtraLarge,
weight: CGFloat = UIFontWeightRegular) -> UIFont {
let pointSize = UIFontDescriptor.currentPreferredSize(textStyle: .footnote,
minimumContentSizeCategory: minimumContentSizeCategory,
maximumContentSizeCategory: maximumContentSizeCategory)
return .systemFont(ofSize: pointSize, weight: weight)
}
static func caption1(minimumContentSizeCategory: UIContentSizeCategory = .extraSmall,
maximumContentSizeCategory: UIContentSizeCategory = .accessibilityExtraExtraExtraLarge,
weight: CGFloat = UIFontWeightRegular) -> UIFont {
let pointSize = UIFontDescriptor.currentPreferredSize(textStyle: .caption1,
minimumContentSizeCategory: minimumContentSizeCategory,
maximumContentSizeCategory: maximumContentSizeCategory)
return .systemFont(ofSize: pointSize, weight: weight)
}
static func caption2(minimumContentSizeCategory: UIContentSizeCategory = .extraSmall,
maximumContentSizeCategory: UIContentSizeCategory = .accessibilityExtraExtraExtraLarge,
weight: CGFloat = UIFontWeightBold) -> UIFont {
let pointSize = UIFontDescriptor.currentPreferredSize(textStyle: .caption2,
minimumContentSizeCategory: minimumContentSizeCategory,
maximumContentSizeCategory: maximumContentSizeCategory)
return .systemFont(ofSize: pointSize, weight: weight)
}
static func mainButton(minimumContentSizeCategory: UIContentSizeCategory = .extraSmall,
maximumContentSizeCategory: UIContentSizeCategory = .accessibilityExtraExtraExtraLarge,
weight: CGFloat = UIFontWeightSemibold) -> UIFont {
let pointSize = UIFontDescriptor.currentPreferredSize(textStyle: .mainButton,
minimumContentSizeCategory: minimumContentSizeCategory,
maximumContentSizeCategory: maximumContentSizeCategory)
return .systemFont(ofSize: pointSize, weight: weight)
}
}
extension UIFontDescriptor {
private static var contentSizeLargeHeightIndex = 3 // this is the index for .large size on the array bellow
private static var contentSizesHeight: [UIContentSizeCategory] =
[.extraSmall,
.small,
.medium,
.large,
.extraLarge,
.extraExtraLarge,
.extraExtraExtraLarge,
.accessibilityMedium,
.accessibilityLarge,
.accessibilityExtraLarge,
.accessibilityExtraExtraLarge,
.accessibilityExtraExtraExtraLarge]
static func currentPreferredSize(textStyle: UIFontTextStyle = .body,
minimumContentSizeCategory: UIContentSizeCategory = .extraSmall,
maximumContentSizeCategory: UIContentSizeCategory = .accessibilityExtraExtraExtraLarge) -> CGFloat {
let contentSize = self.preferredContentSizeCategoryInBoundries(minimumContentSizeCategory: minimumContentSizeCategory,
maximumContentSizeCategory: maximumContentSizeCategory)
guard let style = self.fontSizeTable[textStyle], let fontSize = style[contentSize] else { return 17 }
return fontSize
}
private static func preferredContentSizeCategoryInBoundries(minimumContentSizeCategory: UIContentSizeCategory,
maximumContentSizeCategory: UIContentSizeCategory) -> UIContentSizeCategory {
let contentSize = UIApplication.shared.preferredContentSizeCategory
let preferredContentSizeHeight = self.contentSizesHeight.index(of: contentSize) ?? self.contentSizeLargeHeightIndex
let minimumContentSizeHeight = self.contentSizesHeight.index(of: minimumContentSizeCategory) ?? 0
let maximumContentSizeHeight = self.contentSizesHeight.index(of: maximumContentSizeCategory) ?? self.contentSizesHeight.count
if preferredContentSizeHeight < minimumContentSizeHeight {
return self.contentSizesHeight[minimumContentSizeHeight]
} else if preferredContentSizeHeight > maximumContentSizeHeight {
return self.contentSizesHeight[maximumContentSizeHeight]
}
return contentSize
}
private static var fontSizeTable: [UIFontTextStyle: [UIContentSizeCategory: CGFloat]] = {
return [
.title1: [
.accessibilityExtraExtraExtraLarge: 34,
.accessibilityExtraExtraLarge: 34,
.accessibilityExtraLarge: 34,
.accessibilityLarge: 34,
.accessibilityMedium: 34,
.extraExtraExtraLarge: 34,
.extraExtraLarge: 32,
.extraLarge: 30,
.large: 28,
.medium: 27,
.small: 26,
.extraSmall: 25],
.title2: [
.accessibilityExtraExtraExtraLarge: 28,
.accessibilityExtraExtraLarge: 28,
.accessibilityExtraLarge: 28,
.accessibilityLarge: 28,
.accessibilityMedium: 28,
.extraExtraExtraLarge: 28,
.extraExtraLarge: 26,
.extraLarge: 24,
.large: 22,
.medium: 21,
.small: 20,
.extraSmall: 19],
.title3: [
.accessibilityExtraExtraExtraLarge: 26,
.accessibilityExtraExtraLarge: 26,
.accessibilityExtraLarge: 26,
.accessibilityLarge: 26,
.accessibilityMedium: 26,
.extraExtraExtraLarge: 26,
.extraExtraLarge: 24,
.extraLarge: 22,
.large: 20,
.medium: 19,
.small: 18,
.extraSmall: 17],
.headline: [
.accessibilityExtraExtraExtraLarge: 23,
.accessibilityExtraExtraLarge: 23,
.accessibilityExtraLarge: 23,
.accessibilityLarge: 23,
.accessibilityMedium: 23,
.extraExtraExtraLarge: 23,
.extraExtraLarge: 21,
.extraLarge: 19,
.large: 17,
.medium: 16,
.small: 15,
.extraSmall: 14],
.body: [
.accessibilityExtraExtraExtraLarge: 22,
.accessibilityExtraExtraLarge: 22,
.accessibilityExtraLarge: 22,
.accessibilityLarge: 22,
.accessibilityMedium: 22,
.extraExtraExtraLarge: 22,
.extraExtraLarge: 20,
.extraLarge: 18,
.large: 16,
.medium: 15,
.small: 14,
.extraSmall: 13],
.callout: [
.accessibilityExtraExtraExtraLarge: 22,
.accessibilityExtraExtraLarge: 22,
.accessibilityExtraLarge: 22,
.accessibilityLarge: 22,
.accessibilityMedium: 22,
.extraExtraExtraLarge: 22,
.extraExtraLarge: 20,
.extraLarge: 18,
.large: 16,
.medium: 15,
.small: 14,
.extraSmall: 13],
.subheadline: [
.accessibilityExtraExtraExtraLarge: 20,
.accessibilityExtraExtraLarge: 20,
.accessibilityExtraLarge: 20,
.accessibilityLarge: 20,
.accessibilityMedium: 20,
.extraExtraExtraLarge: 20,
.extraExtraLarge: 18,
.extraLarge: 16,
.large: 14,
.medium: 13,
.small: 12,
.extraSmall: 11],
.footnote: [
.accessibilityExtraExtraExtraLarge: 19,
.accessibilityExtraExtraLarge: 19,
.accessibilityExtraLarge: 19,
.accessibilityLarge: 19,
.accessibilityMedium: 19,
.extraExtraExtraLarge: 19,
.extraExtraLarge: 17,
.extraLarge: 15,
.large: 13,
.medium: 12,
.small: 12,
.extraSmall: 12],
.caption1: [
.accessibilityExtraExtraExtraLarge: 18,
.accessibilityExtraExtraLarge: 18,
.accessibilityExtraLarge: 18,
.accessibilityLarge: 18,
.accessibilityMedium: 18,
.extraExtraExtraLarge: 18,
.extraExtraLarge: 16,
.extraLarge: 14,
.large: 12,
.medium: 11,
.small: 11,
.extraSmall: 11],
.caption2: [
.accessibilityExtraExtraExtraLarge: 17,
.accessibilityExtraExtraLarge: 17,
.accessibilityExtraLarge: 17,
.accessibilityLarge: 17,
.accessibilityMedium: 17,
.extraExtraExtraLarge: 17,
.extraExtraLarge: 15,
.extraLarge: 13,
.large: 11,
.medium: 10,
.small: 10,
.extraSmall: 10],
.mainButton: [
.accessibilityExtraExtraExtraLarge: 22,
.accessibilityExtraExtraLarge: 22,
.accessibilityExtraLarge: 22,
.accessibilityLarge: 22,
.accessibilityMedium: 22,
.extraExtraExtraLarge: 22,
.extraExtraLarge: 20,
.extraLarge: 18,
.large: 16,
.medium: 15,
.small: 14,
.extraSmall: 13]
]
}()
}
extension UIFontTextStyle {
public static let mainButton: UIFontTextStyle = UIFontTextStyle(rawValue: "main button")
}
// swiftlint:enable line_length
// swiftlint:enable file_length
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment