Skip to content

Commit

Permalink
Add support for Dynamic Type (#560)
Browse files Browse the repository at this point in the history
* Clean up

* Add adjustsFontForContentSizeCategory to AnimateableLabel

* Add adjustsFontForContentSizeCategory properties

* Enable dynamic type in example

* Require iOS 11

* Update TMLabelBarButton default font

* Update TMTabItemBarButton default font

* Fix constraint warnings
  • Loading branch information
msaps authored Mar 8, 2021
1 parent f2fdfa0 commit d2e6d1e
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 15 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ All notable changes to this project will be documented in this file.
- `0.5.x` Releases - [0.5.0](#050) | [0.5.1](#051) | [0.5.2](#052) | [0.5.3](#053)
- `0.4.x` Releases - [0.4.0](#040) | [0.4.1](#041) | [0.4.2](#042) | [0.4.3](#043) | [0.4.4](#044) | [0.4.5](#045) | [0.4.6](#046) | [0.4.7](#047) | [0.4.8](#048)

---
## [2.11.0](https://github.com/uias/Tabman/releases/tag/2.11.0)
Released on 2021-03-XX

#### Added
- Support for Dynamic Type to `TMLabelBarButton` with `adjustsFontForContentSizeCategory`.
- Support for Dynamic Type to `TMTabItemBarButton` with `adjustsFontForContentSizeCategory`.

---
## [2.10.0](https://github.com/uias/Tabman/releases/tag/2.10.0)
Released on 2021-01-23
Expand Down
14 changes: 13 additions & 1 deletion Sources/Tabman/Bar/BarButton/Types/TMLabelBarButton.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ open class TMLabelBarButton: TMBarButton {

private struct Defaults {
static let contentInset = UIEdgeInsets(top: 12.0, left: 0.0, bottom: 12.0, right: 0.0)
static let font = UIFont.systemFont(ofSize: 17.0, weight: .semibold)
static let font = UIFont.preferredFont(forTextStyle: .headline)
static let text = "Item"
static let badgeLeadingInset: CGFloat = 8.0
}
Expand Down Expand Up @@ -104,6 +104,18 @@ open class TMLabelBarButton: TMBarButton {
label.font = selectedFont
}
}
/// A Boolean that indicates whether the object automatically updates its font when the device's content size category changes.
///
/// Defaults to `false`.
@available(iOS 11, *)
open var adjustsFontForContentSizeCategory: Bool {
get {
label.adjustsFontForContentSizeCategory
}
set {
label.adjustsFontForContentSizeCategory = newValue
}
}

/// How to vertically align the label within the button. Defaults to `.center`.
///
Expand Down
28 changes: 23 additions & 5 deletions Sources/Tabman/Bar/BarButton/Types/TMTabItemBarButton.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,18 @@ open class TMTabItemBarButton: TMBarButton {
label.font = font
}
}
/// A Boolean that indicates whether the object automatically updates its font when the device's content size category changes.
///
/// Defaults to `false`.
@available(iOS 11, *)
open var adjustsFontForContentSizeCategory: Bool {
get {
label.adjustsFontForContentSizeCategory
}
set {
label.adjustsFontForContentSizeCategory = newValue
}
}
/// Content Mode for the image view.
open var imageContentMode: UIView.ContentMode {
get {
Expand All @@ -92,7 +104,7 @@ open class TMTabItemBarButton: TMBarButton {
}
}

// MARK: Lifecycle
// MARK: Init

public required init(for item: TMBarItemable, intrinsicSuperview: UIView?) {
super.init(for: item, intrinsicSuperview: intrinsicSuperview)
Expand All @@ -106,6 +118,8 @@ open class TMTabItemBarButton: TMBarButton {
super.init(coder: aDecoder)
}

// MARK: Lifecycle

open override func layout(in view: UIView) {
super.layout(in: view)

Expand Down Expand Up @@ -263,13 +277,17 @@ open class TMTabItemBarButton: TMBarButton {
])

// Label / Image
let labelTrailing = container.trailingAnchor.constraint(equalTo: label.trailingAnchor, constant: labelPadding)
labelTrailing.priority = .init(999)
let imageViewLeading = imageView.leadingAnchor.constraint(greaterThanOrEqualTo: container.leadingAnchor, constant: imagePadding)
imageViewLeading.priority = .init(999)
constraints.append(contentsOf: [
imageView.topAnchor.constraint(equalTo: container.topAnchor, constant: imagePadding),
imageView.centerXAnchor.constraint(equalTo: container.centerXAnchor),
imageView.leadingAnchor.constraint(greaterThanOrEqualTo: container.leadingAnchor, constant: imagePadding),
imageViewLeading,
label.topAnchor.constraint(equalTo: imageView.bottomAnchor, constant: Defaults.labelTopPadding),
label.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: labelPadding),
container.trailingAnchor.constraint(equalTo: label.trailingAnchor, constant: labelPadding),
labelTrailing,
label.bottomAnchor.constraint(equalTo: container.bottomAnchor)
])

Expand All @@ -288,9 +306,9 @@ extension TMTabItemBarButton {
private func defaultFont(for device: UIDevice) -> UIFont {
switch device.userInterfaceIdiom {
case .pad:
return UIFont.systemFont(ofSize: 14.0, weight: .medium)
return UIFont.preferredFont(forTextStyle: .caption1)
default:
return UIFont.systemFont(ofSize: 10.0, weight: .medium)
return UIFont.preferredFont(forTextStyle: .caption2)
}
}
}
55 changes: 46 additions & 9 deletions Sources/Tabman/Bar/Generic/AnimateableLabel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,7 @@ internal class AnimateableLabel: UIView {
}
var font: UIFont? {
didSet {
textLayer.font = font
textLayer.fontSize = font?.pointSize ?? 17.0
invalidateIntrinsicContentSize()
superview?.setNeedsLayout()
superview?.layoutIfNeeded()
reloadTextLayerForCurrentFont()
}
}
var textAlignment: NSTextAlignment? {
Expand All @@ -52,30 +48,71 @@ internal class AnimateableLabel: UIView {
}
}

private var _adjustsFontForContentSizeCategory = false
/// A Boolean that indicates whether the object automatically updates its font when the device's content size category changes.
///
/// Defaults to `false`.
@available(iOS 11, *)
var adjustsFontForContentSizeCategory: Bool {
get {
_adjustsFontForContentSizeCategory
}
set {
_adjustsFontForContentSizeCategory = newValue
reloadTextLayerForCurrentFont()
}
}

// MARK: Init

override init(frame: CGRect) {
super.init(frame: frame)
initialize()
commonInit()
}

required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
initialize()
commonInit()
}

private func initialize() {
private func commonInit() {

textLayer.truncationMode = .end
textLayer.contentsScale = UIScreen.main.scale
layer.addSublayer(textLayer)
}

// MARK: Lifecycle

override func layoutSubviews() {
super.layoutSubviews()

textLayer.frame = bounds
}

override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)

if #available(iOS 10, *) {
guard traitCollection.preferredContentSizeCategory != previousTraitCollection?.preferredContentSizeCategory else {
return
}
reloadTextLayerForCurrentFont()
}
}

private func reloadTextLayerForCurrentFont() {
if #available(iOS 11, *), adjustsFontForContentSizeCategory, let font = font, let textStyle = font.fontDescriptor.object(forKey: .textStyle) as? UIFont.TextStyle {
let font = UIFontMetrics(forTextStyle: textStyle).scaledFont(for: font)
textLayer.font = font
textLayer.fontSize = font.pointSize
} else {
textLayer.font = font
textLayer.fontSize = font?.pointSize ?? 17.0
}
invalidateIntrinsicContentSize()
superview?.setNeedsLayout()
superview?.layoutIfNeeded()
}
}

private extension AnimateableLabel {
Expand Down
3 changes: 3 additions & 0 deletions Sources/iOS/TabViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ class TabViewController: TabmanViewController, PageboyViewControllerDataSource,
bar.buttons.customize {
$0.tintColor = UIColor.tabmanForeground.withAlphaComponent(0.4)
$0.selectedTintColor = .tabmanForeground
if #available(iOS 11, *) {
$0.adjustsFontForContentSizeCategory = true
}
}
bar.indicator.tintColor = .tabmanForeground

Expand Down

0 comments on commit d2e6d1e

Please sign in to comment.