├── .swift-version
├── assets
├── demo.gif
├── demo_attributed.gif
├── demo_single_line.gif
└── visual_fittable_root_view.png
├── Package.swift
├── FittableFontLabel Example
├── iOS Example
│ ├── Assets.xcassets
│ │ ├── Contents.json
│ │ ├── App Icon & Top Shelf Image.brandassets
│ │ │ ├── App Icon - Large.imagestack
│ │ │ │ ├── Back.imagestacklayer
│ │ │ │ │ ├── Contents.json
│ │ │ │ │ └── Content.imageset
│ │ │ │ │ │ └── Contents.json
│ │ │ │ ├── Front.imagestacklayer
│ │ │ │ │ ├── Contents.json
│ │ │ │ │ └── Content.imageset
│ │ │ │ │ │ └── Contents.json
│ │ │ │ ├── Middle.imagestacklayer
│ │ │ │ │ ├── Contents.json
│ │ │ │ │ └── Content.imageset
│ │ │ │ │ │ └── Contents.json
│ │ │ │ └── Contents.json
│ │ │ ├── App Icon - Small.imagestack
│ │ │ │ ├── Back.imagestacklayer
│ │ │ │ │ ├── Contents.json
│ │ │ │ │ └── Content.imageset
│ │ │ │ │ │ └── Contents.json
│ │ │ │ ├── Front.imagestacklayer
│ │ │ │ │ ├── Contents.json
│ │ │ │ │ └── Content.imageset
│ │ │ │ │ │ └── Contents.json
│ │ │ │ ├── Middle.imagestacklayer
│ │ │ │ │ ├── Contents.json
│ │ │ │ │ └── Content.imageset
│ │ │ │ │ │ └── Contents.json
│ │ │ │ └── Contents.json
│ │ │ ├── Top Shelf Image.imageset
│ │ │ │ └── Contents.json
│ │ │ └── Contents.json
│ │ ├── LaunchImage.launchimage
│ │ │ └── Contents.json
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── AppDelegate.swift
│ ├── Info.plist
│ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ └── ViewController.swift
├── FittableFontLabel Example.xcodeproj
│ ├── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ ├── xcshareddata
│ │ └── xcschemes
│ │ │ └── iOS Example.xcscheme
│ └── project.pbxproj
└── .swiftlint.yml
├── .swiftpm
└── xcode
│ └── package.xcworkspace
│ └── contents.xcworkspacedata
├── FittableFontLabel
├── FittableFontLabel.xcodeproj
│ ├── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ ├── xcshareddata
│ │ └── xcschemes
│ │ │ └── FittableFontLabel iOS.xcscheme
│ └── project.pbxproj
├── FittableFontLabel iOS
│ ├── FittableFontLabel.h
│ └── Info.plist
├── .swiftlint.yml
└── FittableFontLabel iOS Tests
│ ├── Info.plist
│ └── FittableFontLabelTests.swift
├── FittableFontLabel.xcworkspace
├── xcshareddata
│ └── IDEWorkspaceChecks.plist
└── contents.xcworkspacedata
├── .gitignore
├── FittableFontLabel.podspec
├── LICENSE
├── .travis.yml
├── Source
├── FittableRootView.swift
├── FittableFontLabel.swift
└── UILabelExtension.swift
├── CHANGELOG.md
└── README.md
/.swift-version:
--------------------------------------------------------------------------------
1 | 4.2
--------------------------------------------------------------------------------
/assets/demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tbaranes/FittableFontLabel/HEAD/assets/demo.gif
--------------------------------------------------------------------------------
/assets/demo_attributed.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tbaranes/FittableFontLabel/HEAD/assets/demo_attributed.gif
--------------------------------------------------------------------------------
/assets/demo_single_line.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tbaranes/FittableFontLabel/HEAD/assets/demo_single_line.gif
--------------------------------------------------------------------------------
/assets/visual_fittable_root_view.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tbaranes/FittableFontLabel/HEAD/assets/visual_fittable_root_view.png
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:5.5.0
2 | import PackageDescription
3 |
4 | let package = Package(
5 | name: "FittableFontLabel"
6 | )
--------------------------------------------------------------------------------
/FittableFontLabel Example/iOS Example/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/FittableFontLabel Example/iOS Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Back.imagestacklayer/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/FittableFontLabel Example/iOS Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Front.imagestacklayer/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/FittableFontLabel Example/iOS Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/FittableFontLabel Example/iOS Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Front.imagestacklayer/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/FittableFontLabel Example/iOS Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Middle.imagestacklayer/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/FittableFontLabel Example/iOS Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Middle.imagestacklayer/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/FittableFontLabel Example/FittableFontLabel Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/FittableFontLabel/FittableFontLabel.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/FittableFontLabel Example/iOS Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "scale" : "1x"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/FittableFontLabel.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/FittableFontLabel Example/iOS Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Back.imagestacklayer/Content.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "scale" : "1x"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/FittableFontLabel Example/iOS Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Front.imagestacklayer/Content.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "scale" : "1x"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/FittableFontLabel Example/iOS Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "scale" : "1x"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/FittableFontLabel Example/iOS Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Content.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "scale" : "1x"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/FittableFontLabel Example/iOS Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Front.imagestacklayer/Content.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "scale" : "1x"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/FittableFontLabel Example/iOS Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "tv",
5 | "scale" : "1x"
6 | }
7 | ],
8 | "info" : {
9 | "version" : 1,
10 | "author" : "xcode"
11 | }
12 | }
--------------------------------------------------------------------------------
/FittableFontLabel Example/iOS Example/Assets.xcassets/LaunchImage.launchimage/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "orientation" : "landscape",
5 | "idiom" : "tv",
6 | "extent" : "full-screen",
7 | "minimum-system-version" : "9.0",
8 | "scale" : "1x"
9 | }
10 | ],
11 | "info" : {
12 | "version" : 1,
13 | "author" : "xcode"
14 | }
15 | }
--------------------------------------------------------------------------------
/FittableFontLabel.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/FittableFontLabel Example/iOS Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "layers" : [
3 | {
4 | "filename" : "Front.imagestacklayer"
5 | },
6 | {
7 | "filename" : "Middle.imagestacklayer"
8 | },
9 | {
10 | "filename" : "Back.imagestacklayer"
11 | }
12 | ],
13 | "info" : {
14 | "version" : 1,
15 | "author" : "xcode"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/FittableFontLabel Example/iOS Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "layers" : [
3 | {
4 | "filename" : "Front.imagestacklayer"
5 | },
6 | {
7 | "filename" : "Middle.imagestacklayer"
8 | },
9 | {
10 | "filename" : "Back.imagestacklayer"
11 | }
12 | ],
13 | "info" : {
14 | "version" : 1,
15 | "author" : "xcode"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/FittableFontLabel Example/iOS Example/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // IncrementableLabel
4 | //
5 | // Created by Tom Baranes on 20/01/16.
6 | // Copyright © 2016 Recisio. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | private func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
18 | return true
19 | }
20 |
21 | }
22 |
23 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Mac OS X
2 | .DS_Store
3 |
4 | # Xcode
5 |
6 | ## Build generated
7 | build/
8 | DerivedData
9 |
10 | ## Various settings
11 | *.pbxuser
12 | !default.pbxuser
13 | *.mode1v3
14 | !default.mode1v3
15 | *.mode2v3
16 | !default.mode2v3
17 | *.perspectivev3
18 | !default.perspectivev3
19 | xcuserdata
20 |
21 | ## Other
22 | *.xccheckout
23 | *.moved-aside
24 | *.xcuserstate
25 | *.xcscmblueprint
26 |
27 | ## Obj-C/Swift specific
28 | *.hmap
29 | *.ipa
30 |
31 | ## Playgrounds
32 | timeline.xctimeline
33 | playground.xcworkspace
34 |
35 | # Swift Package Manager
36 | .build/
37 |
38 | # Carthage
39 | Carthage/Build
--------------------------------------------------------------------------------
/FittableFontLabel Example/.swiftlint.yml:
--------------------------------------------------------------------------------
1 | identifier_name:
2 | min_length: 2
3 | excluded:
4 | - x
5 |
6 | type_name:
7 | excluded:
8 | - T
9 |
10 | line_length: 150
11 | file_length: 500
12 | number_separator:
13 | minimum_length: 5
14 |
15 | opt_in_rules:
16 | - closure_spacing
17 | - conditional_returns_on_newline
18 | - empty_count
19 | - explicit_init
20 | - overridden_super_call
21 | - redundant_nil_coalescing
22 | - nimble_operator
23 | - closure_end_indentation
24 | - first_where
25 | - attributes
26 | - operator_usage_whitespace
27 | - prohibited_super_call
28 | - number_separator
29 | - object_literal
30 | - fatal_error_message
31 |
--------------------------------------------------------------------------------
/FittableFontLabel/FittableFontLabel iOS/FittableFontLabel.h:
--------------------------------------------------------------------------------
1 | //
2 | // FittableFontLabel.h
3 | // FittableFontLabel
4 | //
5 | // Created by Tom Baranes on 25/04/16.
6 | // Copyright © 2016 Tom Baranes. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for FittableFontLabel.
12 | FOUNDATION_EXPORT double FittableFontLabelVersionNumber;
13 |
14 | //! Project version string for FittableFontLabel.
15 | FOUNDATION_EXPORT const unsigned char FittableFontLabelVersionString[];
16 |
17 | // In this header, you should import all the public headers of your framework using statements like #import
18 |
19 |
20 |
--------------------------------------------------------------------------------
/FittableFontLabel Example/iOS Example/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "assets" : [
3 | {
4 | "size" : "1280x768",
5 | "idiom" : "tv",
6 | "filename" : "App Icon - Large.imagestack",
7 | "role" : "primary-app-icon"
8 | },
9 | {
10 | "size" : "400x240",
11 | "idiom" : "tv",
12 | "filename" : "App Icon - Small.imagestack",
13 | "role" : "primary-app-icon"
14 | },
15 | {
16 | "size" : "1920x720",
17 | "idiom" : "tv",
18 | "filename" : "Top Shelf Image.imageset",
19 | "role" : "top-shelf-image"
20 | }
21 | ],
22 | "info" : {
23 | "version" : 1,
24 | "author" : "xcode"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/FittableFontLabel/.swiftlint.yml:
--------------------------------------------------------------------------------
1 | line_length: 180
2 | opt_in_rules:
3 | - closure_spacing
4 | - conditional_returns_on_newline
5 | - empty_count
6 | - explicit_init
7 | - overridden_super_call
8 | - redundant_nil_coalescing
9 | - nimble_operator
10 | - closure_end_indentation
11 | - first_where
12 | - attributes
13 | - operator_usage_whitespace
14 | - prohibited_super_call
15 | - number_separator
16 | - object_literal
17 | - fatal_error_message
18 | - private_outlet
19 | - implicit_return
20 | - multiline_parameters
21 | - vertical_parameter_alignment_on_call
22 | - unneeded_parentheses_in_closure_argument
23 | - joined_default_parameter
24 | - pattern_matching_keywords
25 | - array_init
26 | - contains_over_first_not_nil
27 | - let_var_whitespace
28 | - literal_expression_end_indentation
29 | # - trailing_closure // false positive
30 | included:
31 | - ../Source
--------------------------------------------------------------------------------
/FittableFontLabel/FittableFontLabel iOS Tests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/FittableFontLabel/FittableFontLabel iOS/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 3.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(CURRENT_PROJECT_VERSION)
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/FittableFontLabel.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 |
3 | # ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
4 |
5 | s.name = "FittableFontLabel"
6 | s.module_name = "FittableFontLabel"
7 | s.version = "3.0.0"
8 | s.summary = "UILabel (extension) that adjust the font size to fit a rect (width and height)."
9 | s.description = "UILabel (extension or subclass) that adjust the font size to fit a frame: width and height if multilines, width only if single lines"
10 | s.homepage = "https://github.com/tbaranes/FittableFontLabel"
11 | s.license = { :type => "MIT", :file => "LICENSE" }
12 | s.author = { "Tom Baranes" => "tom.baranes@gmail.com" }
13 | s.source = { :git => "https://github.com/tbaranes/FittableFontLabel.git", :tag => "#{s.version}" }
14 |
15 | # ――― Spec tech ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
16 |
17 | s.ios.deployment_target = '8.0'
18 | s.requires_arc = true
19 | s.source_files = 'Source/*.swift'
20 |
21 | end
22 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Tom Baranes
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/FittableFontLabel Example/iOS Example/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "ipad",
35 | "size" : "29x29",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "ipad",
40 | "size" : "29x29",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "40x40",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "40x40",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "76x76",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "76x76",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "83.5x83.5",
66 | "scale" : "2x"
67 | }
68 | ],
69 | "info" : {
70 | "version" : 1,
71 | "author" : "xcode"
72 | }
73 | }
--------------------------------------------------------------------------------
/FittableFontLabel Example/iOS Example/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | UISupportedInterfaceOrientations~ipad
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/FittableFontLabel Example/iOS Example/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: objective-c
2 | osx_image: xcode10.2
3 | notifications:
4 | email: false
5 | branches:
6 | only:
7 | - master
8 | env:
9 | global:
10 | - LC_CTYPE=en_US.UTF-8
11 | - LANG=en_US.UTF-8
12 | - WORKSPACE=FittableFontLabel.xcworkspace
13 | - IOS_FRAMEWORK_SCHEME="FittableFontLabel iOS"
14 | - EXAMPLE_SCHEME="iOS Example"
15 | matrix:
16 | - DESTINATION="OS=12.2,name=iPhone Xʀ" SCHEME="$IOS_FRAMEWORK_SCHEME" RUN_TESTS="YES" BUILD_EXAMPLE="YES"
17 | - DESTINATION="OS=11.4,name=iPhone 6" SCHEME="$IOS_FRAMEWORK_SCHEME" RUN_TESTS="YES" BUILD_EXAMPLE="YES"
18 | script:
19 | - set -o pipefail
20 | - xcodebuild -version
21 | - xcodebuild -showsdks
22 |
23 | # Build Framework in Debug and Run Tests if specified
24 | - if [ $RUN_TESTS == "YES" ]; then
25 | xcodebuild -workspace "$WORKSPACE" -scheme "$SCHEME" -destination "$DESTINATION" -configuration Debug ONLY_ACTIVE_ARCH=NO ENABLE_TESTABILITY=YES test | xcpretty;
26 | else
27 | xcodebuild -workspace "$WORKSPACE" -scheme "$SCHEME" -destination "$DESTINATION" -configuration Debug ONLY_ACTIVE_ARCH=NO build | xcpretty;
28 | fi
29 |
30 | # Build Framework in Release and Run Tests if specified
31 | - if [ $RUN_TESTS == "YES" ]; then
32 | xcodebuild -workspace "$WORKSPACE" -scheme "$SCHEME" -destination "$DESTINATION" -configuration Release ONLY_ACTIVE_ARCH=NO ENABLE_TESTABILITY=YES test | xcpretty;
33 | else
34 | xcodebuild -workspace "$WORKSPACE" -scheme "$SCHEME" -destination "$DESTINATION" -configuration Release ONLY_ACTIVE_ARCH=NO build | xcpretty;
35 | fi
36 |
37 | # Build Example in Debug if specified
38 | - if [ $BUILD_EXAMPLE == "YES" ]; then
39 | xcodebuild -workspace "$WORKSPACE" -scheme "$EXAMPLE_SCHEME" -destination "$DESTINATION" -configuration Debug ONLY_ACTIVE_ARCH=NO build | xcpretty;
40 | fi
41 |
42 | # Run `pod lib lint` if specified
43 | - if [ $POD_LINT == "YES" ]; then
44 | pod lib lint;
45 | fi
46 |
47 | after_success:
48 | - sleep 5 # Workaround for https://github.com/travis-ci/travis-ci/issues/4725
--------------------------------------------------------------------------------
/Source/FittableRootView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FittableRootView.swift
3 | //
4 | //
5 | // Created by Tyson_Freeze on 12/31/21.
6 | //
7 |
8 | import UIKit
9 |
10 | /// A UIView subclass to give the FittableFontLabel package a root to recursively search for UILabels within.
11 | open class FittableRootView: UIView {
12 |
13 | /// If true, this view and it's subviews will be searched for any UILabels with a fontSizeLinkIdentifier.
14 | @IBInspectable public var searchView: Bool = true
15 |
16 | // MARK: Private
17 |
18 | private var fontSizeLinks: [String : fontSizeLink] = [:]
19 |
20 | private class fontSizeLink {
21 | var minimumFontSize: CGFloat = CGFloat.greatestFiniteMagnitude
22 | var labels: [FittableFontLabel] = []
23 |
24 | init(label: FittableFontLabel) {
25 | add(label: label)
26 | }
27 |
28 | func add(label: FittableFontLabel) {
29 | labels.append(label)
30 | if label.autoAdjustFontSize {
31 | minimumFontSize = min(minimumFontSize, label.font.pointSize)
32 | }
33 | }
34 | }
35 |
36 | // MARK: Life cycle
37 |
38 | open override func draw(_ rect: CGRect) {
39 | if searchView {
40 | updateFontSizeLinks(in: self)
41 | standardizeFontSizes()
42 | }
43 | }
44 |
45 | // MARK: Search
46 |
47 | private func updateFontSizeLinks(in view: UIView) {
48 | for subview in view.subviews {
49 | if let label = subview as? FittableFontLabel {
50 | if let fontSizeLinkIdentifier = label.linkIdentifier {
51 | if let fontSizeLink = fontSizeLinks[fontSizeLinkIdentifier] {
52 | fontSizeLink.add(label: label)
53 | } else {
54 | fontSizeLinks[fontSizeLinkIdentifier] = fontSizeLink(label: label)
55 | }
56 | }
57 | } else {
58 | updateFontSizeLinks(in: subview)
59 | }
60 | }
61 | }
62 |
63 | private func standardizeFontSizes() {
64 | for fontLink in fontSizeLinks.values {
65 | for label in fontLink.labels {
66 | label.font = label.font.withSize(fontLink.minimumFontSize)
67 | }
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to the project will be documented in this file.
4 |
5 | ---
6 |
7 | ## Next
8 |
9 | #### API breaking changes
10 |
11 | N/A
12 |
13 | #### Enhancements
14 |
15 | - Swift 5 and Xcode 10.2 support
16 |
17 | #### Bugfixes
18 |
19 | - Fix rounding when calculated font size has long decimals therefore rendering results with cutting off the last line (probably due to rounding up in UILabel rendering)
20 |
21 | ## [3.0.0](https://github.com/tbaranes/FittableFontLabel/releases/tag/3.0.0) (18-09-2018)
22 |
23 | #### API breaking changes
24 |
25 | - Swift 4.2 and Xcode 10 support
26 |
27 | #### Enhancements
28 |
29 | - Swift 4 and Xcode 9 support
30 |
31 | ## [2.0.0](https://github.com/tbaranes/FittableFontLabel/releases/tag/2.0.0) (10-11-2017)
32 |
33 |
34 | #### Enhancements
35 |
36 | - Swift 4 and Xcode 9 support
37 |
38 | ## [1.4.0](https://github.com/tbaranes/FittableFontLabel/releases/tag/1.4.0) (11-09-2016)
39 |
40 | #### API breaking changes
41 |
42 | - Swift 3 compatibility
43 |
44 | #### Bugfixes
45 |
46 | - Improved issue with long strings in small labels getting truncated
47 |
48 | ## [1.3.0](https://github.com/tbaranes/FittableFontLabel/releases/tag/1.3.0) (15/08/2016)
49 |
50 | #### Enhancements
51 |
52 | - Improving performance by using binary search instead of simple loop. That may prevent xcode freezing
53 |
54 | #### Bugfixes
55 |
56 | - Fixed `fontSizeThatFits` when used with empty strings
57 |
58 | ## [1.2.0](https://github.com/tbaranes/FittableFontLabel/releases/tag/1.2.0) (01/08/2016)
59 |
60 | #### Enhancements
61 |
62 | - Improving default value of `fontSizeToFit` in `UILabelExtension`. Default value is now explicitly 100
63 | - Added `fontSizeThatFits` method in `UILabelExtension` that returns a font size of the given text which can just fit the given `CGSize`.
64 |
65 | ## [1.1.0](https://github.com/tbaranes/FittableFontLabel/releases/tag/1.1.0) (25/04/2016)
66 |
67 | #### API breaking changes
68 |
69 | N/A
70 |
71 | #### Enhancements
72 |
73 | - `FittableFontLabel` now support `topInset`, `leftInset`, `bottomInset`, `rightInset`
74 |
75 | #### Bugfixes
76 |
77 | - Fixed interface builder freeze
78 |
79 | ## [1.0.1](https://github.com/tbaranes/FittableFontLabel/releases/tag/1.0.1) (29/03/2016)
80 |
81 | #### Enhancements
82 |
83 | - Renaming the extension class
84 |
85 | #### Bugfixes
86 |
87 | - Fixed inspectable attributes for `FittableFontLabel`
88 |
89 | ## [1.0.0](https://github.com/tbaranes/FittableFontLabel/releases/tag/1.0.0) (27/03/2016)
90 |
91 | First version
92 |
--------------------------------------------------------------------------------
/FittableFontLabel Example/iOS Example/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // FittableLabel
4 | //
5 | // Created by Tom Baranes on 20/01/16.
6 | // Copyright © 2016 Recisio. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import FittableFontLabel
11 |
12 | class ViewController: UIViewController {
13 |
14 | // MARK: Properties IB
15 |
16 | @IBOutlet weak var autoFittableLabel: FittableFontLabel! {
17 | didSet {
18 | setup(label: autoFittableLabel)
19 | }
20 | }
21 |
22 | @IBOutlet weak var labelFittableWidthAndHeight: UILabel! {
23 | didSet {
24 | labelFittableWidthAndHeight.text = words[0]
25 | setup(label: labelFittableWidthAndHeight)
26 | }
27 | }
28 |
29 | @IBOutlet weak var labelFittableWidth: UILabel! {
30 | didSet {
31 | setup(label: labelFittableWidth)
32 | labelFittableWidth.text = words[0..<3].joined(separator: " ")
33 | }
34 | }
35 |
36 | @IBOutlet weak var attributedLabelFittable: UILabel! {
37 | didSet {
38 | setup(label: attributedLabelFittable)
39 | attributedLabelFittable.text = words[0]
40 | }
41 | }
42 |
43 | @IBOutlet weak var autoFittableLabelWithInsets: FittableFontLabel! {
44 | didSet {
45 | setup(label: autoFittableLabelWithInsets)
46 | }
47 | }
48 |
49 | // MARK: Properties
50 |
51 | let words = [String](["apple", "orange", "banana", "grape", "kiwi", "mango", "lychee", "lemon", "coconut", "pear", "pineapple", "peach", "strawberry", "fig", "lime", "papaya", "nectarine", "plum", "quince", "raspberry", "ohajiki", "watermelon", "blackberry", "cherry", "avocado"])
52 |
53 | // MARK: Life cycle
54 |
55 | override func viewDidLoad() {
56 | super.viewDidLoad()
57 | let timer = Timer.scheduledTimer(timeInterval: 0.7, target: self, selector: #selector(reloadLabels), userInfo: nil, repeats: true);
58 | RunLoop.main.add(timer, forMode: RunLoop.Mode.common)
59 |
60 |
61 | self.view.backgroundColor = UIColor(white: 0.1, alpha: 1.0)
62 | }
63 |
64 | private func setup(label: UILabel) {
65 | label.layer.borderWidth = 2.0
66 | label.layer.borderColor = UIColor.red.cgColor
67 | label.layer.cornerRadius = 3.0
68 | }
69 |
70 | // MARK:
71 |
72 | @objc
73 | func reloadLabels() {
74 | let random = Int(arc4random_uniform(UInt32(self.words.count)))
75 | labelFittableWidthAndHeight.text = String(format: "%@ %@", labelFittableWidthAndHeight.text!, words[random])
76 | labelFittableWidthAndHeight.fontSizeToFit(maxFontSize: 50)
77 | autoFittableLabel.text = labelFittableWidthAndHeight.text
78 | autoFittableLabelWithInsets.text = labelFittableWidthAndHeight.text
79 |
80 | let paragraph = NSMutableParagraphStyle()
81 | paragraph.lineSpacing = 10.0
82 | paragraph.alignment = .center
83 | let attributes = [NSAttributedString.Key.paragraphStyle: paragraph]
84 | let attributedText = NSAttributedString(string: labelFittableWidthAndHeight.text!, attributes: attributes)
85 | attributedLabelFittable.attributedText = attributedText
86 | attributedLabelFittable.fontSizeToFit(maxFontSize: 50)
87 |
88 | let screenWidth = labelFittableWidth.window!.screen.bounds.width
89 | let newWidth = CGFloat(arc4random_uniform(UInt32(screenWidth - 50.0)))
90 | labelFittableWidth.frame.size.width = newWidth
91 | labelFittableWidth.fontSizeToFit(maxFontSize: 50)
92 | }
93 |
94 | }
95 |
--------------------------------------------------------------------------------
/FittableFontLabel Example/FittableFontLabel Example.xcodeproj/xcshareddata/xcschemes/iOS Example.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/Source/FittableFontLabel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FittableFontLabel.swift
3 | //
4 | // Copyright (c) 2016 Tom Baranes (https://github.com/tbaranes)
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | import UIKit
25 |
26 | // An UILabel subclass allowing you to automatize the process of adjusting the font size.
27 | @IBDesignable
28 | open class FittableFontLabel: UILabel {
29 |
30 | // MARK: Properties
31 |
32 | /// If true, the font size will be adjusted each time that the text or the frame change.
33 | @IBInspectable public var autoAdjustFontSize: Bool = true
34 |
35 | /// The biggest font size to use during drawing. The default value is the current font size
36 | @IBInspectable public var maxFontSize: CGFloat = CGFloat.nan
37 |
38 | /// The scale factor that determines the smallest font size to use during drawing. The default value is 0.1
39 | @IBInspectable public var minFontScale: CGFloat = CGFloat.nan
40 |
41 | /// UIEdgeInset
42 | @IBInspectable public var leftInset: CGFloat = 0
43 | @IBInspectable public var rightInset: CGFloat = 0
44 | @IBInspectable public var topInset: CGFloat = 0
45 | @IBInspectable public var bottomInset: CGFloat = 0
46 |
47 | /// Identifier
48 | @IBInspectable public var linkIdentifier: String?
49 |
50 | // MARK: Properties override
51 |
52 | open override var text: String? {
53 | didSet {
54 | adjustFontSize()
55 | }
56 | }
57 |
58 | open override var frame: CGRect {
59 | didSet {
60 | adjustFontSize()
61 | }
62 | }
63 |
64 | // MARK: Private
65 |
66 | var isUpdatingFromIB = false
67 |
68 | // MARK: Life cycle
69 |
70 | open override func prepareForInterfaceBuilder() {
71 | super.prepareForInterfaceBuilder()
72 | isUpdatingFromIB = autoAdjustFontSize
73 | adjustFontSize()
74 | }
75 |
76 | open override func awakeFromNib() {
77 | super.awakeFromNib()
78 | isUpdatingFromIB = autoAdjustFontSize
79 | adjustFontSize()
80 | }
81 |
82 | open override func layoutSubviews() {
83 | super.layoutSubviews()
84 | if !isUpdatingFromIB {
85 | adjustFontSize()
86 | }
87 | isUpdatingFromIB = false
88 | }
89 |
90 | // MARK: Insets
91 |
92 | open override func drawText(in rect: CGRect) {
93 | let insets = UIEdgeInsets(top: topInset, left: leftInset, bottom: bottomInset, right: rightInset)
94 | super.drawText(in: rect.inset(by: insets))
95 | }
96 |
97 | }
98 |
99 | // MARK: Helpers
100 |
101 | extension FittableFontLabel {
102 |
103 | private func adjustFontSize() {
104 | if autoAdjustFontSize {
105 | fontSizeToFit(maxFontSize: maxFontSize, minFontScale: minFontScale)
106 | }
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/FittableFontLabel/FittableFontLabel.xcodeproj/xcshareddata/xcschemes/FittableFontLabel iOS.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
49 |
50 |
51 |
52 |
53 |
54 |
64 |
65 |
71 |
72 |
73 |
74 |
75 |
76 |
82 |
83 |
89 |
90 |
91 |
92 |
94 |
95 |
98 |
99 |
100 |
--------------------------------------------------------------------------------
/FittableFontLabel/FittableFontLabel iOS Tests/FittableFontLabelTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FittableFontLabelTests.swift
3 | // FittableFontLabelTests
4 | //
5 | // Created by Tom Baranes on 25/04/16.
6 | // Copyright © 2016 Tom Baranes. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import FittableFontLabel
11 |
12 | class FittableFontLabelTests: XCTestCase {
13 |
14 | override func setUp() {
15 | super.setUp()
16 | }
17 |
18 | override func tearDown() {
19 | super.tearDown()
20 | }
21 |
22 | // MARK: Helper
23 |
24 | let shortText = "Etiam turpis elit"
25 | // swiftlint:disable:next line_length
26 | let longText = "Etiam turpis elit, efficitur nec suscipit vitae, aliquam vitae lorem. Aenean mauris tortor, semper vel facilisis nec, facilisis ut neque. Aliquam erat volutpat. Nam eget varius mauris, ut condimentum quam. Duis ex nisi, iaculis in ex ut, lobortis pretium est. Sed non lorem venenatis, fermentum quam aliquet, ultrices arcu. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Duis ullamcorper convallis tellus, vitae bibendum mi dapibus in. Morbi pellentesque aliquet urna, id aliquet orci efficitur sed. Donec et mi urna. Proin sagittis semper massa in semper."
27 | }
28 |
29 | // MARK: - Single line
30 |
31 | extension FittableFontLabelTests {
32 |
33 | // MARK: Expecting size
34 |
35 | func testSingleLine_expectingMinSize() {
36 | let label = UILabel(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
37 | label.text = longText
38 | let fontSize = label.fontSizeThatFits(text: longText, maxFontSize: 20, minFontScale: 0.1,
39 | rectSize: CGSize(width: 20, height: 20))
40 | XCTAssertEqual(fontSize, 2.0)
41 | }
42 |
43 | func testSingleLine_expectingMaxSize() {
44 | let label = UILabel(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
45 | label.text = longText
46 | let fontSize = label.fontSizeThatFits(text: shortText, maxFontSize: 20, minFontScale: 0.1,
47 | rectSize: CGSize(width: 1000, height: 1000))
48 | XCTAssertEqual(fontSize, 20)
49 | }
50 |
51 | func testSingleLine_expectingMediumSize() {
52 | let label = UILabel(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
53 | label.text = longText
54 | let fontSize = label.fontSizeThatFits(text: shortText, maxFontSize: 100, minFontScale: 0.1,
55 | rectSize: CGSize(width: 100, height: 100))
56 | XCTAssertTrue(fontSize > 100 * 0.1)
57 | XCTAssertTrue(fontSize < 100)
58 | }
59 |
60 | // MARK: Special case
61 |
62 | func testSingleLine_withEmptyTextLabel() {
63 | let label = UILabel(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
64 | let fontSize = label.fontSizeThatFits(text: shortText, maxFontSize: 20, minFontScale: 0.1,
65 | rectSize: CGSize(width: 1000, height: 1000))
66 | XCTAssertEqual(fontSize, 20)
67 | }
68 |
69 | func testSingleLine_withSizeZero() {
70 | let label = UILabel(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
71 | let fontSize = label.fontSizeThatFits(text: shortText, maxFontSize: 20, minFontScale: 0.1,
72 | rectSize: CGSize(width: 0, height: 0))
73 | XCTAssertEqual(fontSize, 2.0)
74 | }
75 |
76 | }
77 |
78 | // MARK: - Multiline line
79 |
80 | extension FittableFontLabelTests {
81 |
82 | // MARK: Expecting size
83 |
84 | func testMultiline_expectingMinSize() {
85 | let label = UILabel(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
86 | label.numberOfLines = 0
87 | label.text = longText
88 | let fontSize = label.fontSizeThatFits(text: longText, maxFontSize: 20, minFontScale: 0.1,
89 | rectSize: CGSize(width: 0, height: 0))
90 | XCTAssertEqual(fontSize, 2.0)
91 | }
92 |
93 | func testMultiline_expectingMaxSize() {
94 | let label = UILabel(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
95 | label.numberOfLines = 0
96 | label.text = longText
97 | let fontSize = label.fontSizeThatFits(text: shortText, maxFontSize: 20, minFontScale: 0.1,
98 | rectSize: CGSize(width: 1000, height: 1000))
99 | XCTAssertEqual(fontSize, 20)
100 | }
101 |
102 | func testMultiline_expectingMediumSize() {
103 | let label = UILabel(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
104 | label.numberOfLines = 0
105 | label.text = longText
106 | let fontSize = label.fontSizeThatFits(text: shortText, maxFontSize: 100, minFontScale: 0.1,
107 | rectSize: CGSize(width: 100, height: 100))
108 | XCTAssertTrue(fontSize > 100 * 0.1)
109 | XCTAssertTrue(fontSize < 100)
110 | }
111 |
112 | // MARK: Special case
113 |
114 | func testMultiline_withEmptyTextLabel() {
115 | let label = UILabel(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
116 | label.numberOfLines = 0
117 | let fontSize = label.fontSizeThatFits(text: shortText, maxFontSize: 20, minFontScale: 0.1,
118 | rectSize: CGSize(width: 1000, height: 1000))
119 | XCTAssertEqual(fontSize, 20)
120 | }
121 |
122 | func testMultiline_withSizeZero() {
123 | let label = UILabel(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
124 | label.numberOfLines = 0
125 | let fontSize = label.fontSizeThatFits(text: shortText, maxFontSize: 20, minFontScale: 0.1,
126 | rectSize: CGSize(width: 0, height: 0))
127 | XCTAssertEqual(fontSize, 2.0)
128 | }
129 |
130 | }
131 |
--------------------------------------------------------------------------------
/Source/UILabelExtension.swift:
--------------------------------------------------------------------------------
1 | // FittableLabel.swift
2 | //
3 | // Copyright (c) 2016 Tom Baranes (https://github.com/tbaranes)
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | import UIKit
24 |
25 | extension UILabel {
26 |
27 | /**
28 | Resize the font to make the current text fit the label frame.
29 |
30 | - parameter maxFontSize: The max font size available
31 | - parameter minFontScale: The min font scale that the font will have
32 | - parameter rectSize: Rect size where the label must fit
33 | */
34 | public func fontSizeToFit(maxFontSize: CGFloat = 100, minFontScale: CGFloat = 0.1, rectSize: CGSize? = nil) {
35 | guard let unwrappedText = self.text else {
36 | return
37 | }
38 |
39 | let newFontSize = fontSizeThatFits(text: unwrappedText, maxFontSize: maxFontSize, minFontScale: minFontScale, rectSize: rectSize)
40 | font = font.withSize(newFontSize)
41 | }
42 |
43 | /**
44 | Returns a font size of a specific string in a specific font that fits a specific size
45 |
46 | - parameter text: The text to use
47 | - parameter maxFontSize: The max font size available
48 | - parameter minFontScale: The min font scale that the font will have
49 | - parameter rectSize: Rect size where the label must fit
50 | */
51 | public func fontSizeThatFits(text string: String, maxFontSize: CGFloat = 100, minFontScale: CGFloat = 0.1, rectSize: CGSize? = nil) -> CGFloat {
52 | let maxFontSize = maxFontSize.isNaN ? 100 : maxFontSize
53 | let minFontScale = minFontScale.isNaN ? 0.1 : minFontScale
54 | let minimumFontSize = maxFontSize * minFontScale
55 | let rectSize = rectSize ?? bounds.size
56 | guard !string.isEmpty else {
57 | return self.font.pointSize
58 | }
59 |
60 | let constraintSize = numberOfLines == 1 ?
61 | CGSize(width: CGFloat.greatestFiniteMagnitude, height: rectSize.height) :
62 | CGSize(width: rectSize.width, height: CGFloat.greatestFiniteMagnitude)
63 | let calculatedFontSize = binarySearch(string: string, minSize: minimumFontSize, maxSize: maxFontSize, size: rectSize, constraintSize: constraintSize)
64 | return (calculatedFontSize * 10.0).rounded(.down) / 10.0
65 | }
66 |
67 | }
68 |
69 | // MARK: - Helpers
70 |
71 | extension UILabel {
72 |
73 | private func currentAttributedStringAttributes() -> [NSAttributedString.Key: Any] {
74 | var newAttributes = [NSAttributedString.Key: Any]()
75 | attributedText?.enumerateAttributes(in: NSRange(0..<(text?.count ?? 0)), options: .longestEffectiveRangeNotRequired, using: { attributes, _, _ in
76 | newAttributes = attributes
77 | })
78 | return newAttributes
79 | }
80 |
81 | }
82 |
83 | // MARK: - Search
84 |
85 | extension UILabel {
86 |
87 | private enum FontSizeState {
88 | case fit, tooBig, tooSmall
89 | }
90 |
91 | private func binarySearch(string: String, minSize: CGFloat, maxSize: CGFloat, size: CGSize, constraintSize: CGSize) -> CGFloat {
92 | let fontSize = (minSize + maxSize) / 2
93 | var attributes = currentAttributedStringAttributes()
94 | attributes[NSAttributedString.Key.font] = font.withSize(fontSize)
95 |
96 | let rect = string.boundingRect(with: constraintSize, options: .usesLineFragmentOrigin, attributes: attributes, context: nil)
97 | let state = numberOfLines == 1 ? singleLineSizeState(rect: rect, size: size) : multiLineSizeState(rect: rect, size: size)
98 |
99 | // if the search range is smaller than 0.1 of a font size we stop
100 | // returning either side of min or max depending on the state
101 | let diff = maxSize - minSize
102 | guard diff > 0.1 else {
103 | switch state {
104 | case .tooSmall:
105 | return maxSize
106 | default:
107 | return minSize
108 | }
109 | }
110 |
111 | switch state {
112 | case .fit: return fontSize
113 | case .tooBig: return binarySearch(string: string, minSize: minSize, maxSize: fontSize, size: size, constraintSize: constraintSize)
114 | case .tooSmall: return binarySearch(string: string, minSize: fontSize, maxSize: maxSize, size: size, constraintSize: constraintSize)
115 | }
116 | }
117 |
118 | private func singleLineSizeState(rect: CGRect, size: CGSize) -> FontSizeState {
119 | if rect.width >= size.width + 10 && rect.width <= size.width {
120 | return .fit
121 | } else if rect.width > size.width {
122 | return .tooBig
123 | } else {
124 | return .tooSmall
125 | }
126 | }
127 |
128 | private func multiLineSizeState(rect: CGRect, size: CGSize) -> FontSizeState {
129 | // if rect within 10 of size
130 | if rect.height < size.height + 10 &&
131 | rect.height > size.height - 10 &&
132 | rect.width > size.width + 10 &&
133 | rect.width < size.width - 10 {
134 | return .fit
135 | } else if rect.height > size.height || rect.width > size.width {
136 | return .tooBig
137 | } else {
138 | return .tooSmall
139 | }
140 | }
141 |
142 | }
143 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # FittableFontLabel
2 |
3 | [](https://travis-ci.org/tbaranes/FittableFontLabel)
4 | 
5 | [](http://cocoadocs.org/docsets/FittableFontLabel)
6 | [](https://github.com/tbaranes/FittableFontLabel)
7 | [](https://github.com/Carthage/Carthage)
8 |
9 | `UILabel` can shrink font size as follows:
10 |
11 | ```swift
12 | label.minimumScaleFactor = 0.3
13 | label.adjustsFontSizeToFitWidth = true
14 | label.numberOfLines = 1
15 | ```
16 |
17 | But it won't always work as expected:
18 |
19 | - Doesn't fit the label height
20 | - Big top / bottom margins when the maxFontSize is huge
21 | - Not really customisable
22 | - Can't keep font size consistent across multiple labels
23 | - ...
24 |
25 | That's why `FittableFontLabel` exists:
26 |
27 | - Make the text fit the label size: width and height if multilines, width only if single lines
28 | - Works with one or several lines
29 | - Supports attributed string (custom line spacing...)
30 | - Customize `maxFontSize` without using default label font size
31 | - Auto-layout compliant
32 | - Keep font size consistent across multiple labels using 'FittableRootView'
33 | - `UILabel` extension if we want to use `UILabel`
34 | - Customisable from xibs / storyboards when using the UILabel's subclass `FittableFontLabel`
35 | - ...
36 |
37 | **Multilines `UILabel`:**
38 |
39 | 
40 |
41 | **Multilines `UILabel` with attributed string (lines spacing):**
42 |
43 | 
44 |
45 | **Single line `UILabel`:**
46 |
47 | 
48 |
49 | **Consistent font size across multiple labels `FittableRootView`**
50 |
51 | 
52 |
53 | ## Usage
54 |
55 | ### FittableFontLabel
56 | ```swift
57 | let aFittableFontLabel = FittableFontLabel(frame: CGRect(x: 0, y: 0, width: 300, height: 100))
58 | aFittableFontLabel.autoFittableFont = true
59 | aFittableFontLabel.lineBreakMode = .ByWordWrapping
60 | aFittableFontLabel.numberOfLines = 0 // or 1...
61 | aFittableFontLabel.text = "?"
62 | // Change the text, it will always fit the label frame!
63 | ```
64 |
65 | Check the sample project for advanced usage.
66 |
67 | **Note:** The label `lineBreakMode` must be set to `NSLineBreakByWordWrapping` in order to work.
68 |
69 | ### FittableRootView
70 | 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.
71 |
72 | 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.
73 |
74 | **Notes:**
75 | - FittableRootView has an inspectable bool `searchView`. This allows you to disable the search, giving the `FittableRootView` identical behavior to a normal `UIView`.
76 | - You can use multiple identifiers to standardize the font size across multiple sets of labels within the same view.
77 | - 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.
78 |
79 | ## Installation
80 |
81 | - iOS 8.0+
82 |
83 | ### CocoaPods
84 |
85 | Add `pod FittableFontLabel` to your Podfile.
86 |
87 | ### Carthage
88 |
89 | Add `github "tbaranes/FittableFontLabel"` to your Cartfile.
90 |
91 | ### Swift Package Manager
92 |
93 | FittableFontLabel is available on SPM. Just add the following to your Package file:
94 |
95 | ```swift
96 | // swift-tools-version:5.5.0
97 | import PackageDescription
98 |
99 | let package = Package(
100 | dependencies: [
101 | .Package(url: "https://github.com/tbaranes/FittableFontLabel.git", majorVersion: 1)
102 | ]
103 | )
104 | ```
105 |
106 | ### Manual Installation
107 |
108 | Just drag the `Source/*.swift` files into your project.
109 |
110 |
111 | ## UILabel extension
112 |
113 | ```swift
114 | func fontSizeToFit(maxFontSize: CGFloat = 100,
115 | minFontScale: CGFloat = 0.1,
116 | rectSize: CGSize? = nil)
117 | ```
118 |
119 | Adjust the font size to make the current text fit the label frame.
120 |
121 | - `maxFontSize`: the biggest font size to use during drawing. The default value is 100
122 | - `minFontScale`: the scale factor that determines the smallest font size to use during drawing. The default value is 0.1
123 | - `rectSize`: the size where the text must fit. The default value is the label bounds
124 |
125 | ```swift
126 | func fontSizeThatFits(
127 | text string: String,
128 | maxFontSize: CGFloat = 100,
129 | minFontScale: CGFloat = 0.1,
130 | rectSize: CGSize? = nil) -> CGFloat
131 | ```
132 |
133 | Returns the font size that can make the `text` parameter fit the label frame.
134 |
135 | - `text`: the text that needs to fit in the label
136 | - `maxFontSize`: the biggest font size that can be returned. The default value is 100
137 | - `minFontScale`: the scale factor that determines the smallest font size that can be returned. The default value is 0.1
138 | - `rectSize`: the size where the text must fit. The default value is the label bounds
139 |
140 | ## FittableFontLabel
141 |
142 | An `UILabel` subclass allowing you to automatize the process of adjusting the font size.
143 |
144 | ```swift
145 | @IBInspectable public var autoAdjustFontSize: Bool = true
146 | ```
147 |
148 | If `true`, the font size will be adjusted each time that the `text` or the `frame` change.
149 |
150 | ```swift
151 | @IBInspectable public var maxFontSize = CGFloat.NaN
152 | ```
153 |
154 | The biggest font size to use during drawing. The default value is the current font size
155 |
156 | ```swift
157 | @IBInspectable public var minFontScale = CGFloat.NaN
158 | ```
159 |
160 | The scale factor that determines the smallest font size to use during drawing. The default value is 0.1
161 |
162 | ```swift
163 | @IBInspectable public var leftInset: CGFloat = 0
164 | @IBInspectable public var rightInset: CGFloat = 0
165 | @IBInspectable public var topInset: CGFloat = 0
166 | @IBInspectable public var bottomInset: CGFloat = 0
167 | ```
168 |
169 | 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.
170 |
171 | ## Contribution
172 |
173 | - If you found a **bug**, open an **issue**
174 | - If you have a **feature request**, open an **issue**
175 | - If you want to **contribute**, submit a **pull request**
176 |
177 | ## Licence
178 |
179 | `FittableFontLabel` is available under the MIT license. See the LICENSE file for more info.
180 |
--------------------------------------------------------------------------------
/FittableFontLabel Example/FittableFontLabel Example.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | E23EA9A01D5E581200029673 /* FittableFontLabel.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E251BE401CCE82CB00EA621A /* FittableFontLabel.framework */; };
11 | E23EA9A11D5E581200029673 /* FittableFontLabel.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = E251BE401CCE82CB00EA621A /* FittableFontLabel.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
12 | E2C3AF631C4FC0ED00EB275B /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E298E3EE1C4F8A41009704B1 /* AppDelegate.swift */; };
13 | E2C3AF641C4FC0ED00EB275B /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E298E3F01C4F8A41009704B1 /* ViewController.swift */; };
14 | E2C3AF651C4FC11200EB275B /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E298E3F21C4F8A41009704B1 /* Main.storyboard */; };
15 | E2C3AF661C4FC11500EB275B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E298E3F51C4F8A41009704B1 /* Assets.xcassets */; };
16 | E2C3AF671C4FC11900EB275B /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E298E3F71C4F8A41009704B1 /* LaunchScreen.storyboard */; };
17 | /* End PBXBuildFile section */
18 |
19 | /* Begin PBXContainerItemProxy section */
20 | E23EA9A21D5E581200029673 /* PBXContainerItemProxy */ = {
21 | isa = PBXContainerItemProxy;
22 | containerPortal = E251BE3A1CCE82CB00EA621A /* FittableFontLabel.xcodeproj */;
23 | proxyType = 1;
24 | remoteGlobalIDString = E2227AA11CCE80C5006C4289;
25 | remoteInfo = "FittableFontLabel iOS";
26 | };
27 | E251BE3F1CCE82CB00EA621A /* PBXContainerItemProxy */ = {
28 | isa = PBXContainerItemProxy;
29 | containerPortal = E251BE3A1CCE82CB00EA621A /* FittableFontLabel.xcodeproj */;
30 | proxyType = 2;
31 | remoteGlobalIDString = E2227AA21CCE80C5006C4289;
32 | remoteInfo = "FittableFontLabel iOS";
33 | };
34 | E251BE411CCE82CB00EA621A /* PBXContainerItemProxy */ = {
35 | isa = PBXContainerItemProxy;
36 | containerPortal = E251BE3A1CCE82CB00EA621A /* FittableFontLabel.xcodeproj */;
37 | proxyType = 2;
38 | remoteGlobalIDString = E2227AAC1CCE80C5006C4289;
39 | remoteInfo = "FittableFontLabel iOS Tests";
40 | };
41 | /* End PBXContainerItemProxy section */
42 |
43 | /* Begin PBXCopyFilesBuildPhase section */
44 | E23EA9A41D5E581200029673 /* Embed Frameworks */ = {
45 | isa = PBXCopyFilesBuildPhase;
46 | buildActionMask = 2147483647;
47 | dstPath = "";
48 | dstSubfolderSpec = 10;
49 | files = (
50 | E23EA9A11D5E581200029673 /* FittableFontLabel.framework in Embed Frameworks */,
51 | );
52 | name = "Embed Frameworks";
53 | runOnlyForDeploymentPostprocessing = 0;
54 | };
55 | /* End PBXCopyFilesBuildPhase section */
56 |
57 | /* Begin PBXFileReference section */
58 | E251BE3A1CCE82CB00EA621A /* FittableFontLabel.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = FittableFontLabel.xcodeproj; path = ../FittableFontLabel/FittableFontLabel.xcodeproj; sourceTree = ""; };
59 | E298E3EE1C4F8A41009704B1 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
60 | E298E3F01C4F8A41009704B1 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
61 | E298E3F31C4F8A41009704B1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
62 | E298E3F51C4F8A41009704B1 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
63 | E298E3F81C4F8A41009704B1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
64 | E298E3FA1C4F8A41009704B1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
65 | E2C3AF3E1C4FBFB300EB275B /* FittableFontLabel iOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "FittableFontLabel iOS.app"; sourceTree = BUILT_PRODUCTS_DIR; };
66 | /* End PBXFileReference section */
67 |
68 | /* Begin PBXFrameworksBuildPhase section */
69 | E2C3AF3B1C4FBFB300EB275B /* Frameworks */ = {
70 | isa = PBXFrameworksBuildPhase;
71 | buildActionMask = 2147483647;
72 | files = (
73 | E23EA9A01D5E581200029673 /* FittableFontLabel.framework in Frameworks */,
74 | );
75 | runOnlyForDeploymentPostprocessing = 0;
76 | };
77 | /* End PBXFrameworksBuildPhase section */
78 |
79 | /* Begin PBXGroup section */
80 | E251BE3B1CCE82CB00EA621A /* Products */ = {
81 | isa = PBXGroup;
82 | children = (
83 | E251BE401CCE82CB00EA621A /* FittableFontLabel.framework */,
84 | E251BE421CCE82CB00EA621A /* FittableFontLabel iOS Tests.xctest */,
85 | );
86 | name = Products;
87 | sourceTree = "";
88 | };
89 | E298E3E21C4F8A41009704B1 = {
90 | isa = PBXGroup;
91 | children = (
92 | E298E3ED1C4F8A41009704B1 /* iOS Example */,
93 | E298E3EC1C4F8A41009704B1 /* Products */,
94 | E251BE3A1CCE82CB00EA621A /* FittableFontLabel.xcodeproj */,
95 | );
96 | sourceTree = "";
97 | };
98 | E298E3EC1C4F8A41009704B1 /* Products */ = {
99 | isa = PBXGroup;
100 | children = (
101 | E2C3AF3E1C4FBFB300EB275B /* FittableFontLabel iOS.app */,
102 | );
103 | name = Products;
104 | sourceTree = "";
105 | };
106 | E298E3ED1C4F8A41009704B1 /* iOS Example */ = {
107 | isa = PBXGroup;
108 | children = (
109 | E298E3EE1C4F8A41009704B1 /* AppDelegate.swift */,
110 | E298E3F01C4F8A41009704B1 /* ViewController.swift */,
111 | E298E3F21C4F8A41009704B1 /* Main.storyboard */,
112 | E298E3F51C4F8A41009704B1 /* Assets.xcassets */,
113 | E298E3F71C4F8A41009704B1 /* LaunchScreen.storyboard */,
114 | E298E3FA1C4F8A41009704B1 /* Info.plist */,
115 | );
116 | path = "iOS Example";
117 | sourceTree = "";
118 | };
119 | /* End PBXGroup section */
120 |
121 | /* Begin PBXNativeTarget section */
122 | E2C3AF3D1C4FBFB300EB275B /* iOS Example */ = {
123 | isa = PBXNativeTarget;
124 | buildConfigurationList = E2C3AF4D1C4FBFB300EB275B /* Build configuration list for PBXNativeTarget "iOS Example" */;
125 | buildPhases = (
126 | E2C3AF3A1C4FBFB300EB275B /* Sources */,
127 | E2C3AF3B1C4FBFB300EB275B /* Frameworks */,
128 | E2C3AF3C1C4FBFB300EB275B /* Resources */,
129 | E23EA9A41D5E581200029673 /* Embed Frameworks */,
130 | );
131 | buildRules = (
132 | );
133 | dependencies = (
134 | E23EA9A31D5E581200029673 /* PBXTargetDependency */,
135 | );
136 | name = "iOS Example";
137 | productName = IncrementableLabel;
138 | productReference = E2C3AF3E1C4FBFB300EB275B /* FittableFontLabel iOS.app */;
139 | productType = "com.apple.product-type.application";
140 | };
141 | /* End PBXNativeTarget section */
142 |
143 | /* Begin PBXProject section */
144 | E298E3E31C4F8A41009704B1 /* Project object */ = {
145 | isa = PBXProject;
146 | attributes = {
147 | LastSwiftUpdateCheck = 0720;
148 | LastUpgradeCheck = 1020;
149 | ORGANIZATIONNAME = Recisio;
150 | TargetAttributes = {
151 | E2C3AF3D1C4FBFB300EB275B = {
152 | CreatedOnToolsVersion = 7.2;
153 | DevelopmentTeam = TNVENL2JX3;
154 | LastSwiftMigration = 1020;
155 | ProvisioningStyle = Automatic;
156 | };
157 | };
158 | };
159 | buildConfigurationList = E298E3E61C4F8A41009704B1 /* Build configuration list for PBXProject "FittableFontLabel Example" */;
160 | compatibilityVersion = "Xcode 3.2";
161 | developmentRegion = en;
162 | hasScannedForEncodings = 0;
163 | knownRegions = (
164 | en,
165 | Base,
166 | );
167 | mainGroup = E298E3E21C4F8A41009704B1;
168 | productRefGroup = E298E3EC1C4F8A41009704B1 /* Products */;
169 | projectDirPath = "";
170 | projectReferences = (
171 | {
172 | ProductGroup = E251BE3B1CCE82CB00EA621A /* Products */;
173 | ProjectRef = E251BE3A1CCE82CB00EA621A /* FittableFontLabel.xcodeproj */;
174 | },
175 | );
176 | projectRoot = "";
177 | targets = (
178 | E2C3AF3D1C4FBFB300EB275B /* iOS Example */,
179 | );
180 | };
181 | /* End PBXProject section */
182 |
183 | /* Begin PBXReferenceProxy section */
184 | E251BE401CCE82CB00EA621A /* FittableFontLabel.framework */ = {
185 | isa = PBXReferenceProxy;
186 | fileType = wrapper.framework;
187 | path = FittableFontLabel.framework;
188 | remoteRef = E251BE3F1CCE82CB00EA621A /* PBXContainerItemProxy */;
189 | sourceTree = BUILT_PRODUCTS_DIR;
190 | };
191 | E251BE421CCE82CB00EA621A /* FittableFontLabel iOS Tests.xctest */ = {
192 | isa = PBXReferenceProxy;
193 | fileType = wrapper.cfbundle;
194 | path = "FittableFontLabel iOS Tests.xctest";
195 | remoteRef = E251BE411CCE82CB00EA621A /* PBXContainerItemProxy */;
196 | sourceTree = BUILT_PRODUCTS_DIR;
197 | };
198 | /* End PBXReferenceProxy section */
199 |
200 | /* Begin PBXResourcesBuildPhase section */
201 | E2C3AF3C1C4FBFB300EB275B /* Resources */ = {
202 | isa = PBXResourcesBuildPhase;
203 | buildActionMask = 2147483647;
204 | files = (
205 | E2C3AF671C4FC11900EB275B /* LaunchScreen.storyboard in Resources */,
206 | E2C3AF661C4FC11500EB275B /* Assets.xcassets in Resources */,
207 | E2C3AF651C4FC11200EB275B /* Main.storyboard in Resources */,
208 | );
209 | runOnlyForDeploymentPostprocessing = 0;
210 | };
211 | /* End PBXResourcesBuildPhase section */
212 |
213 | /* Begin PBXSourcesBuildPhase section */
214 | E2C3AF3A1C4FBFB300EB275B /* Sources */ = {
215 | isa = PBXSourcesBuildPhase;
216 | buildActionMask = 2147483647;
217 | files = (
218 | E2C3AF641C4FC0ED00EB275B /* ViewController.swift in Sources */,
219 | E2C3AF631C4FC0ED00EB275B /* AppDelegate.swift in Sources */,
220 | );
221 | runOnlyForDeploymentPostprocessing = 0;
222 | };
223 | /* End PBXSourcesBuildPhase section */
224 |
225 | /* Begin PBXTargetDependency section */
226 | E23EA9A31D5E581200029673 /* PBXTargetDependency */ = {
227 | isa = PBXTargetDependency;
228 | name = "FittableFontLabel iOS";
229 | targetProxy = E23EA9A21D5E581200029673 /* PBXContainerItemProxy */;
230 | };
231 | /* End PBXTargetDependency section */
232 |
233 | /* Begin PBXVariantGroup section */
234 | E298E3F21C4F8A41009704B1 /* Main.storyboard */ = {
235 | isa = PBXVariantGroup;
236 | children = (
237 | E298E3F31C4F8A41009704B1 /* Base */,
238 | );
239 | name = Main.storyboard;
240 | sourceTree = "";
241 | };
242 | E298E3F71C4F8A41009704B1 /* LaunchScreen.storyboard */ = {
243 | isa = PBXVariantGroup;
244 | children = (
245 | E298E3F81C4F8A41009704B1 /* Base */,
246 | );
247 | name = LaunchScreen.storyboard;
248 | sourceTree = "";
249 | };
250 | /* End PBXVariantGroup section */
251 |
252 | /* Begin XCBuildConfiguration section */
253 | E298E3FB1C4F8A41009704B1 /* Debug */ = {
254 | isa = XCBuildConfiguration;
255 | buildSettings = {
256 | ALWAYS_SEARCH_USER_PATHS = NO;
257 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
258 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
259 | CLANG_CXX_LIBRARY = "libc++";
260 | CLANG_ENABLE_MODULES = YES;
261 | CLANG_ENABLE_OBJC_ARC = YES;
262 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
263 | CLANG_WARN_BOOL_CONVERSION = YES;
264 | CLANG_WARN_COMMA = YES;
265 | CLANG_WARN_CONSTANT_CONVERSION = YES;
266 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
267 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
268 | CLANG_WARN_EMPTY_BODY = YES;
269 | CLANG_WARN_ENUM_CONVERSION = YES;
270 | CLANG_WARN_INFINITE_RECURSION = YES;
271 | CLANG_WARN_INT_CONVERSION = YES;
272 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
273 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
274 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
275 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
276 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
277 | CLANG_WARN_STRICT_PROTOTYPES = YES;
278 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
279 | CLANG_WARN_UNREACHABLE_CODE = YES;
280 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
281 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
282 | COPY_PHASE_STRIP = NO;
283 | DEBUG_INFORMATION_FORMAT = dwarf;
284 | ENABLE_STRICT_OBJC_MSGSEND = YES;
285 | ENABLE_TESTABILITY = YES;
286 | GCC_C_LANGUAGE_STANDARD = gnu99;
287 | GCC_DYNAMIC_NO_PIC = NO;
288 | GCC_NO_COMMON_BLOCKS = YES;
289 | GCC_OPTIMIZATION_LEVEL = 0;
290 | GCC_PREPROCESSOR_DEFINITIONS = (
291 | "DEBUG=1",
292 | "$(inherited)",
293 | );
294 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
295 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
296 | GCC_WARN_UNDECLARED_SELECTOR = YES;
297 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
298 | GCC_WARN_UNUSED_FUNCTION = YES;
299 | GCC_WARN_UNUSED_VARIABLE = YES;
300 | IPHONEOS_DEPLOYMENT_TARGET = 9.2;
301 | MTL_ENABLE_DEBUG_INFO = YES;
302 | ONLY_ACTIVE_ARCH = YES;
303 | SDKROOT = iphoneos;
304 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
305 | SWIFT_VERSION = 4.0;
306 | TARGETED_DEVICE_FAMILY = "1,2";
307 | };
308 | name = Debug;
309 | };
310 | E298E3FC1C4F8A41009704B1 /* Release */ = {
311 | isa = XCBuildConfiguration;
312 | buildSettings = {
313 | ALWAYS_SEARCH_USER_PATHS = NO;
314 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
315 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
316 | CLANG_CXX_LIBRARY = "libc++";
317 | CLANG_ENABLE_MODULES = YES;
318 | CLANG_ENABLE_OBJC_ARC = YES;
319 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
320 | CLANG_WARN_BOOL_CONVERSION = YES;
321 | CLANG_WARN_COMMA = YES;
322 | CLANG_WARN_CONSTANT_CONVERSION = YES;
323 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
324 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
325 | CLANG_WARN_EMPTY_BODY = YES;
326 | CLANG_WARN_ENUM_CONVERSION = YES;
327 | CLANG_WARN_INFINITE_RECURSION = YES;
328 | CLANG_WARN_INT_CONVERSION = YES;
329 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
330 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
331 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
332 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
333 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
334 | CLANG_WARN_STRICT_PROTOTYPES = YES;
335 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
336 | CLANG_WARN_UNREACHABLE_CODE = YES;
337 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
338 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
339 | COPY_PHASE_STRIP = NO;
340 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
341 | ENABLE_NS_ASSERTIONS = NO;
342 | ENABLE_STRICT_OBJC_MSGSEND = YES;
343 | GCC_C_LANGUAGE_STANDARD = gnu99;
344 | GCC_NO_COMMON_BLOCKS = YES;
345 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
346 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
347 | GCC_WARN_UNDECLARED_SELECTOR = YES;
348 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
349 | GCC_WARN_UNUSED_FUNCTION = YES;
350 | GCC_WARN_UNUSED_VARIABLE = YES;
351 | IPHONEOS_DEPLOYMENT_TARGET = 9.2;
352 | MTL_ENABLE_DEBUG_INFO = NO;
353 | SDKROOT = iphoneos;
354 | SWIFT_VERSION = 4.0;
355 | TARGETED_DEVICE_FAMILY = "1,2";
356 | VALIDATE_PRODUCT = YES;
357 | };
358 | name = Release;
359 | };
360 | E2C3AF4E1C4FBFB300EB275B /* Debug */ = {
361 | isa = XCBuildConfiguration;
362 | buildSettings = {
363 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
364 | DEVELOPMENT_TEAM = TNVENL2JX3;
365 | INFOPLIST_FILE = "$(SRCROOT)/iOS Example/Info.plist";
366 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
367 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
368 | PRODUCT_BUNDLE_IDENTIFIER = com.recisio.IncrementableLabel;
369 | PRODUCT_NAME = "FittableFontLabel iOS";
370 | SWIFT_VERSION = 5.0;
371 | };
372 | name = Debug;
373 | };
374 | E2C3AF4F1C4FBFB300EB275B /* Release */ = {
375 | isa = XCBuildConfiguration;
376 | buildSettings = {
377 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
378 | DEVELOPMENT_TEAM = TNVENL2JX3;
379 | INFOPLIST_FILE = "$(SRCROOT)/iOS Example/Info.plist";
380 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
381 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
382 | PRODUCT_BUNDLE_IDENTIFIER = com.recisio.IncrementableLabel;
383 | PRODUCT_NAME = "FittableFontLabel iOS";
384 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
385 | SWIFT_VERSION = 5.0;
386 | };
387 | name = Release;
388 | };
389 | /* End XCBuildConfiguration section */
390 |
391 | /* Begin XCConfigurationList section */
392 | E298E3E61C4F8A41009704B1 /* Build configuration list for PBXProject "FittableFontLabel Example" */ = {
393 | isa = XCConfigurationList;
394 | buildConfigurations = (
395 | E298E3FB1C4F8A41009704B1 /* Debug */,
396 | E298E3FC1C4F8A41009704B1 /* Release */,
397 | );
398 | defaultConfigurationIsVisible = 0;
399 | defaultConfigurationName = Release;
400 | };
401 | E2C3AF4D1C4FBFB300EB275B /* Build configuration list for PBXNativeTarget "iOS Example" */ = {
402 | isa = XCConfigurationList;
403 | buildConfigurations = (
404 | E2C3AF4E1C4FBFB300EB275B /* Debug */,
405 | E2C3AF4F1C4FBFB300EB275B /* Release */,
406 | );
407 | defaultConfigurationIsVisible = 0;
408 | defaultConfigurationName = Release;
409 | };
410 | /* End XCConfigurationList section */
411 | };
412 | rootObject = E298E3E31C4F8A41009704B1 /* Project object */;
413 | }
414 |
--------------------------------------------------------------------------------
/FittableFontLabel/FittableFontLabel.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | E2227AA61CCE80C5006C4289 /* FittableFontLabel.h in Headers */ = {isa = PBXBuildFile; fileRef = E2227AA51CCE80C5006C4289 /* FittableFontLabel.h */; settings = {ATTRIBUTES = (Public, ); }; };
11 | E2227AAD1CCE80C5006C4289 /* FittableFontLabel.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E2227AA21CCE80C5006C4289 /* FittableFontLabel.framework */; };
12 | E2227AB21CCE80C5006C4289 /* FittableFontLabelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2227AB11CCE80C5006C4289 /* FittableFontLabelTests.swift */; };
13 | E2EFA1B41FB5915A00096E56 /* FittableFontLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2EFA1B21FB5915A00096E56 /* FittableFontLabel.swift */; };
14 | E2EFA1B51FB5915A00096E56 /* UILabelExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2EFA1B31FB5915A00096E56 /* UILabelExtension.swift */; };
15 | /* End PBXBuildFile section */
16 |
17 | /* Begin PBXContainerItemProxy section */
18 | E2227AAE1CCE80C5006C4289 /* PBXContainerItemProxy */ = {
19 | isa = PBXContainerItemProxy;
20 | containerPortal = E2227A991CCE80C5006C4289 /* Project object */;
21 | proxyType = 1;
22 | remoteGlobalIDString = E2227AA11CCE80C5006C4289;
23 | remoteInfo = FittableFontLabel;
24 | };
25 | /* End PBXContainerItemProxy section */
26 |
27 | /* Begin PBXFileReference section */
28 | E2227AA21CCE80C5006C4289 /* FittableFontLabel.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FittableFontLabel.framework; sourceTree = BUILT_PRODUCTS_DIR; };
29 | E2227AA51CCE80C5006C4289 /* FittableFontLabel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FittableFontLabel.h; sourceTree = ""; };
30 | E2227AA71CCE80C5006C4289 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
31 | E2227AAC1CCE80C5006C4289 /* FittableFontLabel iOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "FittableFontLabel iOS Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
32 | E2227AB11CCE80C5006C4289 /* FittableFontLabelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FittableFontLabelTests.swift; sourceTree = ""; };
33 | E2227AB31CCE80C5006C4289 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
34 | E2EFA1B21FB5915A00096E56 /* FittableFontLabel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FittableFontLabel.swift; sourceTree = ""; };
35 | E2EFA1B31FB5915A00096E56 /* UILabelExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UILabelExtension.swift; sourceTree = ""; };
36 | /* End PBXFileReference section */
37 |
38 | /* Begin PBXFrameworksBuildPhase section */
39 | E2227A9E1CCE80C5006C4289 /* Frameworks */ = {
40 | isa = PBXFrameworksBuildPhase;
41 | buildActionMask = 2147483647;
42 | files = (
43 | );
44 | runOnlyForDeploymentPostprocessing = 0;
45 | };
46 | E2227AA91CCE80C5006C4289 /* Frameworks */ = {
47 | isa = PBXFrameworksBuildPhase;
48 | buildActionMask = 2147483647;
49 | files = (
50 | E2227AAD1CCE80C5006C4289 /* FittableFontLabel.framework in Frameworks */,
51 | );
52 | runOnlyForDeploymentPostprocessing = 0;
53 | };
54 | /* End PBXFrameworksBuildPhase section */
55 |
56 | /* Begin PBXGroup section */
57 | E2227A981CCE80C5006C4289 = {
58 | isa = PBXGroup;
59 | children = (
60 | E2EFA1B11FB5915A00096E56 /* Source */,
61 | E2227AA41CCE80C5006C4289 /* FittableFontLabel iOS */,
62 | E2227AB01CCE80C5006C4289 /* FittableFontLabelTests */,
63 | E2227AA31CCE80C5006C4289 /* Products */,
64 | );
65 | sourceTree = "";
66 | };
67 | E2227AA31CCE80C5006C4289 /* Products */ = {
68 | isa = PBXGroup;
69 | children = (
70 | E2227AA21CCE80C5006C4289 /* FittableFontLabel.framework */,
71 | E2227AAC1CCE80C5006C4289 /* FittableFontLabel iOS Tests.xctest */,
72 | );
73 | name = Products;
74 | sourceTree = "";
75 | };
76 | E2227AA41CCE80C5006C4289 /* FittableFontLabel iOS */ = {
77 | isa = PBXGroup;
78 | children = (
79 | E2227AA51CCE80C5006C4289 /* FittableFontLabel.h */,
80 | E2227AA71CCE80C5006C4289 /* Info.plist */,
81 | );
82 | path = "FittableFontLabel iOS";
83 | sourceTree = "";
84 | };
85 | E2227AB01CCE80C5006C4289 /* FittableFontLabelTests */ = {
86 | isa = PBXGroup;
87 | children = (
88 | E2227AB11CCE80C5006C4289 /* FittableFontLabelTests.swift */,
89 | E2227AB31CCE80C5006C4289 /* Info.plist */,
90 | );
91 | name = FittableFontLabelTests;
92 | path = "FittableFontLabel iOS Tests";
93 | sourceTree = "";
94 | };
95 | E2EFA1B11FB5915A00096E56 /* Source */ = {
96 | isa = PBXGroup;
97 | children = (
98 | E2EFA1B21FB5915A00096E56 /* FittableFontLabel.swift */,
99 | E2EFA1B31FB5915A00096E56 /* UILabelExtension.swift */,
100 | );
101 | name = Source;
102 | path = ../Source;
103 | sourceTree = "";
104 | };
105 | /* End PBXGroup section */
106 |
107 | /* Begin PBXHeadersBuildPhase section */
108 | E2227A9F1CCE80C5006C4289 /* Headers */ = {
109 | isa = PBXHeadersBuildPhase;
110 | buildActionMask = 2147483647;
111 | files = (
112 | E2227AA61CCE80C5006C4289 /* FittableFontLabel.h in Headers */,
113 | );
114 | runOnlyForDeploymentPostprocessing = 0;
115 | };
116 | /* End PBXHeadersBuildPhase section */
117 |
118 | /* Begin PBXNativeTarget section */
119 | E2227AA11CCE80C5006C4289 /* FittableFontLabel iOS */ = {
120 | isa = PBXNativeTarget;
121 | buildConfigurationList = E2227AB61CCE80C5006C4289 /* Build configuration list for PBXNativeTarget "FittableFontLabel iOS" */;
122 | buildPhases = (
123 | E2227A9D1CCE80C5006C4289 /* Sources */,
124 | E2227A9E1CCE80C5006C4289 /* Frameworks */,
125 | E2227A9F1CCE80C5006C4289 /* Headers */,
126 | E2227AA01CCE80C5006C4289 /* Resources */,
127 | E20B23CB1D1E7B4000BB327A /* Run Script - ⚠️ SwiftLint */,
128 | );
129 | buildRules = (
130 | );
131 | dependencies = (
132 | );
133 | name = "FittableFontLabel iOS";
134 | productName = FittableFontLabel;
135 | productReference = E2227AA21CCE80C5006C4289 /* FittableFontLabel.framework */;
136 | productType = "com.apple.product-type.framework";
137 | };
138 | E2227AAB1CCE80C5006C4289 /* FittableFontLabel iOS Tests */ = {
139 | isa = PBXNativeTarget;
140 | buildConfigurationList = E2227AB91CCE80C5006C4289 /* Build configuration list for PBXNativeTarget "FittableFontLabel iOS Tests" */;
141 | buildPhases = (
142 | E2227AA81CCE80C5006C4289 /* Sources */,
143 | E2227AA91CCE80C5006C4289 /* Frameworks */,
144 | E2227AAA1CCE80C5006C4289 /* Resources */,
145 | );
146 | buildRules = (
147 | );
148 | dependencies = (
149 | E2227AAF1CCE80C5006C4289 /* PBXTargetDependency */,
150 | );
151 | name = "FittableFontLabel iOS Tests";
152 | productName = FittableFontLabelTests;
153 | productReference = E2227AAC1CCE80C5006C4289 /* FittableFontLabel iOS Tests.xctest */;
154 | productType = "com.apple.product-type.bundle.unit-test";
155 | };
156 | /* End PBXNativeTarget section */
157 |
158 | /* Begin PBXProject section */
159 | E2227A991CCE80C5006C4289 /* Project object */ = {
160 | isa = PBXProject;
161 | attributes = {
162 | LastSwiftUpdateCheck = 0730;
163 | LastUpgradeCheck = 1020;
164 | ORGANIZATIONNAME = "Tom Baranes";
165 | TargetAttributes = {
166 | E2227AA11CCE80C5006C4289 = {
167 | CreatedOnToolsVersion = 7.3;
168 | LastSwiftMigration = 1020;
169 | };
170 | E2227AAB1CCE80C5006C4289 = {
171 | CreatedOnToolsVersion = 7.3;
172 | LastSwiftMigration = 1020;
173 | };
174 | };
175 | };
176 | buildConfigurationList = E2227A9C1CCE80C5006C4289 /* Build configuration list for PBXProject "FittableFontLabel" */;
177 | compatibilityVersion = "Xcode 3.2";
178 | developmentRegion = en;
179 | hasScannedForEncodings = 0;
180 | knownRegions = (
181 | en,
182 | Base,
183 | );
184 | mainGroup = E2227A981CCE80C5006C4289;
185 | productRefGroup = E2227AA31CCE80C5006C4289 /* Products */;
186 | projectDirPath = "";
187 | projectRoot = "";
188 | targets = (
189 | E2227AA11CCE80C5006C4289 /* FittableFontLabel iOS */,
190 | E2227AAB1CCE80C5006C4289 /* FittableFontLabel iOS Tests */,
191 | );
192 | };
193 | /* End PBXProject section */
194 |
195 | /* Begin PBXResourcesBuildPhase section */
196 | E2227AA01CCE80C5006C4289 /* Resources */ = {
197 | isa = PBXResourcesBuildPhase;
198 | buildActionMask = 2147483647;
199 | files = (
200 | );
201 | runOnlyForDeploymentPostprocessing = 0;
202 | };
203 | E2227AAA1CCE80C5006C4289 /* Resources */ = {
204 | isa = PBXResourcesBuildPhase;
205 | buildActionMask = 2147483647;
206 | files = (
207 | );
208 | runOnlyForDeploymentPostprocessing = 0;
209 | };
210 | /* End PBXResourcesBuildPhase section */
211 |
212 | /* Begin PBXShellScriptBuildPhase section */
213 | E20B23CB1D1E7B4000BB327A /* Run Script - ⚠️ SwiftLint */ = {
214 | isa = PBXShellScriptBuildPhase;
215 | buildActionMask = 2147483647;
216 | files = (
217 | );
218 | inputPaths = (
219 | );
220 | name = "Run Script - ⚠️ SwiftLint";
221 | outputPaths = (
222 | );
223 | runOnlyForDeploymentPostprocessing = 0;
224 | shellPath = /bin/sh;
225 | shellScript = "if which swiftlint >/dev/null; then\n swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n";
226 | };
227 | /* End PBXShellScriptBuildPhase section */
228 |
229 | /* Begin PBXSourcesBuildPhase section */
230 | E2227A9D1CCE80C5006C4289 /* Sources */ = {
231 | isa = PBXSourcesBuildPhase;
232 | buildActionMask = 2147483647;
233 | files = (
234 | E2EFA1B51FB5915A00096E56 /* UILabelExtension.swift in Sources */,
235 | E2EFA1B41FB5915A00096E56 /* FittableFontLabel.swift in Sources */,
236 | );
237 | runOnlyForDeploymentPostprocessing = 0;
238 | };
239 | E2227AA81CCE80C5006C4289 /* Sources */ = {
240 | isa = PBXSourcesBuildPhase;
241 | buildActionMask = 2147483647;
242 | files = (
243 | E2227AB21CCE80C5006C4289 /* FittableFontLabelTests.swift in Sources */,
244 | );
245 | runOnlyForDeploymentPostprocessing = 0;
246 | };
247 | /* End PBXSourcesBuildPhase section */
248 |
249 | /* Begin PBXTargetDependency section */
250 | E2227AAF1CCE80C5006C4289 /* PBXTargetDependency */ = {
251 | isa = PBXTargetDependency;
252 | target = E2227AA11CCE80C5006C4289 /* FittableFontLabel iOS */;
253 | targetProxy = E2227AAE1CCE80C5006C4289 /* PBXContainerItemProxy */;
254 | };
255 | /* End PBXTargetDependency section */
256 |
257 | /* Begin XCBuildConfiguration section */
258 | E2227AB41CCE80C5006C4289 /* Debug */ = {
259 | isa = XCBuildConfiguration;
260 | buildSettings = {
261 | ALWAYS_SEARCH_USER_PATHS = NO;
262 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
263 | CLANG_ANALYZER_NONNULL = YES;
264 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
265 | CLANG_CXX_LIBRARY = "libc++";
266 | CLANG_ENABLE_MODULES = YES;
267 | CLANG_ENABLE_OBJC_ARC = YES;
268 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
269 | CLANG_WARN_BOOL_CONVERSION = YES;
270 | CLANG_WARN_COMMA = YES;
271 | CLANG_WARN_CONSTANT_CONVERSION = YES;
272 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
273 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
274 | CLANG_WARN_EMPTY_BODY = YES;
275 | CLANG_WARN_ENUM_CONVERSION = YES;
276 | CLANG_WARN_INFINITE_RECURSION = YES;
277 | CLANG_WARN_INT_CONVERSION = YES;
278 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
279 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
280 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
281 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
282 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
283 | CLANG_WARN_STRICT_PROTOTYPES = YES;
284 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
285 | CLANG_WARN_UNREACHABLE_CODE = YES;
286 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
287 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
288 | COPY_PHASE_STRIP = NO;
289 | CURRENT_PROJECT_VERSION = 1;
290 | DEBUG_INFORMATION_FORMAT = dwarf;
291 | ENABLE_STRICT_OBJC_MSGSEND = YES;
292 | ENABLE_TESTABILITY = YES;
293 | GCC_C_LANGUAGE_STANDARD = gnu99;
294 | GCC_DYNAMIC_NO_PIC = NO;
295 | GCC_NO_COMMON_BLOCKS = YES;
296 | GCC_OPTIMIZATION_LEVEL = 0;
297 | GCC_PREPROCESSOR_DEFINITIONS = (
298 | "DEBUG=1",
299 | "$(inherited)",
300 | );
301 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
302 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
303 | GCC_WARN_UNDECLARED_SELECTOR = YES;
304 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
305 | GCC_WARN_UNUSED_FUNCTION = YES;
306 | GCC_WARN_UNUSED_VARIABLE = YES;
307 | IPHONEOS_DEPLOYMENT_TARGET = 9.3;
308 | MTL_ENABLE_DEBUG_INFO = YES;
309 | ONLY_ACTIVE_ARCH = YES;
310 | SDKROOT = iphoneos;
311 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
312 | SWIFT_VERSION = 4.0;
313 | TARGETED_DEVICE_FAMILY = "1,2";
314 | VERSIONING_SYSTEM = "apple-generic";
315 | VERSION_INFO_PREFIX = "";
316 | };
317 | name = Debug;
318 | };
319 | E2227AB51CCE80C5006C4289 /* Release */ = {
320 | isa = XCBuildConfiguration;
321 | buildSettings = {
322 | ALWAYS_SEARCH_USER_PATHS = NO;
323 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
324 | CLANG_ANALYZER_NONNULL = YES;
325 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
326 | CLANG_CXX_LIBRARY = "libc++";
327 | CLANG_ENABLE_MODULES = YES;
328 | CLANG_ENABLE_OBJC_ARC = YES;
329 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
330 | CLANG_WARN_BOOL_CONVERSION = YES;
331 | CLANG_WARN_COMMA = YES;
332 | CLANG_WARN_CONSTANT_CONVERSION = YES;
333 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
334 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
335 | CLANG_WARN_EMPTY_BODY = YES;
336 | CLANG_WARN_ENUM_CONVERSION = YES;
337 | CLANG_WARN_INFINITE_RECURSION = YES;
338 | CLANG_WARN_INT_CONVERSION = YES;
339 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
340 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
341 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
342 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
343 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
344 | CLANG_WARN_STRICT_PROTOTYPES = YES;
345 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
346 | CLANG_WARN_UNREACHABLE_CODE = YES;
347 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
348 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
349 | COPY_PHASE_STRIP = NO;
350 | CURRENT_PROJECT_VERSION = 1;
351 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
352 | ENABLE_NS_ASSERTIONS = NO;
353 | ENABLE_STRICT_OBJC_MSGSEND = YES;
354 | GCC_C_LANGUAGE_STANDARD = gnu99;
355 | GCC_NO_COMMON_BLOCKS = YES;
356 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
357 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
358 | GCC_WARN_UNDECLARED_SELECTOR = YES;
359 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
360 | GCC_WARN_UNUSED_FUNCTION = YES;
361 | GCC_WARN_UNUSED_VARIABLE = YES;
362 | IPHONEOS_DEPLOYMENT_TARGET = 9.3;
363 | MTL_ENABLE_DEBUG_INFO = NO;
364 | SDKROOT = iphoneos;
365 | SWIFT_VERSION = 4.0;
366 | TARGETED_DEVICE_FAMILY = "1,2";
367 | VALIDATE_PRODUCT = YES;
368 | VERSIONING_SYSTEM = "apple-generic";
369 | VERSION_INFO_PREFIX = "";
370 | };
371 | name = Release;
372 | };
373 | E2227AB71CCE80C5006C4289 /* Debug */ = {
374 | isa = XCBuildConfiguration;
375 | buildSettings = {
376 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
377 | DEFINES_MODULE = YES;
378 | DYLIB_COMPATIBILITY_VERSION = 1;
379 | DYLIB_CURRENT_VERSION = 1;
380 | DYLIB_INSTALL_NAME_BASE = "@rpath";
381 | INFOPLIST_FILE = "$(SRCROOT)/FittableFontLabel iOS/Info.plist";
382 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
383 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
384 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
385 | PRODUCT_BUNDLE_IDENTIFIER = com.tbaranes.FittableFontLabel;
386 | PRODUCT_NAME = FittableFontLabel;
387 | SKIP_INSTALL = YES;
388 | SWIFT_VERSION = 5.0;
389 | };
390 | name = Debug;
391 | };
392 | E2227AB81CCE80C5006C4289 /* Release */ = {
393 | isa = XCBuildConfiguration;
394 | buildSettings = {
395 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
396 | DEFINES_MODULE = YES;
397 | DYLIB_COMPATIBILITY_VERSION = 1;
398 | DYLIB_CURRENT_VERSION = 1;
399 | DYLIB_INSTALL_NAME_BASE = "@rpath";
400 | INFOPLIST_FILE = "$(SRCROOT)/FittableFontLabel iOS/Info.plist";
401 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
402 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
403 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
404 | PRODUCT_BUNDLE_IDENTIFIER = com.tbaranes.FittableFontLabel;
405 | PRODUCT_NAME = FittableFontLabel;
406 | SKIP_INSTALL = YES;
407 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
408 | SWIFT_VERSION = 5.0;
409 | };
410 | name = Release;
411 | };
412 | E2227ABA1CCE80C5006C4289 /* Debug */ = {
413 | isa = XCBuildConfiguration;
414 | buildSettings = {
415 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
416 | INFOPLIST_FILE = "FittableFontLabel iOS Tests/Info.plist";
417 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
418 | PRODUCT_BUNDLE_IDENTIFIER = com.tbaranes.FittableFontLabelTests;
419 | PRODUCT_NAME = "$(TARGET_NAME)";
420 | SWIFT_VERSION = 5.0;
421 | };
422 | name = Debug;
423 | };
424 | E2227ABB1CCE80C5006C4289 /* Release */ = {
425 | isa = XCBuildConfiguration;
426 | buildSettings = {
427 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
428 | INFOPLIST_FILE = "FittableFontLabel iOS Tests/Info.plist";
429 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
430 | PRODUCT_BUNDLE_IDENTIFIER = com.tbaranes.FittableFontLabelTests;
431 | PRODUCT_NAME = "$(TARGET_NAME)";
432 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
433 | SWIFT_VERSION = 5.0;
434 | };
435 | name = Release;
436 | };
437 | E251BE321CCE813100EA621A /* ReleaseTest */ = {
438 | isa = XCBuildConfiguration;
439 | buildSettings = {
440 | ALWAYS_SEARCH_USER_PATHS = NO;
441 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
442 | CLANG_ANALYZER_NONNULL = YES;
443 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
444 | CLANG_CXX_LIBRARY = "libc++";
445 | CLANG_ENABLE_MODULES = YES;
446 | CLANG_ENABLE_OBJC_ARC = YES;
447 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
448 | CLANG_WARN_BOOL_CONVERSION = YES;
449 | CLANG_WARN_COMMA = YES;
450 | CLANG_WARN_CONSTANT_CONVERSION = YES;
451 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
452 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
453 | CLANG_WARN_EMPTY_BODY = YES;
454 | CLANG_WARN_ENUM_CONVERSION = YES;
455 | CLANG_WARN_INFINITE_RECURSION = YES;
456 | CLANG_WARN_INT_CONVERSION = YES;
457 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
458 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
459 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
460 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
461 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
462 | CLANG_WARN_STRICT_PROTOTYPES = YES;
463 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
464 | CLANG_WARN_UNREACHABLE_CODE = YES;
465 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
466 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
467 | COPY_PHASE_STRIP = NO;
468 | CURRENT_PROJECT_VERSION = 1;
469 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
470 | ENABLE_NS_ASSERTIONS = NO;
471 | ENABLE_STRICT_OBJC_MSGSEND = YES;
472 | ENABLE_TESTABILITY = YES;
473 | GCC_C_LANGUAGE_STANDARD = gnu99;
474 | GCC_NO_COMMON_BLOCKS = YES;
475 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
476 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
477 | GCC_WARN_UNDECLARED_SELECTOR = YES;
478 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
479 | GCC_WARN_UNUSED_FUNCTION = YES;
480 | GCC_WARN_UNUSED_VARIABLE = YES;
481 | IPHONEOS_DEPLOYMENT_TARGET = 9.3;
482 | MTL_ENABLE_DEBUG_INFO = NO;
483 | SDKROOT = iphoneos;
484 | SWIFT_VERSION = 4.0;
485 | TARGETED_DEVICE_FAMILY = "1,2";
486 | VALIDATE_PRODUCT = YES;
487 | VERSIONING_SYSTEM = "apple-generic";
488 | VERSION_INFO_PREFIX = "";
489 | };
490 | name = ReleaseTest;
491 | };
492 | E251BE331CCE813100EA621A /* ReleaseTest */ = {
493 | isa = XCBuildConfiguration;
494 | buildSettings = {
495 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
496 | DEFINES_MODULE = YES;
497 | DYLIB_COMPATIBILITY_VERSION = 1;
498 | DYLIB_CURRENT_VERSION = 1;
499 | DYLIB_INSTALL_NAME_BASE = "@rpath";
500 | INFOPLIST_FILE = "$(SRCROOT)/FittableFontLabel iOS/Info.plist";
501 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
502 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
503 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
504 | PRODUCT_BUNDLE_IDENTIFIER = com.tbaranes.FittableFontLabel;
505 | PRODUCT_NAME = FittableFontLabel;
506 | SKIP_INSTALL = YES;
507 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
508 | SWIFT_VERSION = 5.0;
509 | };
510 | name = ReleaseTest;
511 | };
512 | E251BE341CCE813100EA621A /* ReleaseTest */ = {
513 | isa = XCBuildConfiguration;
514 | buildSettings = {
515 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
516 | INFOPLIST_FILE = "FittableFontLabel iOS Tests/Info.plist";
517 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
518 | PRODUCT_BUNDLE_IDENTIFIER = com.tbaranes.FittableFontLabelTests;
519 | PRODUCT_NAME = "$(TARGET_NAME)";
520 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
521 | SWIFT_VERSION = 5.0;
522 | };
523 | name = ReleaseTest;
524 | };
525 | /* End XCBuildConfiguration section */
526 |
527 | /* Begin XCConfigurationList section */
528 | E2227A9C1CCE80C5006C4289 /* Build configuration list for PBXProject "FittableFontLabel" */ = {
529 | isa = XCConfigurationList;
530 | buildConfigurations = (
531 | E2227AB41CCE80C5006C4289 /* Debug */,
532 | E2227AB51CCE80C5006C4289 /* Release */,
533 | E251BE321CCE813100EA621A /* ReleaseTest */,
534 | );
535 | defaultConfigurationIsVisible = 0;
536 | defaultConfigurationName = Release;
537 | };
538 | E2227AB61CCE80C5006C4289 /* Build configuration list for PBXNativeTarget "FittableFontLabel iOS" */ = {
539 | isa = XCConfigurationList;
540 | buildConfigurations = (
541 | E2227AB71CCE80C5006C4289 /* Debug */,
542 | E2227AB81CCE80C5006C4289 /* Release */,
543 | E251BE331CCE813100EA621A /* ReleaseTest */,
544 | );
545 | defaultConfigurationIsVisible = 0;
546 | defaultConfigurationName = Release;
547 | };
548 | E2227AB91CCE80C5006C4289 /* Build configuration list for PBXNativeTarget "FittableFontLabel iOS Tests" */ = {
549 | isa = XCConfigurationList;
550 | buildConfigurations = (
551 | E2227ABA1CCE80C5006C4289 /* Debug */,
552 | E2227ABB1CCE80C5006C4289 /* Release */,
553 | E251BE341CCE813100EA621A /* ReleaseTest */,
554 | );
555 | defaultConfigurationIsVisible = 0;
556 | defaultConfigurationName = Release;
557 | };
558 | /* End XCConfigurationList section */
559 | };
560 | rootObject = E2227A991CCE80C5006C4289 /* Project object */;
561 | }
562 |
--------------------------------------------------------------------------------
/FittableFontLabel Example/iOS Example/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
29 |
39 |
45 |
61 |
67 |
81 |
87 |
104 |
110 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
--------------------------------------------------------------------------------