Skip to content

Commit

Permalink
Merge pull request #38 from Minimistro32/master
Browse files Browse the repository at this point in the history
  • Loading branch information
tbaranes authored Jan 5, 2022
2 parents 9d4d9a8 + 63f6cdc commit b13c32a
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 1 deletion.
7 changes: 7 additions & 0 deletions .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// swift-tools-version:5.5.0
import PackageDescription

let package = Package(
Expand Down
20 changes: 19 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ But it won't always work as expected:
- Doesn't fit the label height
- Big top / bottom margins when the maxFontSize is huge
- Not really customisable
- Can't keep font size consistent across multiple labels
- ...

That's why `FittableFontLabel` exists:
Expand All @@ -28,6 +29,7 @@ That's why `FittableFontLabel` exists:
- Supports attributed string (custom line spacing...)
- Customize `maxFontSize` without using default label font size
- Auto-layout compliant
- Keep font size consistent across multiple labels using 'FittableRootView'
- `UILabel` extension if we want to use `UILabel`
- Customisable from xibs / storyboards when using the UILabel's subclass `FittableFontLabel`
- ...
Expand All @@ -44,8 +46,13 @@ That's why `FittableFontLabel` exists:

![](./assets/demo_single_line.gif)

**Consistent font size across multiple labels `FittableRootView`**

![](./assets/visual_fittable_root_view.png)

## Usage

### FittableFontLabel
```swift
let aFittableFontLabel = FittableFontLabel(frame: CGRect(x: 0, y: 0, width: 300, height: 100))
aFittableFontLabel.autoFittableFont = true
Expand All @@ -59,6 +66,16 @@ Check the sample project for advanced usage.

**Note:** The label `lineBreakMode` must be set to `NSLineBreakByWordWrapping` in order to work.

### FittableRootView
To get a consistent font size across multiple labels embed your FittableFontLabels in a `UIView` with the custom class `FittableRootView`. Then give each label you want to keep consistent the same link identifer.

The FittableRootView acts as the root of a search for FittableFontLabels with link identifiers. Every FittableFontLabel with an identifier found by the search is updated to use the smallest auto adjusted font size calculated for that identifier.

**Notes:**
- FittableRootView has an inspectable bool `searchView`. This allows you to disable the search, giving the `FittableRootView` identical behavior to a normal `UIView`.
- You can use multiple identifiers to standardize the font size across multiple sets of labels within the same view.
- When AutoAdjustFontSize is false, that label's font size is ignored in the search for smallest font size. This way if you know which label is going to be longest (i.e. the smallest font size) you can avoid computing font sizes that will go unused while still keeping font size consistent.

## Installation

- iOS 8.0+
Expand All @@ -76,6 +93,7 @@ Add `github "tbaranes/FittableFontLabel"` to your Cartfile.
FittableFontLabel is available on SPM. Just add the following to your Package file:

```swift
// swift-tools-version:5.5.0
import PackageDescription

let package = Package(
Expand Down Expand Up @@ -148,7 +166,7 @@ The scale factor that determines the smallest font size to use during drawing. T
@IBInspectable public var bottomInset: CGFloat = 0
```

These four properties allow you to set a marge in your label. That will change the rect where the font must fit. The default value is 0.
These four properties allow you to set a margin on your label. That will change the rect where the font must fit. The default value is 0.

## Contribution

Expand Down
3 changes: 3 additions & 0 deletions Source/FittableFontLabel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ open class FittableFontLabel: UILabel {
@IBInspectable public var rightInset: CGFloat = 0
@IBInspectable public var topInset: CGFloat = 0
@IBInspectable public var bottomInset: CGFloat = 0

/// Identifier
@IBInspectable public var linkIdentifier: String?

// MARK: Properties override

Expand Down
70 changes: 70 additions & 0 deletions Source/FittableRootView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
//
// FittableRootView.swift
//
//
// Created by Tyson_Freeze on 12/31/21.
//

import UIKit

/// A UIView subclass to give the FittableFontLabel package a root to recursively search for UILabels within.
open class FittableRootView: UIView {

/// If true, this view and it's subviews will be searched for any UILabels with a fontSizeLinkIdentifier.
@IBInspectable public var searchView: Bool = true

// MARK: Private

private var fontSizeLinks: [String : fontSizeLink] = [:]

private class fontSizeLink {
var minimumFontSize: CGFloat = CGFloat.greatestFiniteMagnitude
var labels: [FittableFontLabel] = []

init(label: FittableFontLabel) {
add(label: label)
}

func add(label: FittableFontLabel) {
labels.append(label)
if label.autoAdjustFontSize {
minimumFontSize = min(minimumFontSize, label.font.pointSize)
}
}
}

// MARK: Life cycle

open override func draw(_ rect: CGRect) {
if searchView {
updateFontSizeLinks(in: self)
standardizeFontSizes()
}
}

// MARK: Search

private func updateFontSizeLinks(in view: UIView) {
for subview in view.subviews {
if let label = subview as? FittableFontLabel {
if let fontSizeLinkIdentifier = label.linkIdentifier {
if let fontSizeLink = fontSizeLinks[fontSizeLinkIdentifier] {
fontSizeLink.add(label: label)
} else {
fontSizeLinks[fontSizeLinkIdentifier] = fontSizeLink(label: label)
}
}
} else {
updateFontSizeLinks(in: subview)
}
}
}

private func standardizeFontSizes() {
for fontLink in fontSizeLinks.values {
for label in fontLink.labels {
label.font = label.font.withSize(fontLink.minimumFontSize)
}
}
}
}
Binary file added assets/visual_fittable_root_view.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit b13c32a

Please sign in to comment.