Add a SharedFont type to ElementFonts.

Using iOS 13 as availability so the properties can be simplified when support for iOS 12 is dropped.
This commit is contained in:
Doug 2022-02-21 12:47:32 +00:00 committed by Doug
parent fee6d9ad68
commit a0a1d63b78
4 changed files with 247 additions and 84 deletions

View file

@ -23,7 +23,7 @@ import SwiftUI
@available(iOS 14.0, *)
public struct FontSwiftUI: Fonts {
public let uiFonts: ElementFonts
public let uiFonts: FontsUIKit
public var largeTitle: Font
@ -66,27 +66,27 @@ public struct FontSwiftUI: Fonts {
public var caption2SB: Font
public init(values: ElementFonts) {
self.uiFonts = values
self.uiFonts = FontsUIKit(values: values)
self.largeTitle = Font(values.largeTitle)
self.largeTitleB = Font(values.largeTitleB)
self.title1 = Font(values.title1)
self.title1B = Font(values.title1B)
self.title2 = Font(values.title2)
self.title2B = Font(values.title2B)
self.title3 = Font(values.title3)
self.title3SB = Font(values.title3SB)
self.headline = Font(values.headline)
self.subheadline = Font(values.subheadline)
self.body = Font(values.body)
self.bodySB = Font(values.bodySB)
self.callout = Font(values.callout)
self.calloutSB = Font(values.calloutSB)
self.footnote = Font(values.footnote)
self.footnoteSB = Font(values.footnoteSB)
self.caption1 = Font(values.caption1)
self.caption1SB = Font(values.caption1SB)
self.caption2 = Font(values.caption2)
self.caption2SB = Font(values.caption2SB)
self.largeTitle = values.largeTitle.font
self.largeTitleB = values.largeTitleB.font
self.title1 = values.title1.font
self.title1B = values.title1B.font
self.title2 = values.title2.font
self.title2B = values.title2B.font
self.title3 = values.title3.font
self.title3SB = values.title3SB.font
self.headline = values.headline.font
self.subheadline = values.subheadline.font
self.body = values.body.font
self.bodySB = values.bodySB.font
self.callout = values.callout.font
self.calloutSB = values.calloutSB.font
self.footnote = values.footnote.font
self.footnoteSB = values.footnoteSB.font
self.caption1 = values.caption1.font
self.caption1SB = values.caption1SB.font
self.caption2 = values.caption2.font
self.caption2SB = values.caption2SB.font
}
}

View file

@ -63,25 +63,25 @@ import UIKit
public var caption2SB: UIFont
public init(values: ElementFonts) {
self.largeTitle = values.largeTitle
self.largeTitleB = values.largeTitleB
self.title1 = values.title1
self.title1B = values.title1B
self.title2 = values.title2
self.title2B = values.title2B
self.title3 = values.title3
self.title3SB = values.title3SB
self.headline = values.headline
self.subheadline = values.subheadline
self.body = values.body
self.bodySB = values.bodySB
self.callout = values.callout
self.calloutSB = values.calloutSB
self.footnote = values.footnote
self.footnoteSB = values.footnoteSB
self.caption1 = values.caption1
self.caption1SB = values.caption1SB
self.caption2 = values.caption2
self.caption2SB = values.caption2SB
self.largeTitle = values.largeTitle.uiFont
self.largeTitleB = values.largeTitleB.uiFont
self.title1 = values.title1.uiFont
self.title1B = values.title1B.uiFont
self.title2 = values.title2.uiFont
self.title2B = values.title2B.uiFont
self.title3 = values.title3.uiFont
self.title3SB = values.title3SB.uiFont
self.headline = values.headline.uiFont
self.subheadline = values.subheadline.uiFont
self.body = values.body.uiFont
self.bodySB = values.bodySB.uiFont
self.callout = values.callout.uiFont
self.calloutSB = values.calloutSB.uiFont
self.footnote = values.footnote.uiFont
self.footnoteSB = values.footnoteSB.uiFont
self.caption1 = values.caption1.uiFont
self.caption1SB = values.caption1SB.uiFont
self.caption2 = values.caption2.uiFont
self.caption2SB = values.caption2SB.uiFont
}
}

View file

@ -14,12 +14,42 @@
// limitations under the License.
//
import UIKit
import SwiftUI
/// Fonts at https://www.figma.com/file/X4XTH9iS2KGJ2wFKDqkyed/Compound?node-id=1362%3A0
@objcMembers
public class ElementFonts {
// MARK: - Types
/// A wrapper to provide both a `UIFont` and a SwiftUI `Font` in the same type.
/// The need for this comes from `Font` not adapting for dynamic type until the app
/// is restarted (or working at all in Xcode Previews) when initialised from a `UIFont`
/// (even if that font was created with the appropriate metrics).
public struct SharedFont {
public let uiFont: UIFont
/// The underlying font for the `font` property. This is stored
/// as an optional `Any` due to unavailability on iOS 12.
private let _font: Any?
@available(iOS 13.0, *)
public var font: Font {
_font as! Font
}
@available(iOS, deprecated: 13.0, message: "Use init(uiFont:font:) instead and remove this initialiser.")
init(uiFont: UIFont) {
self.uiFont = uiFont
self._font = nil
}
@available(iOS 13.0, *)
init(uiFont: UIFont, font: Font) {
self.uiFont = uiFont
self._font = font
}
}
// MARK: - Setup
public init() {
@ -35,85 +65,217 @@ public class ElementFonts {
}
// MARK: - Fonts protocol
extension ElementFonts: Fonts {
extension ElementFonts: Fonts {
public var largeTitle: UIFont {
return self.font(forTextStyle: .largeTitle)
public var largeTitle: SharedFont {
let uiFont = self.font(forTextStyle: .largeTitle)
if #available(iOS 13.0, *) {
return SharedFont(uiFont: uiFont, font: .largeTitle)
} else {
return SharedFont(uiFont: uiFont)
}
}
public var largeTitleB: UIFont {
return self.largeTitle.vc_bold
public var largeTitleB: SharedFont {
let uiFont = self.largeTitle.uiFont.vc_bold
if #available(iOS 13.0, *) {
return SharedFont(uiFont: uiFont, font: .largeTitle.bold())
} else {
return SharedFont(uiFont: uiFont)
}
}
public var title1: UIFont {
return self.font(forTextStyle: .title1)
public var title1: SharedFont {
let uiFont = self.font(forTextStyle: .title1)
if #available(iOS 13.0, *) {
return SharedFont(uiFont: uiFont, font: .title)
} else {
return SharedFont(uiFont: uiFont)
}
}
public var title1B: UIFont {
return self.title1.vc_bold
public var title1B: SharedFont {
let uiFont = self.title1.uiFont.vc_bold
if #available(iOS 13.0, *) {
return SharedFont(uiFont: uiFont, font: .title.bold())
} else {
return SharedFont(uiFont: uiFont)
}
}
public var title2: UIFont {
return self.font(forTextStyle: .title2)
public var title2: SharedFont {
let uiFont = self.font(forTextStyle: .title2)
if #available(iOS 13.0, *) {
return SharedFont(uiFont: uiFont, font: Font(uiFont))
} else if #available(iOS 14.0, *) {
return SharedFont(uiFont: uiFont, font: .title2)
} else {
return SharedFont(uiFont: uiFont)
}
}
public var title2B: UIFont {
return self.title2.vc_bold
public var title2B: SharedFont {
let uiFont = self.title2.uiFont.vc_bold
if #available(iOS 13.0, *) {
return SharedFont(uiFont: uiFont, font: Font(uiFont))
} else if #available(iOS 14.0, *) {
return SharedFont(uiFont: uiFont, font: .title2.bold())
} else {
return SharedFont(uiFont: uiFont)
}
}
public var title3: UIFont {
return self.font(forTextStyle: .title3)
public var title3: SharedFont {
let uiFont = self.font(forTextStyle: .title3)
if #available(iOS 13.0, *) {
return SharedFont(uiFont: uiFont, font: Font(uiFont))
} else if #available(iOS 14.0, *) {
return SharedFont(uiFont: uiFont, font: .title3)
} else {
return SharedFont(uiFont: uiFont)
}
}
public var title3SB: UIFont {
return self.title3.vc_semiBold
public var title3SB: SharedFont {
let uiFont = self.title3.uiFont.vc_semiBold
if #available(iOS 13.0, *) {
return SharedFont(uiFont: uiFont, font: Font(uiFont))
} else if #available(iOS 14.0, *) {
return SharedFont(uiFont: uiFont, font: .title3.weight(.semibold))
} else {
return SharedFont(uiFont: uiFont)
}
}
public var headline: UIFont {
return self.font(forTextStyle: .headline)
public var headline: SharedFont {
let uiFont = self.font(forTextStyle: .headline)
if #available(iOS 13.0, *) {
return SharedFont(uiFont: uiFont, font: .headline)
} else {
return SharedFont(uiFont: uiFont)
}
}
public var subheadline: UIFont {
return self.font(forTextStyle: .subheadline)
public var subheadline: SharedFont {
let uiFont = self.font(forTextStyle: .subheadline)
if #available(iOS 13.0, *) {
return SharedFont(uiFont: uiFont, font: .subheadline)
} else {
return SharedFont(uiFont: uiFont)
}
}
public var body: UIFont {
return self.font(forTextStyle: .body)
public var body: SharedFont {
let uiFont = self.font(forTextStyle: .body)
if #available(iOS 13.0, *) {
return SharedFont(uiFont: uiFont, font: .body)
} else {
return SharedFont(uiFont: uiFont)
}
}
public var bodySB: UIFont {
return self.body.vc_semiBold
public var bodySB: SharedFont {
let uiFont = self.body.uiFont.vc_semiBold
if #available(iOS 13.0, *) {
return SharedFont(uiFont: uiFont, font: .body.weight(.semibold))
} else {
return SharedFont(uiFont: uiFont)
}
}
public var callout: UIFont {
return self.font(forTextStyle: .callout)
public var callout: SharedFont {
let uiFont = self.font(forTextStyle: .callout)
if #available(iOS 13.0, *) {
return SharedFont(uiFont: uiFont, font: .callout)
} else {
return SharedFont(uiFont: uiFont)
}
}
public var calloutSB: UIFont {
return self.callout.vc_semiBold
public var calloutSB: SharedFont {
let uiFont = self.callout.uiFont.vc_semiBold
if #available(iOS 13.0, *) {
return SharedFont(uiFont: uiFont, font: .callout.weight(.semibold))
} else {
return SharedFont(uiFont: uiFont)
}
}
public var footnote: UIFont {
return self.font(forTextStyle: .footnote)
public var footnote: SharedFont {
let uiFont = self.font(forTextStyle: .footnote)
if #available(iOS 13.0, *) {
return SharedFont(uiFont: uiFont, font: .footnote)
} else {
return SharedFont(uiFont: uiFont)
}
}
public var footnoteSB: UIFont {
return self.footnote.vc_semiBold
public var footnoteSB: SharedFont {
let uiFont = self.footnote.uiFont.vc_semiBold
if #available(iOS 13.0, *) {
return SharedFont(uiFont: uiFont, font: .footnote.weight(.semibold))
} else {
return SharedFont(uiFont: uiFont)
}
}
public var caption1: UIFont {
return self.font(forTextStyle: .caption1)
public var caption1: SharedFont {
let uiFont = self.font(forTextStyle: .caption1)
if #available(iOS 13.0, *) {
return SharedFont(uiFont: uiFont, font: .caption)
} else {
return SharedFont(uiFont: uiFont)
}
}
public var caption1SB: UIFont {
return self.caption1.vc_semiBold
public var caption1SB: SharedFont {
let uiFont = self.caption1.uiFont.vc_semiBold
if #available(iOS 13.0, *) {
return SharedFont(uiFont: uiFont, font: .caption.weight(.semibold))
} else {
return SharedFont(uiFont: uiFont)
}
}
public var caption2: UIFont {
return self.font(forTextStyle: .caption2)
public var caption2: SharedFont {
let uiFont = self.font(forTextStyle: .caption2)
if #available(iOS 13.0, *) {
return SharedFont(uiFont: uiFont, font: Font(uiFont))
} else if #available(iOS 14.0, *) {
return SharedFont(uiFont: uiFont, font: .caption2)
} else {
return SharedFont(uiFont: uiFont)
}
}
public var caption2SB: UIFont {
return self.caption2.vc_semiBold
public var caption2SB: SharedFont {
let uiFont = self.caption2.uiFont.vc_semiBold
if #available(iOS 13.0, *) {
return SharedFont(uiFont: uiFont, font: Font(uiFont))
} else if #available(iOS 14.0, *) {
return SharedFont(uiFont: uiFont, font: .caption2.weight(.semibold))
} else {
return SharedFont(uiFont: uiFont)
}
}
}

1
changelog.d/5027.bugfix Normal file
View file

@ -0,0 +1 @@
Fonts: Fix dynamic type only working after a fresh launch on SwiftUI views.