├── Example ├── SSDynamicTextExample │ ├── en.lproj │ │ └── InfoPlist.strings │ ├── SSDynamicsView.m │ ├── SSViewController.h │ ├── SSAppDelegate.h │ ├── main.m │ ├── SSDynamicTextExample-Prefix.pch │ ├── SSDynamicsView.h │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── LaunchImage.launchimage │ │ │ └── Contents.json │ ├── SSDynamicTextExample-Info.plist │ ├── SSAppDelegate.m │ ├── SSViewController.m │ └── SSDynamicsView.xib ├── Podfile ├── Podfile.lock ├── SSDynamicTextTests │ ├── SSAttributedStringValidator.h │ ├── SSTestsHelper.h │ ├── Info.plist │ ├── SSTestsHelper.m │ ├── UIFont+SSTextSizeTests.m │ ├── SSDynamicViewsReleaseTests.m │ ├── UIApplication+SSTextSizeTests.m │ ├── SSAttributedStringValidator.m │ ├── UIView+SSTextSizeTests.m │ ├── SSDynamicLabelTests.m │ ├── SSDynamicTextViewTests.m │ ├── SSDynamicTextFieldTests.m │ └── SSDynamicButtonTests.m └── SSDynamicTextExample.xcodeproj │ ├── xcshareddata │ └── xcschemes │ │ └── SSDynamicTextExample.xcscheme │ └── project.pbxproj ├── codecov.yml ├── .gitignore ├── SSDynamicText ├── UIFont+SSTextSize.m ├── NSAttributedString+SSTextSize.h ├── SSDynamicText.h ├── UIFont+SSTextSize.h ├── SSDynamicButton.h ├── Info.plist ├── UIApplication+SSTextSize.h ├── SSDynamicTextField.h ├── SSDynamicTextView.h ├── SSDynamicAttributedTextSizable.h ├── SSDynamicLabel.h ├── SSDynamicTextSizeChanger.h ├── NSAttributedString+SSTextSize.m ├── UIApplication+SSTextSize.m ├── SSDynamicTextSizeChanger.m ├── UIView+SSTextSize.h ├── SSDynamicLabel.m ├── SSDynamicTextView.m ├── SSDynamicTextField.m ├── UIView+SSTextSize.m └── SSDynamicButton.m ├── SSDynamicText.podspec ├── circle.yml ├── LICENSE ├── CHANGELOG.md ├── SSDynamicText.xcodeproj ├── xcshareddata │ └── xcschemes │ │ └── SSDynamicText.xcscheme └── project.pbxproj └── README.md /Example/SSDynamicTextExample/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Example/SSDynamicTextExample/SSDynamicsView.m: -------------------------------------------------------------------------------- 1 | // 2 | // SSDynamicsView.m 3 | // SSDynamicTextExample 4 | // 5 | // Created by Remigiusz Herba on 31/08/15. 6 | // 7 | // 8 | 9 | #import "SSDynamicsView.h" 10 | 11 | @implementation SSDynamicsView 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/cocoapods/specs.git' 2 | 3 | platform :ios, '7.0' 4 | 5 | target :SSDynamicTextExample do 6 | pod 'SSDynamicText', path: '..' 7 | 8 | target :SSDynamicTextTests do 9 | inherit! :search_paths 10 | pod 'OCMock', '~> 3' 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /Example/SSDynamicTextExample/SSViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SSViewController.h 3 | // SSLabelExample 4 | // 5 | // Created by Jonathan Hersh on 10/4/13. 6 | // Copyright (c) 2013 Splinesoft. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SSViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | comment: 2 | layout: "header, changes, diff, sunburst" 3 | coverage: 4 | ignore: 5 | - "Example/*" 6 | - "Applications/*" 7 | status: 8 | patch: 9 | default: 10 | target: 90% 11 | project: 12 | default: 13 | target: 90% 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | .DS_Store 3 | build/ 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | *.xcworkspace 13 | !default.xcworkspace 14 | xcuserdata 15 | profile 16 | *.moved-aside 17 | DerivedData 18 | .idea/ 19 | Example/Pods 20 | *.xcuserstate 21 | -------------------------------------------------------------------------------- /Example/SSDynamicTextExample/SSAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // SSAppDelegate.h 3 | // SSDynamicTextExample 4 | // 5 | // Created by Jonathan Hersh on 10/6/13. 6 | // Copyright (c) 2013 Splinesoft. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SSAppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Example/SSDynamicTextExample/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // SSDynamicTextExample 4 | // 5 | // Created by Jonathan Hersh on 10/6/13. 6 | // Copyright (c) 2013 Splinesoft. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "SSAppDelegate.h" 12 | 13 | int main(int argc, char * argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([SSAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Example/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - OCMock (3.1.5) 3 | - SSDynamicText (1.1.1) 4 | 5 | DEPENDENCIES: 6 | - OCMock (~> 3) 7 | - SSDynamicText (from `..`) 8 | 9 | EXTERNAL SOURCES: 10 | SSDynamicText: 11 | :path: ".." 12 | 13 | SPEC CHECKSUMS: 14 | OCMock: 4c2925291f80407c3738dd1db14d21d0cc278864 15 | SSDynamicText: e8700de63e0006e4438b235c38ffaa42aae227a8 16 | 17 | PODFILE CHECKSUM: 0e12a41ac296d50b08c14cb165dbb2d8a85fb3ae 18 | 19 | COCOAPODS: 1.1.1 20 | -------------------------------------------------------------------------------- /Example/SSDynamicTextExample/SSDynamicTextExample-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #import 8 | 9 | #ifndef __IPHONE_5_0 10 | #warning "This project uses features only available in iOS SDK 5.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | #import 15 | #import 16 | #endif 17 | -------------------------------------------------------------------------------- /Example/SSDynamicTextTests/SSAttributedStringValidator.h: -------------------------------------------------------------------------------- 1 | // 2 | // SSAttributedStringValidator.h 3 | // SSDynamicTextExample 4 | // 5 | // Created by Remigiusz Herba on 31/08/15. 6 | // Copyright (c) 2015 Splinesoft. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SSAttributedStringValidator : NSObject 12 | 13 | + (NSAttributedString *)testAttributedString; 14 | + (BOOL)isValidTestAttributedString:(NSAttributedString *)attributedString changedByDelta:(NSInteger)delta; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Example/SSDynamicTextExample/SSDynamicsView.h: -------------------------------------------------------------------------------- 1 | // 2 | // SSDynamicsView.h 3 | // SSDynamicTextExample 4 | // 5 | // Created by Remigiusz Herba on 31/08/15. 6 | // 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface SSDynamicsView : UIView 13 | 14 | @property (weak, nonatomic) IBOutlet SSDynamicLabel *label; 15 | @property (weak, nonatomic) IBOutlet SSDynamicTextField *textField; 16 | @property (weak, nonatomic) IBOutlet SSDynamicTextView *textView; 17 | @property (weak, nonatomic) IBOutlet SSDynamicButton *button; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /SSDynamicText/UIFont+SSTextSize.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIFont+SSTextSize.m 3 | // SSDynamicText 4 | // 5 | // Created by Jonathan Hersh on 5/16/13. 6 | // Copyright (c) 2013 Splinesoft. All rights reserved. 7 | // 8 | 9 | #import "UIFont+SSTextSize.h" 10 | #import "UIApplication+SSTextSize.h" 11 | 12 | @implementation UIFont (SSTextSize) 13 | 14 | + (instancetype)dynamicFontWithName:(NSString *)fontName baseSize:(CGFloat)baseSize { 15 | return [UIFont fontWithName:fontName 16 | size:(baseSize + [UIApplication sharedApplication].preferredFontSizeDelta)]; 17 | } 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /SSDynamicText/NSAttributedString+SSTextSize.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSAttributedString+SSTextSize.h 3 | // SSDynamicText 4 | // 5 | // Created by Remigiusz Herba on 28/08/15. 6 | // Copyright (c) 2015 Splinesoft. All rights reserved. 7 | // 8 | 9 | @import Foundation; 10 | 11 | @interface NSAttributedString (SSTextSize) 12 | 13 | /** 14 | * Creates NSAttributedString with each font size changed by delta 15 | * @param delta The size by which you want to change the font. 16 | * A negative number will decrease font size. 17 | * A positive number will increase font size. 18 | * @return new NSAttributedString object with font size changed by delta. 19 | */ 20 | - (nonnull NSAttributedString *)ss_attributedStringWithAdjustedFontSizeWithDelta:(NSInteger)delta; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /SSDynamicText/SSDynamicText.h: -------------------------------------------------------------------------------- 1 | // 2 | // SSDynamicText.h 3 | // SSDynamicText 4 | // 5 | // Created by Jonathan Hersh on 10/6/13. 6 | // Copyright (c) 2013 Splinesoft. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for SSDynamicText. 12 | FOUNDATION_EXPORT double SSDynamicTextVersionNumber; 13 | 14 | //! Project version string for SSDynamicText. 15 | FOUNDATION_EXPORT const unsigned char SSDynamicTextVersionString[]; 16 | 17 | #import "UIApplication+SSTextSize.h" 18 | #import "UIFont+SSTextSize.h" 19 | #import "UIView+SSTextSize.h" 20 | #import "NSAttributedString+SSTextSize.h" 21 | 22 | #import "SSDynamicLabel.h" 23 | #import "SSDynamicTextField.h" 24 | #import "SSDynamicTextView.h" 25 | #import "SSDynamicButton.h" 26 | -------------------------------------------------------------------------------- /Example/SSDynamicTextTests/SSTestsHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // SSTestsHelper.h 3 | // SSDynamicTextExample 4 | // 5 | // Created by Remigiusz Herba on 17/09/15. 6 | // Copyright (c) 2015 Splinesoft. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | extern NSString * const SSTestFontName; 12 | extern CGFloat const SSTestFontSize; 13 | extern CGFloat const SSTestFontSizeDifferenceForSizeExtraExtraLarge; 14 | 15 | @interface SSTestsHelper : NSObject 16 | 17 | + (void)startMockingPreferredContentSizeCategory:(NSString *)contentSizeCategory; 18 | + (void)stopMockingPreferredContentSizeCategory; 19 | + (void)postContentSizeChangeNotification; 20 | 21 | + (void)startMockingBundleDictionary:(NSDictionary *)dictionary; 22 | + (void)stopMockingBundleDictionary; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /SSDynamicText/UIFont+SSTextSize.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIFont+SSTextSize.h 3 | // SSDynamicText 4 | // 5 | // Created by Jonathan Hersh on 5/16/13. 6 | // Copyright (c) 2013 Splinesoft. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | 11 | @interface UIFont (SSTextSize) 12 | 13 | /** 14 | * Create a UIFont object using the specified font name and base size. 15 | * The actual size of the returned font is adjusted by 16 | * the user's current preferred font size (specified in Settings.app). 17 | * @param fontName Name of the font to use 18 | * @param baseSize Base size to use, offset by the user's preferred size. 19 | */ 20 | + (nullable instancetype)dynamicFontWithName:(nonnull NSString *)fontName 21 | baseSize:(CGFloat)baseSize; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /SSDynamicText.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'SSDynamicText' 3 | s.version = '1.1.1' 4 | s.summary = "UILabel/UIButton/UITextField/UITextView subclasses that support custom fonts with iOS 7's dynamic text sizes." 5 | s.homepage = 'https://github.com/splinesoft/SSDynamicText' 6 | s.license = { type: 'MIT', file: 'LICENSE' } 7 | s.author = { 'Jonathan Hersh' => 'jon@her.sh' } 8 | s.source = { git: 'https://github.com/splinesoft/SSDynamicText.git', tag: s.version.to_s } 9 | s.requires_arc = true 10 | s.compiler_flags = '-fmodules' 11 | s.source_files = 'SSDynamicText/*.{h,m}' 12 | s.frameworks = 'UIKit' 13 | s.ios.deployment_target = '7.0' 14 | s.social_media_url = 'https://twitter.com/jhersh' 15 | end 16 | -------------------------------------------------------------------------------- /Example/SSDynamicTextTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | net.splinesoft.$(PRODUCT_NAME:rfc1034identifier) 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 | -------------------------------------------------------------------------------- /SSDynamicText/SSDynamicButton.h: -------------------------------------------------------------------------------- 1 | // 2 | // SSDynamicButton.h 3 | // SSDynamicText 4 | // 5 | // Created by Adam Grzegorowski on 18/07/15. 6 | // Copyright (c) 2015 Splinesoft. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | 11 | /** 12 | * While creating this button in xib, don't forget to change it type to Custom !! 13 | */ 14 | @interface SSDynamicButton : UIButton 15 | 16 | /** 17 | * Create a button with dynamic-sizing title label that will adjust its size in response to changes 18 | * to the user's preferred text size. 19 | */ 20 | + (nonnull instancetype)buttonWithFont:(nonnull NSString *)fontName 21 | baseSize:(CGFloat)size; 22 | 23 | /** 24 | * Create a button with dynamic-sizing title label using a base font descriptor. 25 | */ 26 | + (nonnull instancetype)buttonWithFontDescriptor:(nullable UIFontDescriptor *)descriptor; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /SSDynamicText/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 | 1.1.1 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /SSDynamicText/UIApplication+SSTextSize.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIApplication+SSTextSize.h 3 | // SSDynamicText 4 | // 5 | // Created by Jonathan Hersh on 10/4/13. 6 | // Copyright (c) 2013 Splinesoft. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | 11 | @interface UIApplication (SSTextSize) 12 | 13 | /** 14 | * In iOS 7, the user can select his or her preferred font size in settings.app. 15 | * This property returns a numeric delta between the default size setting (Large) 16 | * and the user's current preferred text size. 17 | * 18 | * This is used as part of the UIFont+TextSize category. 19 | * 20 | * @return a delta between the default size setting and the user's current text size. 21 | * A negative number indicates the user has selected a size smaller than the default. 22 | * A positive number indicates the user has selected a size larger than the default. 23 | */ 24 | @property (nonatomic, readonly) NSInteger preferredFontSizeDelta; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /circle.yml: -------------------------------------------------------------------------------- 1 | machine: 2 | environment: 3 | LANG: en_US.UTF-8 4 | LC_CTYPE: en_US.UTF-8 5 | xcode: 6 | version: "8.0" 7 | dependencies: 8 | pre: 9 | - xcrun instruments -w "iPhone 6s (10.0)" || exit 0 10 | override: 11 | - sudo gem install cocoapods xcpretty obcd -N 12 | - pod install --project-directory=Example 13 | test: 14 | override: 15 | - set -o pipefail && xcodebuild -workspace Example/SSDynamicTextExample.xcworkspace 16 | -scheme SSDynamicTextExample -sdk iphonesimulator -destination "platform=iOS Simulator,name=iPhone 6s" 17 | GCC_INSTRUMENT_PROGRAM_FLOW_ARCS=YES GCC_GENERATE_TEST_COVERAGE_FILES=YES clean test ONLY_ACTIVE_ARCH=NO | xcpretty -c 18 | --report junit --output ${CIRCLE_TEST_REPORTS}/junit.xml 19 | - pod lib lint --quick 20 | - obcd --path SSDynamicText find HeaderStyle 21 | deployment: 22 | codecov: 23 | branch: /.*/ 24 | commands: 25 | - bash <(curl -s https://codecov.io/bash) 26 | -------------------------------------------------------------------------------- /SSDynamicText/SSDynamicTextField.h: -------------------------------------------------------------------------------- 1 | // 2 | // SSDynamicTextField.h 3 | // SSDynamicText 4 | // 5 | // Created by Jonathan Hersh on 10/6/13. 6 | // Copyright (c) 2013 Splinesoft. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | 11 | #import "SSDynamicAttributedTextSizable.h" 12 | 13 | @interface SSDynamicTextField : UITextField 14 | 15 | /** 16 | * Create a dynamic-sizing label that will adjust its size in response to changes 17 | * to the user's preferred text size. 18 | */ 19 | + (nonnull instancetype)textFieldWithFont:(nonnull NSString *)fontName 20 | baseSize:(CGFloat)size; 21 | 22 | /** 23 | * Create a dynamic-sizing label using a base font descriptor. 24 | * If `descriptor` is nil, sets font descriptor with `-ss_defaultFontName` and `-ss_defaultBaseSize` values. 25 | * @see ss_defaultFontName, ss_defaultBaseSize. 26 | */ 27 | + (nonnull instancetype)textFieldWithFontDescriptor:(nullable UIFontDescriptor *)descriptor; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /SSDynamicText/SSDynamicTextView.h: -------------------------------------------------------------------------------- 1 | // 2 | // SSDynamicTextView.h 3 | // SSDynamicText 4 | // 5 | // Created by Jonathan Hersh on 10/6/13. 6 | // Copyright (c) 2013 Splinesoft. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | 11 | #import "SSDynamicAttributedTextSizable.h" 12 | 13 | @interface SSDynamicTextView : UITextView 14 | 15 | /** 16 | * Create a dynamic-sizing textview that will adjust its size in response to changes 17 | * to the user's preferred text size. 18 | */ 19 | + (nonnull instancetype)textViewWithFont:(nonnull NSString *)fontName 20 | baseSize:(CGFloat)size; 21 | 22 | /** 23 | * Create a dynamic-sizing label using a base font descriptor. 24 | * If `descriptor` is nil, sets font descriptor with `-ss_defaultFontName` and `-ss_defaultBaseSize` values. 25 | * @see ss_defaultFontName, ss_defaultBaseSize. 26 | */ 27 | + (nonnull instancetype)textViewWithFontDescriptor:(nullable UIFontDescriptor *)descriptor; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /SSDynamicText/SSDynamicAttributedTextSizable.h: -------------------------------------------------------------------------------- 1 | // 2 | // SSDynamicAttributedTextSizable.h 3 | // SSDynamicText 4 | // 5 | // Created by Remigiusz Herba on 15/09/15. 6 | // Copyright (c) 2015 Splinesoft. All rights reserved. 7 | // 8 | 9 | @import Foundation; 10 | 11 | @protocol SSDynamicAttributedTextSizable 12 | 13 | /** 14 | * TextView and TextField sometimes calls setAttributedText even when we work with normal text. 15 | * Framework is using it under the hood sometimes after layouts or even `-setText:` calls it. Because of that we cannot override 16 | * default attributeText setter to change font, sometimes it change font at random. 17 | * 18 | * This is used to set attributedText which will be dynamicaly changed with font size changes. 19 | * Updating this will change attributedText to dynamicAttributedText + font sizes changed with delta. 20 | * @return original dynamicAttributedText value. To check current attributedText font sizes use @property attributedText. 21 | * 22 | */ 23 | @property (nonatomic, copy) NSAttributedString *dynamicAttributedText; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /Example/SSDynamicTextExample/Images.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" : "40x40", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "60x60", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "ipad", 20 | "size" : "29x29", 21 | "scale" : "1x" 22 | }, 23 | { 24 | "idiom" : "ipad", 25 | "size" : "29x29", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "ipad", 30 | "size" : "40x40", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "40x40", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "76x76", 41 | "scale" : "1x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "76x76", 46 | "scale" : "2x" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | } 53 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Jonathan Hersh 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /SSDynamicText/SSDynamicLabel.h: -------------------------------------------------------------------------------- 1 | // 2 | // SSDynamicLabel.h 3 | // SSDynamicText 4 | // 5 | // Created by Jonathan Hersh on 10/4/13. 6 | // Copyright (c) 2013 Splinesoft. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | 11 | #import "SSDynamicAttributedTextSizable.h" 12 | 13 | /** 14 | * In iOS 7, the user can set his or her preferred text size in Settings.app. 15 | * This label adjusts its font size by an offset determined by the user's preferred text size. 16 | */ 17 | 18 | @interface SSDynamicLabel : UILabel 19 | 20 | /** 21 | * Create a dynamic-sizing label that will adjust its size in response to changes 22 | * to the user's preferred text size. 23 | */ 24 | + (nonnull instancetype)labelWithFont:(nonnull NSString *)fontName 25 | baseSize:(CGFloat)size; 26 | 27 | /** 28 | * Create a dynamic-sizing label using a base font descriptor. 29 | * If `descriptor` is nil, sets font descriptor with `-ss_defaultFontName` and `-ss_defaultBaseSize` values. 30 | * @see ss_defaultFontName, ss_defaultBaseSize. 31 | */ 32 | + (nonnull instancetype)labelWithFontDescriptor:(nullable UIFontDescriptor *)descriptor; 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /Example/SSDynamicTextExample/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "7.0", 8 | "scale" : "2x" 9 | }, 10 | { 11 | "orientation" : "portrait", 12 | "idiom" : "iphone", 13 | "subtype" : "retina4", 14 | "extent" : "full-screen", 15 | "minimum-system-version" : "7.0", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "orientation" : "portrait", 20 | "idiom" : "ipad", 21 | "extent" : "full-screen", 22 | "minimum-system-version" : "7.0", 23 | "scale" : "1x" 24 | }, 25 | { 26 | "orientation" : "landscape", 27 | "idiom" : "ipad", 28 | "extent" : "full-screen", 29 | "minimum-system-version" : "7.0", 30 | "scale" : "1x" 31 | }, 32 | { 33 | "orientation" : "portrait", 34 | "idiom" : "ipad", 35 | "extent" : "full-screen", 36 | "minimum-system-version" : "7.0", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "orientation" : "landscape", 41 | "idiom" : "ipad", 42 | "extent" : "full-screen", 43 | "minimum-system-version" : "7.0", 44 | "scale" : "2x" 45 | } 46 | ], 47 | "info" : { 48 | "version" : 1, 49 | "author" : "xcode" 50 | } 51 | } -------------------------------------------------------------------------------- /SSDynamicText/SSDynamicTextSizeChanger.h: -------------------------------------------------------------------------------- 1 | // 2 | // SSDynamicTextSizeChanger.h 3 | // SSDynamicText 4 | // 5 | // Created by Remigiusz Herba on 15/09/15. 6 | // Copyright (c) 2015 Splinesoft. All rights reserved. 7 | // 8 | 9 | @import Foundation; 10 | 11 | #import "SSDynamicAttributedTextSizable.h" 12 | #import "UIView+SSTextSize.h" 13 | 14 | @interface SSDynamicTextSizeChanger : NSObject 15 | 16 | /** 17 | * The default font descriptor used by view. 18 | * Its size is adjusted up (or down) based on the user's preferred text size. 19 | * Updating this will change the view's font. 20 | */ 21 | @property (nonatomic, strong, nullable) UIFontDescriptor *defaultFontDescriptor; 22 | 23 | /** 24 | * The default block called by view when font size change. 25 | */ 26 | @property (nonatomic, readonly, nullable) SSTextSizeChangedBlock changeHandler; 27 | 28 | /** 29 | * Block which is called when SSDynamicTextSizeChanger want to change font, view should configure this block. 30 | */ 31 | @property (nonatomic, copy, nullable) void(^fontChangeBlock)(UIFont * __nullable font); 32 | 33 | /** 34 | * Block which is called when SSDynamicTextSizeChanger want to change attributedText, view should configure this block. 35 | */ 36 | @property (nonatomic, copy, nullable) void(^attributedTextChangeBlock)(NSAttributedString * __nullable attributedString); 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /SSDynamicText/NSAttributedString+SSTextSize.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSAttributedString+SSTextSize.m 3 | // SSDynamicText 4 | // 5 | // Created by Remigiusz Herba on 28/08/15. 6 | // Copyright (c) 2015 Splinesoft. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | 11 | #import "NSAttributedString+SSTextSize.h" 12 | 13 | @implementation NSAttributedString (SSTextSize) 14 | 15 | - (NSAttributedString *)ss_attributedStringWithAdjustedFontSizeWithDelta:(NSInteger)delta { 16 | NSMutableAttributedString *attributedString = [self mutableCopy]; 17 | [attributedString beginEditing]; 18 | [attributedString enumerateAttribute:NSFontAttributeName 19 | inRange:NSMakeRange(0, attributedString.length) 20 | options:0 21 | usingBlock:^(UIFont *value, NSRange range, BOOL *stop) { 22 | 23 | if (value) { 24 | UIFont *newFont = [UIFont fontWithDescriptor:value.fontDescriptor size:value.pointSize + delta]; 25 | [attributedString removeAttribute:NSFontAttributeName range:range]; 26 | [attributedString addAttribute:NSFontAttributeName value:newFont range:range]; 27 | } 28 | }]; 29 | [attributedString endEditing]; 30 | return [attributedString copy]; 31 | } 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /SSDynamicText/UIApplication+SSTextSize.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIApplication+SSTextSize.m 3 | // SSDynamicText 4 | // 5 | // Created by Jonathan Hersh on 10/4/13. 6 | // Copyright (c) 2013 Splinesoft. All rights reserved. 7 | // 8 | 9 | #import "UIApplication+SSTextSize.h" 10 | 11 | @implementation UIApplication (SSTextSize) 12 | 13 | - (NSInteger)preferredFontSizeDelta { 14 | static NSArray *fontSizes; 15 | static dispatch_once_t onceToken; 16 | dispatch_once(&onceToken, ^{ 17 | fontSizes = @[ 18 | UIContentSizeCategoryExtraSmall, 19 | UIContentSizeCategorySmall, 20 | UIContentSizeCategoryMedium, 21 | UIContentSizeCategoryLarge, 22 | UIContentSizeCategoryExtraLarge, 23 | UIContentSizeCategoryExtraExtraLarge, 24 | UIContentSizeCategoryExtraExtraExtraLarge, 25 | UIContentSizeCategoryAccessibilityMedium, 26 | UIContentSizeCategoryAccessibilityLarge, 27 | UIContentSizeCategoryAccessibilityExtraLarge, 28 | UIContentSizeCategoryAccessibilityExtraExtraLarge, 29 | UIContentSizeCategoryAccessibilityExtraExtraExtraLarge, 30 | ]; 31 | }); 32 | 33 | NSUInteger currentSize = [fontSizes indexOfObject:self.preferredContentSizeCategory]; 34 | 35 | if (currentSize == NSNotFound) { 36 | return 0; 37 | } 38 | 39 | // Default size is 'Large' 40 | return currentSize - [fontSizes indexOfObject:UIContentSizeCategoryLarge]; 41 | } 42 | 43 | @end 44 | -------------------------------------------------------------------------------- /Example/SSDynamicTextTests/SSTestsHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // SSTestsHelper.m 3 | // SSDynamicTextExample 4 | // 5 | // Created by Remigiusz Herba on 17/09/15. 6 | // Copyright (c) 2015 Splinesoft. All rights reserved. 7 | // 8 | 9 | #import "SSTestsHelper.h" 10 | #import 11 | 12 | NSString * const SSTestFontName = @"Avenir-Roman"; 13 | CGFloat const SSTestFontSize = 14.f; 14 | CGFloat const SSTestFontSizeDifferenceForSizeExtraExtraLarge = 2.f; 15 | 16 | static id applicationMock; 17 | static id bundleMock; 18 | 19 | @implementation SSTestsHelper 20 | 21 | + (void)startMockingPreferredContentSizeCategory:(NSString *)contentSizeCategory { 22 | if (applicationMock) { 23 | [self stopMockingPreferredContentSizeCategory]; 24 | } 25 | 26 | applicationMock = OCMPartialMock([UIApplication sharedApplication]); 27 | OCMStub([applicationMock preferredContentSizeCategory]).andReturn(contentSizeCategory); 28 | } 29 | 30 | + (void)stopMockingPreferredContentSizeCategory { 31 | [applicationMock stopMocking]; 32 | applicationMock = nil; 33 | } 34 | 35 | + (void)postContentSizeChangeNotification { 36 | [[NSNotificationCenter defaultCenter] postNotificationName:UIContentSizeCategoryDidChangeNotification object:nil]; 37 | } 38 | 39 | + (void)startMockingBundleDictionary:(NSDictionary *)dictionary { 40 | if (bundleMock) { 41 | [self stopMockingBundleDictionary]; 42 | } 43 | 44 | bundleMock = OCMPartialMock([NSBundle mainBundle]); 45 | OCMStub([bundleMock infoDictionary]).andReturn(dictionary); 46 | } 47 | 48 | + (void)stopMockingBundleDictionary { 49 | [bundleMock stopMocking]; 50 | bundleMock = nil; 51 | } 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /Example/SSDynamicTextExample/SSDynamicTextExample-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | net.splinesoft.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /Example/SSDynamicTextTests/UIFont+SSTextSizeTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIFont+SSTextSizeTests.m 3 | // SSDynamicTextExample 4 | // 5 | // Created by Adam Grzegorowski on 30/11/15. 6 | // Copyright (c) 2015 Splinesoft. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "UIFont+SSTextSize.h" 12 | #import "UIApplication+SSTextSize.h" 13 | #import "SSTestsHelper.h" 14 | 15 | @interface UIFont_SSTextSizeTests : XCTestCase 16 | 17 | @end 18 | 19 | @implementation UIFont_SSTextSizeTests 20 | 21 | - (void)testDynamicFontWithNameBaseSizeShouldReturnFontWithSizeIncreasedOfPreferredFontSizeDelta { 22 | 23 | //Arrange 24 | NSArray *contentSizeCategories = @[ 25 | UIContentSizeCategoryExtraSmall, 26 | UIContentSizeCategorySmall, 27 | UIContentSizeCategoryMedium, 28 | UIContentSizeCategoryLarge, 29 | UIContentSizeCategoryExtraLarge, 30 | UIContentSizeCategoryExtraExtraLarge, 31 | UIContentSizeCategoryExtraExtraExtraLarge, 32 | UIContentSizeCategoryAccessibilityMedium, 33 | UIContentSizeCategoryAccessibilityLarge, 34 | UIContentSizeCategoryAccessibilityExtraLarge, 35 | UIContentSizeCategoryAccessibilityExtraExtraLarge, 36 | UIContentSizeCategoryAccessibilityExtraExtraExtraLarge, 37 | ]; 38 | 39 | for (NSString *contentSizeCategory in contentSizeCategories) { 40 | 41 | [SSTestsHelper startMockingPreferredContentSizeCategory:contentSizeCategory]; 42 | NSInteger preferredFontSizeDelta = [UIApplication sharedApplication].preferredFontSizeDelta; 43 | 44 | //Act 45 | UIFont *font = [UIFont dynamicFontWithName:SSTestFontName baseSize:SSTestFontSize]; 46 | 47 | //Assert 48 | XCTAssertEqualWithAccuracy(font.pointSize, SSTestFontSize + preferredFontSizeDelta, FLT_EPSILON); 49 | 50 | //Clean Up 51 | [SSTestsHelper stopMockingPreferredContentSizeCategory]; 52 | } 53 | } 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /SSDynamicText/SSDynamicTextSizeChanger.m: -------------------------------------------------------------------------------- 1 | // 2 | // SSDynamicTextSizeChanger.m 3 | // SSDynamicText 4 | // 5 | // Created by Remigiusz Herba on 15/09/15. 6 | // Copyright (c) 2015 Splinesoft. All rights reserved. 7 | // 8 | 9 | #import "SSDynamicTextSizeChanger.h" 10 | #import "NSAttributedString+SSTextSize.h" 11 | #import "UIApplication+SSTextSize.h" 12 | 13 | @interface SSDynamicTextSizeChanger() 14 | 15 | @property (nonatomic, copy) NSAttributedString *baseAttributedText; 16 | 17 | @end 18 | 19 | @implementation SSDynamicTextSizeChanger 20 | 21 | - (void)changeAttributedStringFontWithDelta:(NSInteger)newDelta { 22 | if (self.attributedTextChangeBlock) { 23 | self.attributedTextChangeBlock([self.baseAttributedText ss_attributedStringWithAdjustedFontSizeWithDelta:newDelta]); 24 | } 25 | } 26 | 27 | - (void)changeFontWithDelta:(NSInteger)newDelta { 28 | CGFloat preferredSize = [self.defaultFontDescriptor.fontAttributes[UIFontDescriptorSizeAttribute] floatValue]; 29 | preferredSize += newDelta; 30 | 31 | if (self.fontChangeBlock) { 32 | self.fontChangeBlock([UIFont fontWithDescriptor:self.defaultFontDescriptor 33 | size:preferredSize]); 34 | } 35 | } 36 | 37 | - (SSTextSizeChangedBlock)changeHandler { 38 | __weak typeof(self) weakSelf = self; 39 | 40 | SSTextSizeChangedBlock changeHandler = ^(NSInteger newDelta) { 41 | [weakSelf changeFontWithDelta:newDelta]; 42 | if (weakSelf.baseAttributedText.length > 0) { 43 | [weakSelf changeAttributedStringFontWithDelta:newDelta]; 44 | } 45 | }; 46 | return changeHandler; 47 | } 48 | 49 | #pragma mark - SSDynamicAttributedTextSizable 50 | 51 | - (NSAttributedString *)dynamicAttributedText { 52 | return self.baseAttributedText; 53 | } 54 | 55 | - (void)setDynamicAttributedText:(NSAttributedString *)attributedText { 56 | self.baseAttributedText = [attributedText copy]; 57 | [self changeAttributedStringFontWithDelta:[UIApplication sharedApplication].preferredFontSizeDelta]; 58 | } 59 | 60 | @end 61 | -------------------------------------------------------------------------------- /SSDynamicText/UIView+SSTextSize.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+SSTextSize.h 3 | // SSDynamicText 4 | // 5 | // Created by Jonathan Hersh on 10/4/13. 6 | // Copyright (c) 2013 Splinesoft. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | 11 | UIKIT_EXTERN NSString * __nonnull const kSSDynamicDefaultFontName; 12 | UIKIT_EXTERN NSString * __nonnull const kSSDynamicDefaultBaseSize; 13 | 14 | @interface UIView (SSTextSize) 15 | 16 | typedef void (^SSTextSizeChangedBlock) (NSInteger); 17 | 18 | /** 19 | * The default font descriptor used by this view. 20 | * Its size is adjusted up (or down) based on the user's preferred text size. 21 | * Updating this will change the view's font. 22 | */ 23 | @property (nonatomic, strong, nullable) UIFontDescriptor *defaultFontDescriptor; 24 | 25 | /** 26 | * Default FontName if set in Info.plist or systemFontName if not set. 27 | * Key: kSSDynamicDefaultFontName 28 | */ 29 | @property (nonatomic, readonly, nonnull) NSString *ss_defaultFontName; 30 | 31 | /** 32 | * DefaultBaseSize if set in Info.plist or 16.0f if not set. 33 | * Key: kSSDynamicDefaultBaseSize 34 | */ 35 | @property (nonatomic, readonly) CGFloat ss_defaultBaseSize; 36 | 37 | /* 38 | * Begin observing changes to the user's preferred text size with the given callback block. 39 | * When the user changes her preferred text size, the callback block is called with the 40 | * new text size delta from the default. 41 | */ 42 | - (void)ss_startObservingTextSizeChangesWithBlock:(nonnull SSTextSizeChangedBlock)block; 43 | 44 | /** 45 | * Stop observing changes to text size. 46 | */ 47 | - (void)ss_stopObservingTextSizeChanges; 48 | 49 | /** 50 | * Force a recalculation of our preferred text size. 51 | */ 52 | - (void)preferredContentSizeDidChange; 53 | 54 | /** 55 | * Sets `defaultFontDescriptor` based on font parameter. 56 | * If font parameter is `nil`, sets `defaultFontDesciptor` with default font name and default base size. 57 | * @see defaultFontDescriptor, ss_defaultFontName, ss_defaultBaseSize. 58 | */ 59 | - (void)setupDefaultFontDescriptorBasedOnFont:(nullable UIFont *)font; 60 | 61 | @end 62 | -------------------------------------------------------------------------------- /Example/SSDynamicTextTests/SSDynamicViewsReleaseTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // SSDynamicViewReleaseTests.m 3 | // SSDynamicTextExample 4 | // 5 | // Created by Adam Grzegorowski on 06/12/15. 6 | // Copyright (c) 2015 Splinesoft. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SSTestsHelper.h" 11 | #import "SSDynamicText.h" 12 | 13 | @interface SSDynamicViewsReleaseTests : XCTestCase 14 | @end 15 | 16 | @implementation SSDynamicViewsReleaseTests 17 | 18 | - (void)testDynamicLabelShouldBeReleaseable { 19 | // Arrange 20 | __weak SSDynamicLabel *label = nil; 21 | 22 | // Act 23 | @autoreleasepool { 24 | label = [[SSDynamicLabel alloc] init]; 25 | label.defaultFontDescriptor = [UIFontDescriptor fontDescriptorWithName:SSTestFontName size:SSTestFontSize]; 26 | } 27 | 28 | // Assert 29 | XCTAssertNil(label); 30 | } 31 | 32 | 33 | - (void)testDynamicButtonShouldShouldBeReleaseable { 34 | // Arrange 35 | __weak SSDynamicButton *button = nil; 36 | 37 | // Act 38 | @autoreleasepool { 39 | button = [[SSDynamicButton alloc] init]; 40 | button.defaultFontDescriptor = [UIFontDescriptor fontDescriptorWithName:SSTestFontName size:SSTestFontSize]; 41 | } 42 | 43 | // Assert 44 | XCTAssertNil(button); 45 | } 46 | 47 | - (void)testDynamicTextViewShouldShouldBeReleaseable { 48 | // Arrange 49 | __weak SSDynamicTextView *textView = nil; 50 | 51 | @autoreleasepool { 52 | // Act 53 | textView = [[SSDynamicTextView alloc] init]; 54 | textView.defaultFontDescriptor = [UIFontDescriptor fontDescriptorWithName:SSTestFontName size:SSTestFontSize]; 55 | } 56 | 57 | // Assert 58 | XCTAssertNil(textView); 59 | } 60 | 61 | - (void)testDynamicTextFieldShouldBeReleaseable { 62 | // Arrange 63 | __weak SSDynamicTextField *textField = nil; 64 | 65 | @autoreleasepool { 66 | // Act 67 | textField = [[SSDynamicTextField alloc] init]; 68 | textField.defaultFontDescriptor = [UIFontDescriptor fontDescriptorWithName:SSTestFontName size:SSTestFontSize]; 69 | } 70 | 71 | // Assert 72 | XCTAssertNil(textField); 73 | } 74 | 75 | @end 76 | -------------------------------------------------------------------------------- /Example/SSDynamicTextExample/SSAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // SSAppDelegate.m 3 | // SSDynamicTextExample 4 | // 5 | // Created by Jonathan Hersh on 10/6/13. 6 | // Copyright (c) 2013 Splinesoft. All rights reserved. 7 | // 8 | 9 | #import "SSAppDelegate.h" 10 | #import "SSViewController.h" 11 | 12 | @implementation SSAppDelegate 13 | 14 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 15 | { 16 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 17 | self.window.rootViewController = [SSViewController new]; 18 | [self.window makeKeyAndVisible]; 19 | 20 | return YES; 21 | } 22 | 23 | - (void)applicationWillResignActive:(UIApplication *)application 24 | { 25 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 26 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 27 | } 28 | 29 | - (void)applicationDidEnterBackground:(UIApplication *)application 30 | { 31 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | - (void)applicationWillEnterForeground:(UIApplication *)application 36 | { 37 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 38 | } 39 | 40 | - (void)applicationDidBecomeActive:(UIApplication *)application 41 | { 42 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 43 | } 44 | 45 | - (void)applicationWillTerminate:(UIApplication *)application 46 | { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /Example/SSDynamicTextTests/UIApplication+SSTextSizeTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIApplication+SSTextSizeTests.m 3 | // SSDynamicTextExample 4 | // 5 | // Created by Adam Grzegorowski on 01/12/15. 6 | // Copyright (c) 2015 Splinesoft. All rights reserved. 7 | // 8 | 9 | #import "UIApplication+SSTextSize.h" 10 | #import "SSTestsHelper.h" 11 | 12 | #import 13 | 14 | @interface UIApplication_SSTextSizeTests : XCTestCase 15 | 16 | @end 17 | 18 | @implementation UIApplication_SSTextSizeTests 19 | 20 | - (void)testPreferredFontSizeDeltaForKnownContentSizeCategories { 21 | //Arrange 22 | NSDictionary *contentSizeCategoriesWithDeltas = @{ 23 | UIContentSizeCategoryExtraSmall : @(-3), 24 | UIContentSizeCategorySmall : @(-2), 25 | UIContentSizeCategoryMedium : @(-1), 26 | UIContentSizeCategoryLarge : @0, 27 | UIContentSizeCategoryExtraLarge : @1, 28 | UIContentSizeCategoryExtraExtraLarge : @2, 29 | UIContentSizeCategoryExtraExtraExtraLarge : @3, 30 | UIContentSizeCategoryAccessibilityMedium : @4, 31 | UIContentSizeCategoryAccessibilityLarge : @5, 32 | UIContentSizeCategoryAccessibilityExtraLarge : @6, 33 | UIContentSizeCategoryAccessibilityExtraExtraLarge : @7, 34 | UIContentSizeCategoryAccessibilityExtraExtraExtraLarge : @8, 35 | }; 36 | 37 | [contentSizeCategoriesWithDeltas enumerateKeysAndObjectsUsingBlock:^(NSString *contentSizeCategory, NSNumber *contentSizeDelta, BOOL *stop) { 38 | 39 | [SSTestsHelper startMockingPreferredContentSizeCategory:contentSizeCategory]; 40 | 41 | //Act 42 | NSInteger preferredFontSizeDelta = [UIApplication sharedApplication].preferredFontSizeDelta; 43 | 44 | //Assert 45 | XCTAssertEqual(preferredFontSizeDelta, contentSizeDelta.integerValue, @"Font size delta should be zero"); 46 | 47 | //Clean Up 48 | [SSTestsHelper stopMockingPreferredContentSizeCategory]; 49 | }]; 50 | } 51 | 52 | // In next versions of iOS might be provided new size category. For such cases use default delta size, which is zero. 53 | - (void)testPreferredFontSizeDeltaShouldBeEqualToZeroForUnknownContentSizeCategory { 54 | //Arrange 55 | [SSTestsHelper startMockingPreferredContentSizeCategory:@"NewContentSizeCategory"]; 56 | 57 | //Act 58 | NSInteger preferredFontSizeDelta = [UIApplication sharedApplication].preferredFontSizeDelta; 59 | 60 | //Assert 61 | XCTAssertEqual(preferredFontSizeDelta, 0, @"Font size delta should be zero, for uknown content size category"); 62 | 63 | //Clean Up 64 | [SSTestsHelper stopMockingPreferredContentSizeCategory]; 65 | } 66 | 67 | @end 68 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # SSDynamicText CHANGELOG 2 | 3 | ## 1.1.1 4 | ###### January 8, 2016 5 | 6 | - **(fixed)** Fixed memory leak caused by strong retain cycle in `SSDynamicLabel`, `SSDynamicTextView` and `SSDynamicTextField` classes, [#40](https://github.com/splinesoft/SSDynamicText/issues/40). _([Grubas7](https://github.com/Grubas7))_ 7 | 8 | ## 1.1.0 9 | ###### September 26, 2016 10 | 11 | - **(fixed)** Fixed IB crash for `SSDynamicButton` subclasses, [#36](https://github.com/splinesoft/SSDynamicText/issues/36). _([Grubas7](https://github.com/Grubas7))_ 12 | - **(added)** Added Carthage support (by creating SSDynamicText project with framework target). _([Grubas7](https://github.com/Grubas7))_ 13 | 14 | ## 1.0.0 15 | ###### June 5, 2016 16 | 17 | - **(fixed)** Fixed `titleLabel` font upgrade for `SSDynamicButton` after font change, [#27](https://github.com/splinesoft/SSDynamicText/issues/27). _([Grubas7](https://github.com/Grubas7))_ 18 | - **(modified)** Changed `ss_defaultFontName`, and `ss_defaultBaseSize` from methods to readonly properties. _([Grubas7](https://github.com/Grubas7))_ 19 | 20 | ## 0.5.0 21 | ###### October 5, 2015 22 | 23 | - **(added)** Added `NSAttributedString` support. _([Remiki](https://github.com/Remki))_ 24 | 25 | ## 0.4.0 26 | ###### July 19, 2015 27 | 28 | - **(added)** Added `SSDynamicButton` class, [#8](https://github.com/splinesoft/SSDynamicText/issues/8). _([Grubas7](https://github.com/Grubas7))_ 29 | - **(modified)** Made views class methods inheritable, issue [#7](https://github.com/splinesoft/SSDynamicText/issues/7). _([jhersh](https://github.com/jhersh))_ 30 | 31 | ## 0.3.0 32 | ###### July 15, 2015 33 | 34 | - **(modified)** Removed double initialization for views, [#6](https://github.com/splinesoft/SSDynamicText/issues/6). _([jhersh](https://github.com/jhersh))_ 35 | 36 | ## 0.2.2 37 | ###### April 24, 2015 38 | 39 | - **(added)** Added support for accessibility content size categories. _([Remiki](https://github.com/Remki))_ 40 | - **(modifed)** Fixed font and font size settings for views loaded from Interface Builder. _([Remiki](https://github.com/Remki))_ 41 | 42 | ## 0.2.1 43 | ###### October 30, 2014 44 | 45 | - **(added)** Added `-ss_defaultFontName` and `-ss_defaultBaseSize` methods to `UIView+SSTextSize` class. _([angrauel](https://github.com/angrauel))_ 46 | 47 | ## 0.2.0 48 | ###### October 23, 2014 49 | 50 | - **(added)** Added Interface Builder support. _([angrauel](https://github.com/angrauel))_ 51 | 52 | ## 0.1.0 53 | ###### October 7, 2013 54 | 55 | - **(added)** Added `SSDynamicTextView`, `SSDynamicTextField` and `UIView+SSTextSize` classes. _([jhersh](https://github.com/jhersh))_ 56 | - **(modified)** Renamed `SSLabel` to `SSDynamicLabel`. _([jhersh](https://github.com/jhersh))_ 57 | 58 | ## 0.0.1 59 | ###### October 7, 2013 60 | 61 | - **(added)** Added `SSDynamicLabel`, `UIFont+SSTextSize` and `UIApplication+SSTextSize` classes. _([jhersh](https://github.com/jhersh))_ 62 | -------------------------------------------------------------------------------- /SSDynamicText.xcodeproj/xcshareddata/xcschemes/SSDynamicText.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /SSDynamicText/SSDynamicLabel.m: -------------------------------------------------------------------------------- 1 | // 2 | // SSDynamicLabel.m 3 | // SSDynamicText 4 | // 5 | // Created by Jonathan Hersh on 10/4/13. 6 | // Copyright (c) 2013 Splinesoft. All rights reserved. 7 | // 8 | 9 | #import "SSDynamicLabel.h" 10 | #import "SSDynamicTextSizeChanger.h" 11 | 12 | @interface SSDynamicLabel () 13 | 14 | @property (nonatomic, strong) SSDynamicTextSizeChanger *textSizeChanger; 15 | 16 | @end 17 | 18 | @implementation SSDynamicLabel 19 | 20 | - (instancetype)initWithFrame:(CGRect)frame { 21 | if (self = [super initWithFrame:frame]) { 22 | [self startObservingTextSizeChanges]; 23 | } 24 | 25 | return self; 26 | } 27 | 28 | - (void)awakeFromNib { 29 | [super awakeFromNib]; 30 | 31 | [self setupDefaultFontDescriptorBasedOnFont:self.font]; 32 | [self startObservingTextSizeChanges]; 33 | } 34 | 35 | + (instancetype)labelWithFont:(NSString *)fontName baseSize:(CGFloat)size { 36 | UIFontDescriptor *fontDescriptor = [UIFontDescriptor fontDescriptorWithName:fontName size:size]; 37 | 38 | return [self labelWithFontDescriptor:fontDescriptor]; 39 | } 40 | 41 | + (instancetype)labelWithFontDescriptor:(UIFontDescriptor *)descriptor { 42 | SSDynamicLabel *label = [self new]; 43 | label.defaultFontDescriptor = descriptor; 44 | 45 | return label; 46 | } 47 | 48 | - (void)dealloc { 49 | [self ss_stopObservingTextSizeChanges]; 50 | } 51 | 52 | #pragma mark - Accessors 53 | 54 | - (void)setDefaultFontDescriptor:(UIFontDescriptor *)defaultFontDescriptor { 55 | self.textSizeChanger.defaultFontDescriptor = defaultFontDescriptor; 56 | super.defaultFontDescriptor = defaultFontDescriptor; 57 | } 58 | 59 | - (void)setFont:(UIFont *)font { 60 | [super setFont:font]; 61 | [self setupDefaultFontDescriptorBasedOnFont:self.font]; 62 | } 63 | 64 | #pragma mark - Private Methods 65 | 66 | - (SSDynamicTextSizeChanger *)textSizeChanger { 67 | if (_textSizeChanger == nil) { 68 | _textSizeChanger = [self createTextChanger]; 69 | } 70 | return _textSizeChanger; 71 | } 72 | 73 | - (SSDynamicTextSizeChanger *)createTextChanger { 74 | SSDynamicTextSizeChanger *changer = [[SSDynamicTextSizeChanger alloc] init]; 75 | __weak typeof(self) weakSelf = self; 76 | 77 | changer.fontChangeBlock = ^(UIFont *font) { 78 | // https://github.com/splinesoft/SSDynamicText/issues/40 79 | [weakSelf superSetFont:font]; 80 | }; 81 | 82 | changer.attributedTextChangeBlock = ^(NSAttributedString *attributedText) { 83 | weakSelf.attributedText = attributedText; 84 | }; 85 | return changer; 86 | } 87 | 88 | - (void)superSetFont:(UIFont *)font { 89 | [super setFont:font]; 90 | } 91 | 92 | - (void)startObservingTextSizeChanges { 93 | [self ss_startObservingTextSizeChangesWithBlock:self.textSizeChanger.changeHandler]; 94 | } 95 | 96 | #pragma mark - SSDynamicAttributedTextSizable 97 | 98 | - (NSAttributedString *)dynamicAttributedText { 99 | return self.textSizeChanger.dynamicAttributedText; 100 | } 101 | 102 | - (void)setDynamicAttributedText:(NSAttributedString *)attributedText { 103 | self.textSizeChanger.dynamicAttributedText = attributedText; 104 | } 105 | 106 | @end 107 | -------------------------------------------------------------------------------- /SSDynamicText/SSDynamicTextView.m: -------------------------------------------------------------------------------- 1 | // 2 | // SSDynamicTextView.m 3 | // SSDynamicText 4 | // 5 | // Created by Jonathan Hersh on 10/6/13. 6 | // Copyright (c) 2013 Splinesoft. All rights reserved. 7 | // 8 | 9 | #import "SSDynamicTextView.h" 10 | #import "SSDynamicTextSizeChanger.h" 11 | 12 | @interface SSDynamicTextView () 13 | 14 | @property (nonatomic, strong) SSDynamicTextSizeChanger *textSizeChanger; 15 | 16 | @end 17 | 18 | @implementation SSDynamicTextView 19 | 20 | - (instancetype)initWithFrame:(CGRect)frame { 21 | if (self = [super initWithFrame:frame]) { 22 | [self startObservingTextSizeChanges]; 23 | } 24 | 25 | return self; 26 | } 27 | 28 | - (void)awakeFromNib { 29 | [super awakeFromNib]; 30 | 31 | [self setupDefaultFontDescriptorBasedOnFont:self.font]; 32 | [self startObservingTextSizeChanges]; 33 | } 34 | 35 | + (instancetype)textViewWithFont:(NSString *)fontName baseSize:(CGFloat)size { 36 | UIFontDescriptor *fontDescriptor = [UIFontDescriptor fontDescriptorWithName:fontName size:size]; 37 | 38 | return [self textViewWithFontDescriptor:fontDescriptor]; 39 | } 40 | 41 | + (instancetype)textViewWithFontDescriptor:(UIFontDescriptor *)descriptor { 42 | SSDynamicTextView *textView = [self new]; 43 | textView.defaultFontDescriptor = descriptor; 44 | 45 | return textView; 46 | } 47 | 48 | - (void)dealloc { 49 | [self ss_stopObservingTextSizeChanges]; 50 | } 51 | 52 | #pragma mark - Accessors 53 | 54 | - (void)setDefaultFontDescriptor:(UIFontDescriptor *)defaultFontDescriptor { 55 | self.textSizeChanger.defaultFontDescriptor = defaultFontDescriptor; 56 | [super setDefaultFontDescriptor:defaultFontDescriptor]; 57 | } 58 | 59 | - (void)setFont:(UIFont *)font { 60 | [super setFont:font]; 61 | [self setupDefaultFontDescriptorBasedOnFont:self.font]; 62 | } 63 | 64 | #pragma mark - Private Methods 65 | 66 | - (SSDynamicTextSizeChanger *)textSizeChanger { 67 | if (_textSizeChanger == nil) { 68 | _textSizeChanger = [self createTextChanger]; 69 | } 70 | return _textSizeChanger; 71 | } 72 | 73 | - (SSDynamicTextSizeChanger *)createTextChanger { 74 | SSDynamicTextSizeChanger *changer = [[SSDynamicTextSizeChanger alloc] init]; 75 | __weak typeof(self) weakSelf = self; 76 | 77 | changer.fontChangeBlock = ^(UIFont *font) { 78 | // https://github.com/splinesoft/SSDynamicText/issues/40 79 | [weakSelf superSetFont:font]; 80 | }; 81 | 82 | changer.attributedTextChangeBlock = ^(NSAttributedString *attributedText) { 83 | weakSelf.attributedText = attributedText; 84 | }; 85 | return changer; 86 | } 87 | 88 | - (void)superSetFont:(UIFont *)font { 89 | [super setFont:font]; 90 | } 91 | 92 | - (void)startObservingTextSizeChanges { 93 | [self ss_startObservingTextSizeChangesWithBlock:self.textSizeChanger.changeHandler]; 94 | } 95 | 96 | #pragma mark - SSDynamicAttributedTextSizable 97 | 98 | - (NSAttributedString *)dynamicAttributedText { 99 | return self.textSizeChanger.dynamicAttributedText; 100 | } 101 | 102 | - (void)setDynamicAttributedText:(NSAttributedString *)attributedText { 103 | self.textSizeChanger.dynamicAttributedText = attributedText; 104 | } 105 | 106 | @end 107 | -------------------------------------------------------------------------------- /SSDynamicText/SSDynamicTextField.m: -------------------------------------------------------------------------------- 1 | // 2 | // SSDynamicTextField.m 3 | // SSDynamicText 4 | // 5 | // Created by Jonathan Hersh on 10/6/13. 6 | // Copyright (c) 2013 Splinesoft. All rights reserved. 7 | // 8 | 9 | #import "SSDynamicTextField.h" 10 | #import "SSDynamicTextSizeChanger.h" 11 | 12 | @interface SSDynamicTextField () 13 | 14 | @property (nonatomic, strong) SSDynamicTextSizeChanger *textSizeChanger; 15 | 16 | @end 17 | 18 | @implementation SSDynamicTextField 19 | 20 | - (instancetype)initWithFrame:(CGRect)frame { 21 | if (self = [super initWithFrame:frame]) { 22 | [self startObservingTextSizeChanges]; 23 | } 24 | 25 | return self; 26 | } 27 | 28 | - (void)awakeFromNib { 29 | [super awakeFromNib]; 30 | 31 | [self setupDefaultFontDescriptorBasedOnFont:self.font]; 32 | [self startObservingTextSizeChanges]; 33 | } 34 | 35 | + (instancetype)textFieldWithFont:(NSString *)fontName baseSize:(CGFloat)size { 36 | UIFontDescriptor *fontDescriptor = [UIFontDescriptor fontDescriptorWithName:fontName size:size]; 37 | 38 | return [self textFieldWithFontDescriptor:fontDescriptor]; 39 | } 40 | 41 | + (instancetype)textFieldWithFontDescriptor:(UIFontDescriptor *)descriptor { 42 | SSDynamicTextField *textField = [self new]; 43 | textField.defaultFontDescriptor = descriptor; 44 | 45 | return textField; 46 | } 47 | 48 | - (void)dealloc { 49 | [self ss_stopObservingTextSizeChanges]; 50 | } 51 | 52 | #pragma mark - Accessors 53 | 54 | - (void)setDefaultFontDescriptor:(UIFontDescriptor *)defaultFontDescriptor { 55 | self.textSizeChanger.defaultFontDescriptor = defaultFontDescriptor; 56 | super.defaultFontDescriptor = defaultFontDescriptor; 57 | } 58 | 59 | - (void)setFont:(UIFont *)font { 60 | [super setFont:font]; 61 | [self setupDefaultFontDescriptorBasedOnFont:self.font]; 62 | } 63 | 64 | #pragma mark - Private Methods 65 | 66 | - (SSDynamicTextSizeChanger *)textSizeChanger { 67 | if (_textSizeChanger == nil) { 68 | _textSizeChanger = [self createTextChanger]; 69 | } 70 | return _textSizeChanger; 71 | } 72 | 73 | - (SSDynamicTextSizeChanger *)createTextChanger { 74 | SSDynamicTextSizeChanger *changer = [[SSDynamicTextSizeChanger alloc] init]; 75 | __weak typeof(self) weakSelf = self; 76 | 77 | changer.fontChangeBlock = ^(UIFont *font) { 78 | // https://github.com/splinesoft/SSDynamicText/issues/40 79 | [weakSelf superSetFont:font]; 80 | }; 81 | 82 | changer.attributedTextChangeBlock = ^(NSAttributedString *attributedText) { 83 | weakSelf.attributedText = attributedText; 84 | }; 85 | return changer; 86 | } 87 | 88 | - (void)superSetFont:(UIFont *)font { 89 | [super setFont:font]; 90 | } 91 | 92 | - (void)startObservingTextSizeChanges { 93 | [self ss_startObservingTextSizeChangesWithBlock:self.textSizeChanger.changeHandler]; 94 | } 95 | 96 | #pragma mark - SSDynamicAttributedTextSizable 97 | 98 | - (NSAttributedString *)dynamicAttributedText { 99 | return self.textSizeChanger.dynamicAttributedText; 100 | } 101 | 102 | - (void)setDynamicAttributedText:(NSAttributedString *)attributedText { 103 | self.textSizeChanger.dynamicAttributedText = attributedText; 104 | } 105 | 106 | @end 107 | -------------------------------------------------------------------------------- /Example/SSDynamicTextTests/SSAttributedStringValidator.m: -------------------------------------------------------------------------------- 1 | // 2 | // SSAttributedStringValidator.m 3 | // SSDynamicTextExample 4 | // 5 | // Created by Remigiusz Herba on 31/08/15. 6 | // 7 | // 8 | 9 | #import "SSAttributedStringValidator.h" 10 | 11 | static NSString * const kTestStringFirstPart = @"Test"; 12 | static NSString * const kTestStringSecondPart = @" string"; 13 | 14 | @implementation SSAttributedStringValidator 15 | 16 | + (UIFont *)firstFont { 17 | static UIFont *firstFont; 18 | static dispatch_once_t onceToken; 19 | dispatch_once(&onceToken, ^{ 20 | firstFont = [UIFont systemFontOfSize:16.0f]; 21 | }); 22 | return firstFont; 23 | } 24 | 25 | + (UIFont *)secondFont { 26 | static UIFont *secondFont; 27 | static dispatch_once_t onceToken; 28 | dispatch_once(&onceToken, ^{ 29 | secondFont = [UIFont fontWithName:@"Courier" size:25.0f]; 30 | }); 31 | return secondFont; 32 | } 33 | 34 | + (NSString *)testString { 35 | static NSString *string; 36 | static dispatch_once_t onceToken; 37 | dispatch_once(&onceToken, ^{ 38 | string = [NSString stringWithFormat:@"%@%@", kTestStringFirstPart, kTestStringSecondPart]; 39 | }); 40 | return string; 41 | } 42 | 43 | #pragma mark - Public Methods 44 | 45 | + (NSAttributedString *)testAttributedString { 46 | NSDictionary *attributes = 47 | @{NSForegroundColorAttributeName: [UIColor blackColor], NSFontAttributeName: [self firstFont]}; 48 | 49 | NSDictionary *secondAttributes = 50 | @{NSForegroundColorAttributeName: [UIColor blueColor], NSFontAttributeName: [self secondFont]}; 51 | 52 | NSMutableAttributedString *testString = [[NSMutableAttributedString alloc] initWithString:[self testString] attributes:attributes]; 53 | [testString addAttributes:secondAttributes range:[[self testString] rangeOfString:kTestStringSecondPart]]; 54 | 55 | return testString; 56 | } 57 | 58 | + (BOOL)isValidTestAttributedString:(NSAttributedString *)attributedString changedByDelta:(NSInteger)delta { 59 | __block BOOL isFirstFontValid = NO; 60 | __block BOOL isSecondFontValid = NO; 61 | UIFont *firstFont = [self firstFont]; 62 | UIFont *secondFont = [self secondFont]; 63 | 64 | [attributedString enumerateAttribute:NSFontAttributeName 65 | inRange:NSMakeRange(0, attributedString.length) 66 | options:0 67 | usingBlock:^(UIFont *value, NSRange range, BOOL *stop) { 68 | 69 | if (value) { 70 | if (NSEqualRanges(range, [[self testString] rangeOfString:kTestStringFirstPart])) { 71 | if ([value.fontName isEqualToString:firstFont.fontName] 72 | && value.pointSize == firstFont.pointSize + delta) { 73 | isFirstFontValid = YES; 74 | } 75 | } 76 | if (NSEqualRanges(range, [[self testString] rangeOfString:kTestStringSecondPart])) { 77 | if ([value.fontName isEqualToString:secondFont.fontName] 78 | && value.pointSize == secondFont.pointSize + delta) { 79 | isSecondFontValid = YES; 80 | } 81 | } 82 | } 83 | }]; 84 | return isFirstFontValid && isSecondFontValid; 85 | } 86 | 87 | @end 88 | -------------------------------------------------------------------------------- /SSDynamicText/UIView+SSTextSize.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+SSTextSize.m 3 | // SSDynamicText 4 | // 5 | // Created by Jonathan Hersh on 10/4/13. 6 | // Copyright (c) 2013 Splinesoft. All rights reserved. 7 | // 8 | 9 | #import "UIView+SSTextSize.h" 10 | #import "UIApplication+SSTextSize.h" 11 | #import 12 | 13 | static char kTextSizeChangedBlockKey; 14 | static char kDefaultFontDescriptorKey; 15 | 16 | NSString * const kSSDynamicDefaultFontName = @"SSDynamicDefaultFontName"; 17 | NSString * const kSSDynamicDefaultBaseSize = @"SSDynamicDefaultBaseSize"; 18 | 19 | @implementation UIView (SSTextSize) 20 | 21 | #pragma mark - default font descriptor 22 | 23 | - (UIFontDescriptor *)defaultFontDescriptor { 24 | return (UIFontDescriptor *)objc_getAssociatedObject(self, &kDefaultFontDescriptorKey); 25 | } 26 | 27 | - (void)setDefaultFontDescriptor:(UIFontDescriptor *)defaultFontDescriptor { 28 | objc_setAssociatedObject(self, &kDefaultFontDescriptorKey, defaultFontDescriptor, OBJC_ASSOCIATION_COPY_NONATOMIC); 29 | 30 | [self preferredContentSizeDidChange]; 31 | } 32 | 33 | #pragma mark - text size changes 34 | 35 | - (void)ss_startObservingTextSizeChangesWithBlock:(SSTextSizeChangedBlock)block { 36 | NSParameterAssert(block); 37 | 38 | [self ss_stopObservingTextSizeChanges]; 39 | 40 | objc_setAssociatedObject(self, &kTextSizeChangedBlockKey, block, OBJC_ASSOCIATION_COPY); 41 | 42 | [[NSNotificationCenter defaultCenter] addObserver:self 43 | selector:@selector(preferredContentSizeDidChange) 44 | name:UIContentSizeCategoryDidChangeNotification 45 | object:nil]; 46 | 47 | [self preferredContentSizeDidChange]; 48 | } 49 | 50 | - (void)ss_stopObservingTextSizeChanges { 51 | objc_setAssociatedObject(self, &kTextSizeChangedBlockKey, nil, OBJC_ASSOCIATION_ASSIGN); 52 | 53 | [[NSNotificationCenter defaultCenter] removeObserver:self 54 | name:UIContentSizeCategoryDidChangeNotification 55 | object:nil]; 56 | } 57 | 58 | - (void)preferredContentSizeDidChange { 59 | NSInteger newDelta = [UIApplication sharedApplication].preferredFontSizeDelta; 60 | 61 | SSTextSizeChangedBlock changeBlock = (SSTextSizeChangedBlock)objc_getAssociatedObject(self, &kTextSizeChangedBlockKey); 62 | 63 | if (changeBlock) { 64 | changeBlock(newDelta); 65 | } 66 | 67 | [self invalidateIntrinsicContentSize]; 68 | [self setNeedsDisplay]; 69 | } 70 | 71 | #pragma mark - Default Fonts 72 | 73 | - (NSString *)ss_defaultFontName { 74 | NSString *defaultFontName = [NSBundle mainBundle].infoDictionary[kSSDynamicDefaultFontName]; 75 | return (defaultFontName ?: [UIFont systemFontOfSize:[self ss_defaultBaseSize]].fontName); 76 | } 77 | 78 | - (CGFloat)ss_defaultBaseSize { 79 | CGFloat defaultBaseSize = [[NSBundle mainBundle].infoDictionary[kSSDynamicDefaultBaseSize] floatValue]; 80 | return (defaultBaseSize == 0.0f ? 16.0f : defaultBaseSize); 81 | } 82 | 83 | - (void)setupDefaultFontDescriptorBasedOnFont:(UIFont *)font { 84 | NSString *fontName; 85 | CGFloat baseSize = 0.0f; 86 | 87 | if (font) { 88 | fontName = font.fontName; 89 | baseSize = font.pointSize; 90 | } 91 | 92 | fontName = (fontName ?: self.ss_defaultFontName); 93 | baseSize = (baseSize ?: self.ss_defaultBaseSize); 94 | 95 | self.defaultFontDescriptor = (font.fontDescriptor ?: [UIFontDescriptor fontDescriptorWithName:fontName 96 | size:baseSize]); 97 | } 98 | 99 | @end 100 | -------------------------------------------------------------------------------- /Example/SSDynamicTextExample.xcodeproj/xcshareddata/xcschemes/SSDynamicTextExample.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 61 | 62 | 68 | 69 | 70 | 71 | 72 | 73 | 79 | 80 | 86 | 87 | 88 | 89 | 91 | 92 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /Example/SSDynamicTextTests/UIView+SSTextSizeTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+SSTextSizeTests.m 3 | // SSDynamicTextExample 4 | // 5 | // Created by Adam Grzegorowski on 01/12/15. 6 | // Copyright (c) 2015 Splinesoft. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SSTestsHelper.h" 11 | 12 | #import "UIView+SSTextSize.h" 13 | #import "SSDynamicLabel.h" 14 | 15 | @interface UIView_SSTextSizeTests : XCTestCase 16 | 17 | @property (nonatomic, strong) SSDynamicLabel *label; 18 | 19 | @end 20 | 21 | @implementation UIView_SSTextSizeTests 22 | 23 | 24 | - (void)setUp { 25 | [super setUp]; 26 | 27 | self.label = [SSDynamicLabel labelWithFont:SSTestFontName baseSize:SSTestFontSize]; 28 | } 29 | 30 | - (void)testDefaultBaseSizeShouldBeEqualToInfoBundleIfSet { 31 | //Arrange 32 | CGFloat expectedBaseSize = 123; 33 | NSDictionary *baseSizeDictionary = [NSDictionary dictionaryWithObject:@(expectedBaseSize) forKey:kSSDynamicDefaultBaseSize]; 34 | [SSTestsHelper startMockingBundleDictionary:baseSizeDictionary]; 35 | 36 | //Act 37 | CGFloat baseSize = [self.label ss_defaultBaseSize]; 38 | 39 | //Assert 40 | XCTAssertEqualWithAccuracy(expectedBaseSize, baseSize, FLT_EPSILON, @"Default base size should be %f", expectedBaseSize); 41 | 42 | //Clean Up 43 | [SSTestsHelper stopMockingBundleDictionary]; 44 | } 45 | 46 | - (void)testDefaultBaseSizeShouldBeEqualTo16IfInfoBundleNotSet { 47 | //Arrange 48 | [SSTestsHelper startMockingBundleDictionary:nil]; 49 | 50 | //Act 51 | CGFloat baseSize = [self.label ss_defaultBaseSize]; 52 | 53 | //Assert 54 | XCTAssertEqualWithAccuracy(baseSize, 16, FLT_EPSILON, @"Default base size should be 16"); 55 | 56 | //Clean Up 57 | [SSTestsHelper stopMockingBundleDictionary]; 58 | } 59 | 60 | - (void)testDefaultFontNameShouldBeEqualToInfoBundleIfSet { 61 | // Arrange 62 | NSString *expectedfontName = SSTestFontName; 63 | NSDictionary *fontNameDictionary = [NSDictionary dictionaryWithObject:expectedfontName forKey:kSSDynamicDefaultFontName]; 64 | [SSTestsHelper startMockingBundleDictionary:fontNameDictionary]; 65 | 66 | NSString *fontName = [self.label ss_defaultFontName]; 67 | 68 | //Assert 69 | XCTAssertEqualObjects(fontName, expectedfontName, @"Default base name should be %@", expectedfontName); 70 | 71 | //Clean Up 72 | [SSTestsHelper stopMockingBundleDictionary]; 73 | } 74 | 75 | - (void)testDefaultFontNameShouldBeEqualToSystemFontIfInfoBundleNotSet { 76 | //Arrange 77 | NSString *expectedFontName = [UIFont systemFontOfSize:SSTestFontSize].fontName; 78 | [SSTestsHelper startMockingBundleDictionary:nil]; 79 | 80 | //Act 81 | NSString *fontName = [self.label ss_defaultFontName]; 82 | 83 | //Assert 84 | XCTAssertEqualObjects(fontName, expectedFontName, @"Default base name should be %@", expectedFontName); 85 | 86 | //Clean Up 87 | [SSTestsHelper stopMockingBundleDictionary]; 88 | } 89 | 90 | - (void)testSetupDefaultFontDescriptiorBasedOnFontShouldBeEqualToInitialFontDescriptor { 91 | //Arrange 92 | UIFontDescriptor *fontDescriptor = [UIFontDescriptor fontDescriptorWithName:SSTestFontName size:SSTestFontSize]; 93 | SSDynamicLabel *label = [SSDynamicLabel labelWithFontDescriptor:fontDescriptor]; 94 | 95 | //Act 96 | [label setupDefaultFontDescriptorBasedOnFont:[UIFont fontWithDescriptor:fontDescriptor size:SSTestFontSize]]; 97 | 98 | //Assert 99 | XCTAssertEqualObjects(label.defaultFontDescriptor, fontDescriptor, 100 | @"Default font descriptor should have font %@ with size %f" , fontDescriptor.postscriptName, fontDescriptor.pointSize); 101 | } 102 | 103 | - (void)testSetupDefaultFontDescriptiorBasedOnNilFontShouldSetFontDescriptorWithDefaultValues { 104 | //Arrange 105 | UIView *testView = [[UIView alloc] init]; 106 | UIFontDescriptor *fontDescriptor = [UIFontDescriptor fontDescriptorWithName:[testView ss_defaultFontName] size:[testView ss_defaultBaseSize]]; 107 | 108 | //Act 109 | [testView setupDefaultFontDescriptorBasedOnFont:nil]; 110 | 111 | //Assert 112 | XCTAssertEqualObjects(testView.defaultFontDescriptor, fontDescriptor, 113 | @"Default font descriptor should have font %@ with size 16" , [UIFont systemFontOfSize:16.0].fontName); 114 | } 115 | 116 | @end 117 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | SSDynamicText 2 | ============= 3 | 4 | [![Circle CI](https://circleci.com/gh/splinesoft/SSDynamicText.svg?style=svg)](https://circleci.com/gh/splinesoft/SSDynamicText) [![codecov.io](http://codecov.io/github/splinesoft/SSDynamicText/coverage.svg?branch=master)](http://codecov.io/github/splinesoft/SSDynamicText?branch=master) 5 | [![Version](https://img.shields.io/cocoapods/v/SSDynamicText.svg)](http://cocoapods.org/pods/SSDynamicText) 6 | [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) 7 | 8 | iOS 7's [`UIFontDescriptor`](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIFontDescriptor_Class/) is pretty neat. Also pretty neat is dynamic text that responds to the preferred text size that the user specified in Settings.app. 9 | 10 | What's not so neat, though, is that `+[UIFont preferredFontForTextStyle:]` only works with the system font, Helvetica Neue (iOS 8) or San Francisco (iOS 9). What if you have custom fonts and want to respect the user's text size preference? 11 | 12 | SSDynamicText is a collection of simple `UILabel`, `UIButton`, `UITextField`, and `UITextView` subclasses inspired by [this](http://stackoverflow.com/questions/18758227/ios7-can-we-use-other-than-helvetica-neue-fonts-with-dynamic-type/19024944#19024944) SO answer. 13 | 14 | ## Requirements 15 | 16 | Xcode 7.0+ with iOS 7.0+ SDK. 17 | 18 | ## Install 19 | 20 | ### [CocoaPods](http://cocoapods.org) 21 | Add to your `Podfile`: 22 | 23 | ```ruby 24 | pod 'SSDynamicText', '~> 1.1.1' 25 | ``` 26 | 27 | ### [Carthage](https://github.com/Carthage/Carthage) 28 | Add to your `Cartfile`: 29 | 30 | ```ruby 31 | github "splinesoft/SSDynamicText", ~> 1.1.1 32 | ``` 33 | 34 | ## Example usage 35 | 36 | `SSDynamicText` provides dynamic auto-sizing labels, buttons, text fields, and text views that respond when the user changes her preferred text size. Check out a full [example](https://github.com/splinesoft/SSDynamicText/blob/master/Example/SSDynamicTextExample/SSViewController.m). 37 | 38 | UIKit views that responds when the user changes her preferred text size: 39 | 40 | ### `SSDynamicLabel` 41 | 42 | ```objc 43 | SSDynamicLabel *myLabel = [SSDynamicLabel labelWithFont:@"Courier" 44 | baseSize:16.0f]; 45 | myLabel.text = @"Auto-sizing text!"; 46 | 47 | // Already have a font descriptor? 48 | UIFontDescriptor *aDescriptor = [UIFontDescriptor fontDescriptorWithName:@"Courier" 49 | size:16.0f]; 50 | SSDynamicLabel *otherLabel = [SSDynamicLabel labelWithFontDescriptor:aDescriptor]; 51 | ``` 52 | 53 | ### `SSDynamicButton` 54 | 55 | ```objc 56 | SSDynamicButton *myButton = [SSDynamicButton buttonWithFont:@"Courier" 57 | baseSize:16.0f]; 58 | [myButton setText:@"Auto-sizing text!" forControlState:UIControlStateNormal]; 59 | ``` 60 | 61 | ### `SSDynamicTextField` 62 | 63 | ```objc 64 | SSDynamicTextField *myTextField = [SSDynamicTextField textFieldWithFont:@"Courier" 65 | baseSize:16.0f]; 66 | myTextField.text = @"Auto-sizing text!"; 67 | ``` 68 | 69 | ### `SSDynamicTextView` 70 | 71 | ```objc 72 | SSDynamicTextView *myTextView = [SSDynamicTextView textViewWithFont:@"Courier" 73 | baseSize:16.0f]; 74 | myTextView.text = @"Auto-sizing text!"; 75 | ``` 76 | 77 | ## `UIFont+SSTextSize` 78 | 79 | Create a `UIFont` object using the specified font name and base size. 80 | The actual size of the returned font is adjusted by the user's current preferred font size (specified in Settings.app). 81 | 82 | ```objc 83 | UIFont *myFont = [UIFont dynamicFontWithName:@"Courier" baseSize:16.0f]; 84 | ``` 85 | 86 | ## `UIApplication+SSTextSize` 87 | 88 | This property returns a numeric delta between the default size setting (Large) and the user's current preferred text size. 89 | 90 | You probably don't need to use this directly. 91 | 92 | ```objc 93 | NSInteger textDelta = [[UIApplication sharedApplication] preferredFontSizeDelta]; 94 | ``` 95 | 96 | ## `NSAttributedString` Support 97 | 98 | SSDynamicText supports attributed text! Assign your `NSAttributedString` to the new `dynamicAttributedText` property. 99 | 100 | `UITextView` and `UITextField` sometimes internally call `-setAttributedText:` even with normal text. To best accommodate that internal implementation detail, we've added a new `dynamicAttribtuedText` property instead of overriding `-setAttributedText:`. 101 | 102 | ```objc 103 | @property (nonatomic, copy) NSAttributedString *dynamicAttributedText; 104 | ``` 105 | 106 | ## Thanks! 107 | 108 | `SSDynamicText` is a [@jhersh](https://github.com/jhersh) production -- ([electronic mail](mailto:jon@her.sh) | [@jhersh](https://twitter.com/jhersh)) 109 | -------------------------------------------------------------------------------- /SSDynamicText/SSDynamicButton.m: -------------------------------------------------------------------------------- 1 | // 2 | // SSDynamicButton.m 3 | // SSDynamicText 4 | // 5 | // Created by Adam Grzegorowski on 18/07/15. 6 | // Copyright (c) 2015 Splinesoft. All rights reserved. 7 | // 8 | 9 | #import "SSDynamicButton.h" 10 | #import "UIApplication+SSTextSize.h" 11 | #import "UIView+SSTextSize.h" 12 | #import "NSAttributedString+SSTextSize.h" 13 | 14 | @interface SSDynamicButton () 15 | 16 | @property (nonatomic, strong) NSMutableDictionary *baseAttributedTitlesDictionary; 17 | 18 | @end 19 | 20 | @implementation SSDynamicButton 21 | 22 | - (instancetype)initWithFrame:(CGRect)frame { 23 | if (self = [super initWithFrame:frame]) { 24 | [self setup]; 25 | } 26 | 27 | return self; 28 | } 29 | 30 | - (void)awakeFromNib { 31 | [super awakeFromNib]; 32 | 33 | NSAssert(self.buttonType == UIButtonTypeCustom, @"Change SSDynamicButton.buttonType to UIButtonTypeCustom in your nib"); 34 | [self setupDefaultFontDescriptorBasedOnFont:self.titleLabel.font]; 35 | 36 | [self setup]; 37 | } 38 | 39 | + (instancetype)buttonWithFont:(NSString *)fontName baseSize:(CGFloat)size { 40 | UIFontDescriptor *fontDescriptor = [UIFontDescriptor fontDescriptorWithName:fontName size:size]; 41 | 42 | return [self buttonWithFontDescriptor:fontDescriptor]; 43 | } 44 | 45 | + (instancetype)buttonWithFontDescriptor:(UIFontDescriptor *)descriptor { 46 | SSDynamicButton *button = [self new]; 47 | button.defaultFontDescriptor = descriptor; 48 | return button; 49 | } 50 | 51 | - (void)dealloc { 52 | [self ss_stopObservingTextSizeChanges]; 53 | [self removeTitleLabelFontObserver]; 54 | } 55 | 56 | - (void)setAttributedTitle:(NSAttributedString *)title forState:(UIControlState)state { 57 | NSNumber *key = @(state); 58 | if (title) { 59 | [self.baseAttributedTitlesDictionary setObject:title forKey:key]; 60 | } else { 61 | [self.baseAttributedTitlesDictionary removeObjectForKey:key]; 62 | } 63 | [self changeAttributedTitle:title forState:state withFontSizeDelta:[UIApplication sharedApplication].preferredFontSizeDelta]; 64 | } 65 | 66 | #pragma mark - Private methods 67 | 68 | - (void)setup { 69 | __weak typeof(self) weakSelf = self; 70 | 71 | [self addTitleLabelFontObserver]; 72 | 73 | SSTextSizeChangedBlock changeHandler = ^(NSInteger newDelta) { 74 | 75 | [weakSelf changeFontWithDelta:newDelta]; 76 | [weakSelf changeAttributedStringWithDelta:newDelta]; 77 | }; 78 | 79 | [self ss_startObservingTextSizeChangesWithBlock:changeHandler]; 80 | } 81 | 82 | - (void)changeFontWithDelta:(NSInteger)newDelta { 83 | CGFloat preferredSize = [self.defaultFontDescriptor.fontAttributes[UIFontDescriptorSizeAttribute] floatValue]; 84 | preferredSize += newDelta; 85 | 86 | [self removeTitleLabelFontObserver]; 87 | self.titleLabel.font = [UIFont fontWithDescriptor:self.defaultFontDescriptor 88 | size:preferredSize]; 89 | 90 | [self addTitleLabelFontObserver]; 91 | } 92 | 93 | - (void)changeAttributedTitle:(NSAttributedString *)attributedTitle forState:(UIControlState)state withFontSizeDelta:(NSInteger)newDelta { 94 | [super setAttributedTitle:[attributedTitle ss_attributedStringWithAdjustedFontSizeWithDelta:newDelta] forState:state]; 95 | } 96 | 97 | - (void)changeAttributedStringWithDelta:(NSInteger)newDelta { 98 | [self.baseAttributedTitlesDictionary enumerateKeysAndObjectsUsingBlock:^(NSNumber *key, NSAttributedString *title, BOOL *stop) { 99 | [self changeAttributedTitle:title forState:key.unsignedIntegerValue withFontSizeDelta:newDelta]; 100 | }]; 101 | } 102 | 103 | #pragma mark - Accessors 104 | 105 | - (NSMutableDictionary *)baseAttributedTitlesDictionary { 106 | if (_baseAttributedTitlesDictionary == nil) { 107 | _baseAttributedTitlesDictionary = [NSMutableDictionary dictionary]; 108 | } 109 | return _baseAttributedTitlesDictionary; 110 | } 111 | 112 | #pragma mark - Font observing 113 | 114 | - (void)addTitleLabelFontObserver { 115 | #if !TARGET_INTERFACE_BUILDER 116 | [self.titleLabel addObserver:self forKeyPath:NSStringFromSelector(@selector(font)) options:NSKeyValueObservingOptionNew context:NULL]; 117 | #endif 118 | } 119 | 120 | - (void)removeTitleLabelFontObserver { 121 | #if !TARGET_INTERFACE_BUILDER 122 | [self.titleLabel removeObserver:self forKeyPath:NSStringFromSelector(@selector(font))]; 123 | #endif 124 | } 125 | 126 | - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { 127 | if ([keyPath isEqualToString:NSStringFromSelector(@selector(font))]) { 128 | 129 | NSInteger newDelta = [UIApplication sharedApplication].preferredFontSizeDelta; 130 | [self setupDefaultFontDescriptorBasedOnFont:self.titleLabel.font]; 131 | 132 | [self changeFontWithDelta:newDelta]; 133 | [self changeAttributedStringWithDelta:newDelta]; 134 | } else { 135 | [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; 136 | } 137 | } 138 | 139 | @end 140 | -------------------------------------------------------------------------------- /Example/SSDynamicTextTests/SSDynamicLabelTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // SSDynamicLabelTests.m 3 | // SSDynamicTextExample 4 | // 5 | // Created by Remigiusz Herba on 31/08/15. 6 | // Copyright (c) 2015 Splinesoft. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SSTestsHelper.h" 11 | #import "SSAttributedStringValidator.h" 12 | 13 | #import "SSDynamicLabel.h" 14 | #import "SSDynamicsView.h" 15 | 16 | @interface SSDynamicLabelTests : XCTestCase 17 | @end 18 | 19 | @implementation SSDynamicLabelTests 20 | 21 | - (void)setUp { 22 | [super setUp]; 23 | 24 | //Default content size category 25 | [SSTestsHelper startMockingPreferredContentSizeCategory:UIContentSizeCategoryLarge]; 26 | } 27 | 28 | - (void)tearDown { 29 | [SSTestsHelper stopMockingPreferredContentSizeCategory]; 30 | [super tearDown]; 31 | } 32 | 33 | - (NSArray *)dynamicLabelsWithFontName:(NSString *)fontName fontSize:(CGFloat)fontSize { 34 | UIFontDescriptor *fontDescriptor = [UIFontDescriptor fontDescriptorWithName:fontName size:fontSize]; 35 | 36 | SSDynamicLabel *dynamicLabel = [[SSDynamicLabel alloc] init]; 37 | dynamicLabel.defaultFontDescriptor = fontDescriptor; 38 | 39 | SSDynamicLabel *dynamicLabelWithFrame = [[SSDynamicLabel alloc] initWithFrame:CGRectZero]; 40 | dynamicLabelWithFrame.font = [UIFont fontWithName:fontName size:fontSize]; 41 | 42 | SSDynamicLabel *dynamicLabelWithFont = [SSDynamicLabel labelWithFont:fontName baseSize:fontSize]; 43 | 44 | SSDynamicLabel *dynamicLabelWithFontDescriptor = [SSDynamicLabel labelWithFontDescriptor:fontDescriptor]; 45 | 46 | SSDynamicsView *view = [[NSBundle mainBundle] loadNibNamed:@"SSDynamicsView" owner:nil options:nil].firstObject; 47 | SSDynamicLabel *dynamicLabelFromXib = view.label; 48 | 49 | return @[ dynamicLabel, dynamicLabelWithFrame, dynamicLabelWithFont, dynamicLabelWithFontDescriptor, dynamicLabelFromXib ]; 50 | } 51 | 52 | - (void)testLabelFontNameShouldBeEqualToFontNameFromConstructor { 53 | //Arrange 54 | NSString *expectedFontName = SSTestFontName; 55 | 56 | //Act 57 | NSArray *dynamicLabels = [self dynamicLabelsWithFontName:SSTestFontName fontSize:SSTestFontSize]; 58 | 59 | for (SSDynamicLabel *label in dynamicLabels) { 60 | //Assert 61 | XCTAssertEqualObjects(label.font.fontName, expectedFontName); 62 | } 63 | } 64 | 65 | - (void)testLabelFontSizeShouldBeEqualToFontSizeInConstructorForDefaultPreferredContentSizeCategory { 66 | //Arrange 67 | CGFloat expectedFontSize = SSTestFontSize; 68 | 69 | //Act 70 | NSArray *dynamicLabels = [self dynamicLabelsWithFontName:SSTestFontName fontSize:SSTestFontSize]; 71 | 72 | for (SSDynamicLabel *label in dynamicLabels) { 73 | //Assert 74 | XCTAssertEqualWithAccuracy(label.font.pointSize, expectedFontSize, FLT_EPSILON); 75 | } 76 | } 77 | 78 | - (void)testLabelFontSizeShouldBeEqualToLabelFontSizeIncreasedByPreferredContentSizeCategoryDelta { 79 | // Arrange 80 | [SSTestsHelper startMockingPreferredContentSizeCategory:UIContentSizeCategoryExtraExtraLarge]; 81 | 82 | CGFloat initialFontSize = SSTestFontSize; 83 | 84 | //Act 85 | NSArray *dynamicLabels = [self dynamicLabelsWithFontName:SSTestFontName fontSize:initialFontSize]; 86 | 87 | for (SSDynamicLabel *label in dynamicLabels) { 88 | 89 | //Assert 90 | XCTAssertEqualWithAccuracy(label.font.pointSize, initialFontSize + SSTestFontSizeDifferenceForSizeExtraExtraLarge, FLT_EPSILON); 91 | } 92 | } 93 | 94 | - (void)testLabelFontSizeShouldBeEqualToNewFontSizeIncreasedByContentSizeCategoryDelta { 95 | //Arrange 96 | CGFloat newFontSize = 7.0f; 97 | UIFont *newFont = [UIFont systemFontOfSize:newFontSize]; 98 | 99 | NSArray *dynamicLabels = [self dynamicLabelsWithFontName:SSTestFontName fontSize:SSTestFontSize]; 100 | 101 | [SSTestsHelper startMockingPreferredContentSizeCategory:UIContentSizeCategoryExtraExtraLarge]; 102 | 103 | for (SSDynamicLabel *label in dynamicLabels) { 104 | //Act 105 | label.font = newFont; 106 | 107 | //Assert 108 | XCTAssertEqualWithAccuracy(label.font.pointSize, newFontSize + SSTestFontSizeDifferenceForSizeExtraExtraLarge, FLT_EPSILON); 109 | } 110 | } 111 | 112 | - (void)testLabelAttributedStringFontSizesShouldBeIncreasedByContentSizeCategoryDelta { 113 | //Arrange 114 | NSAttributedString *attributedString = [SSAttributedStringValidator testAttributedString]; 115 | 116 | NSArray *dynamicLabels = [self dynamicLabelsWithFontName:SSTestFontName fontSize:SSTestFontSize]; 117 | 118 | [SSTestsHelper startMockingPreferredContentSizeCategory:UIContentSizeCategoryExtraExtraLarge]; 119 | 120 | for (SSDynamicLabel *label in dynamicLabels) { 121 | //Act 122 | label.dynamicAttributedText = attributedString; 123 | 124 | //Assert 125 | XCTAssertTrue([SSAttributedStringValidator isValidTestAttributedString:label.attributedText 126 | changedByDelta:SSTestFontSizeDifferenceForSizeExtraExtraLarge]); 127 | 128 | XCTAssertEqualObjects(label.dynamicAttributedText, attributedString); 129 | } 130 | } 131 | 132 | @end 133 | -------------------------------------------------------------------------------- /Example/SSDynamicTextTests/SSDynamicTextViewTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // SSTextViewTests.m 3 | // SSDynamicTextExample 4 | // 5 | // Created by Remigiusz Herba on 31/08/15. 6 | // Copyright (c) 2015 Splinesoft. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SSTestsHelper.h" 11 | #import "SSAttributedStringValidator.h" 12 | 13 | #import "SSDynamicTextView.h" 14 | #import "SSDynamicsView.h" 15 | 16 | @interface SSDynamicTextViewTests : XCTestCase 17 | @end 18 | 19 | @implementation SSDynamicTextViewTests 20 | 21 | - (void)setUp { 22 | [super setUp]; 23 | 24 | //Default content size category 25 | [SSTestsHelper startMockingPreferredContentSizeCategory:UIContentSizeCategoryLarge]; 26 | } 27 | 28 | - (void)tearDown { 29 | [SSTestsHelper stopMockingPreferredContentSizeCategory]; 30 | [super tearDown]; 31 | } 32 | 33 | - (NSArray *)dynamicTextViewsWithFontName:(NSString *)fontName fontSize:(CGFloat)fontSize { 34 | 35 | UIFontDescriptor *fontDescriptor = [UIFontDescriptor fontDescriptorWithName:fontName size:fontSize]; 36 | 37 | SSDynamicTextView *dynamicTextView = [[SSDynamicTextView alloc] init]; 38 | dynamicTextView.defaultFontDescriptor = fontDescriptor; 39 | 40 | SSDynamicTextView *dynamicTextViewWithFrame = [[SSDynamicTextView alloc] initWithFrame:CGRectZero]; 41 | dynamicTextViewWithFrame.font = [UIFont fontWithName:fontName size:fontSize]; 42 | 43 | SSDynamicTextView *dynamicTextViewWithFont = [SSDynamicTextView textViewWithFont:fontName baseSize:fontSize]; 44 | 45 | SSDynamicTextView *dynamicTextViewWithFontDescriptor = [SSDynamicTextView textViewWithFontDescriptor:fontDescriptor]; 46 | 47 | SSDynamicsView *view = [[NSBundle mainBundle] loadNibNamed:@"SSDynamicsView" owner:nil options:nil].firstObject; 48 | SSDynamicTextView *dynamicTextViewFromXib = view.textView; 49 | 50 | return @[ dynamicTextView, dynamicTextViewWithFrame, dynamicTextViewWithFont, dynamicTextViewWithFontDescriptor, dynamicTextViewFromXib ]; 51 | } 52 | 53 | - (void)testTextViewFontNameShouldBeEqualToFontNameFromConstructor { 54 | //Arrange 55 | NSString *expectedFontName = SSTestFontName; 56 | 57 | //Act 58 | NSArray *dynamicTextViews = [self dynamicTextViewsWithFontName:SSTestFontName fontSize:SSTestFontSize]; 59 | 60 | for (SSDynamicTextView *textView in dynamicTextViews) { 61 | //Assert 62 | XCTAssertEqualObjects(textView.font.fontName, expectedFontName); 63 | } 64 | } 65 | 66 | - (void)testTextViewFontSizeShouldBeEqualToFontSizeInConstructorForDefaultPreferredContentSizeCategory { 67 | //Arrange 68 | CGFloat expectedFontSize = SSTestFontSize; 69 | 70 | //Act 71 | NSArray *dynamicTextViews = [self dynamicTextViewsWithFontName:SSTestFontName fontSize:SSTestFontSize]; 72 | 73 | for (SSDynamicTextView *textView in dynamicTextViews) { 74 | //Assert 75 | XCTAssertEqualWithAccuracy(textView.font.pointSize, expectedFontSize, FLT_EPSILON); 76 | } 77 | } 78 | 79 | - (void)testTextViewFontSizeShouldBeEqualToLabelFontSizeIncreasedByPreferredContentSizeCategoryDelta { 80 | // Arrange 81 | [SSTestsHelper startMockingPreferredContentSizeCategory:UIContentSizeCategoryExtraExtraLarge]; 82 | 83 | CGFloat initialFontSize = SSTestFontSize; 84 | 85 | //Act 86 | NSArray *dynamicTextViews = [self dynamicTextViewsWithFontName:SSTestFontName fontSize:initialFontSize]; 87 | 88 | for (SSDynamicTextView *textView in dynamicTextViews) { 89 | 90 | //Assert 91 | XCTAssertEqualWithAccuracy(textView.font.pointSize, initialFontSize + SSTestFontSizeDifferenceForSizeExtraExtraLarge, FLT_EPSILON); 92 | } 93 | } 94 | 95 | - (void)testTextViewFontSizeShouldBeEqualToNewFontSizeIncreasedByContentSizeCategoryDelta { 96 | //Arrange 97 | CGFloat newFontSize = 7.0f; 98 | UIFont *newFont = [UIFont systemFontOfSize:newFontSize]; 99 | 100 | NSArray *dynamicTextViews = [self dynamicTextViewsWithFontName:SSTestFontName fontSize:SSTestFontSize]; 101 | 102 | [SSTestsHelper startMockingPreferredContentSizeCategory:UIContentSizeCategoryExtraExtraLarge]; 103 | 104 | for (SSDynamicTextView *textView in dynamicTextViews) { 105 | //Act 106 | textView.font = newFont; 107 | 108 | //Assert 109 | XCTAssertEqualWithAccuracy(textView.font.pointSize, newFontSize + SSTestFontSizeDifferenceForSizeExtraExtraLarge, FLT_EPSILON); 110 | } 111 | } 112 | 113 | - (void)testTextViewAttributedStringFontSizesShouldBeIncreasedByContentSizeCategoryDelta { 114 | //Arrange 115 | NSAttributedString *attributedString = [SSAttributedStringValidator testAttributedString]; 116 | 117 | NSArray *dynamicTextViews = [self dynamicTextViewsWithFontName:SSTestFontName fontSize:SSTestFontSize]; 118 | 119 | [SSTestsHelper startMockingPreferredContentSizeCategory:UIContentSizeCategoryExtraExtraLarge]; 120 | 121 | for (SSDynamicTextView *textView in dynamicTextViews) { 122 | //Act 123 | textView.dynamicAttributedText = attributedString; 124 | 125 | //Assert 126 | XCTAssertTrue([SSAttributedStringValidator isValidTestAttributedString:textView.attributedText 127 | changedByDelta:SSTestFontSizeDifferenceForSizeExtraExtraLarge]); 128 | 129 | XCTAssertEqualObjects(textView.dynamicAttributedText, attributedString); 130 | } 131 | } 132 | 133 | @end 134 | -------------------------------------------------------------------------------- /Example/SSDynamicTextTests/SSDynamicTextFieldTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // SSDynamicTextFieldTests.m 3 | // SSDynamicTextExample 4 | // 5 | // Created by Remigiusz Herba on 31/08/15. 6 | // Copyright (c) 2015 Splinesoft. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SSTestsHelper.h" 11 | #import "SSAttributedStringValidator.h" 12 | 13 | #import "SSDynamicTextField.h" 14 | #import "SSDynamicsView.h" 15 | 16 | @interface SSDynamicTextFieldTests : XCTestCase 17 | @end 18 | 19 | @implementation SSDynamicTextFieldTests 20 | 21 | - (void)setUp { 22 | [super setUp]; 23 | 24 | //Default content size category 25 | [SSTestsHelper startMockingPreferredContentSizeCategory:UIContentSizeCategoryLarge]; 26 | } 27 | 28 | - (void)tearDown { 29 | [SSTestsHelper stopMockingPreferredContentSizeCategory]; 30 | [super tearDown]; 31 | } 32 | 33 | - (NSArray *)dynamicTextFieldsWithFontName:(NSString *)fontName fontSize:(CGFloat)fontSize { 34 | UIFontDescriptor *fontDescriptor = [UIFontDescriptor fontDescriptorWithName:fontName size:fontSize]; 35 | 36 | SSDynamicTextField *dynamicTextField = [[SSDynamicTextField alloc] init]; 37 | dynamicTextField.defaultFontDescriptor = fontDescriptor; 38 | 39 | SSDynamicTextField *dynamicTextFieldWithFrame = [[SSDynamicTextField alloc] initWithFrame:CGRectZero]; 40 | dynamicTextFieldWithFrame.font = [UIFont fontWithName:fontName size:fontSize]; 41 | 42 | SSDynamicTextField *dynamicTextFieldWithFont = [SSDynamicTextField textFieldWithFont:fontName baseSize:fontSize]; 43 | 44 | SSDynamicTextField *dynamicTextFieldWithFontDescriptor = [SSDynamicTextField textFieldWithFontDescriptor:fontDescriptor]; 45 | 46 | SSDynamicsView *view = [[NSBundle mainBundle] loadNibNamed:@"SSDynamicsView" owner:nil options:nil].firstObject; 47 | SSDynamicTextField *dynamicTextFieldFromXib = view.textField; 48 | 49 | return @[ dynamicTextField, dynamicTextFieldWithFrame, dynamicTextFieldWithFont, dynamicTextFieldWithFontDescriptor, dynamicTextFieldFromXib ]; 50 | } 51 | 52 | - (void)testTextFieldFontNameShouldBeEqualToFontNameFromConstructor { 53 | //Arrange 54 | NSString *expectedFontName = SSTestFontName; 55 | 56 | //Act 57 | NSArray *dynamicTextFields = [self dynamicTextFieldsWithFontName:SSTestFontName fontSize:SSTestFontSize]; 58 | 59 | for (SSDynamicTextField *textField in dynamicTextFields) { 60 | //Assert 61 | XCTAssertEqualObjects(textField.font.fontName, expectedFontName); 62 | } 63 | } 64 | 65 | - (void)testTextFieldFontSizeShouldBeEqualToFontSizeInConstructorForDefaultPreferredContentSizeCategory { 66 | //Arrange 67 | CGFloat expectedFontSize = SSTestFontSize; 68 | 69 | //Act 70 | NSArray *dynamicTextFields = [self dynamicTextFieldsWithFontName:SSTestFontName fontSize:SSTestFontSize]; 71 | 72 | for (SSDynamicTextField *textField in dynamicTextFields) { 73 | //Assert 74 | XCTAssertEqualWithAccuracy(textField.font.pointSize, expectedFontSize, FLT_EPSILON); 75 | } 76 | } 77 | 78 | - (void)testTextFieldFontSizeShouldBeEqualToLabelFontSizeIncreasedByPreferredContentSizeCategoryDelta { 79 | // Arrange 80 | [SSTestsHelper startMockingPreferredContentSizeCategory:UIContentSizeCategoryExtraExtraLarge]; 81 | 82 | CGFloat initialFontSize = SSTestFontSize; 83 | 84 | //Act 85 | NSArray *dynamicTextFields = [self dynamicTextFieldsWithFontName:SSTestFontName fontSize:initialFontSize]; 86 | 87 | for (SSDynamicTextField *textField in dynamicTextFields) { 88 | 89 | //Assert 90 | XCTAssertEqualWithAccuracy(textField.font.pointSize, initialFontSize + SSTestFontSizeDifferenceForSizeExtraExtraLarge, FLT_EPSILON); 91 | } 92 | } 93 | 94 | - (void)testLabelFontSizeShouldBeEqualToNewFontSizeIncreasedByContentSizeCategoryDelta { 95 | //Arrange 96 | CGFloat newFontSize = 7.0f; 97 | UIFont *newFont = [UIFont systemFontOfSize:newFontSize]; 98 | 99 | NSArray *dynamicTextField = [self dynamicTextFieldsWithFontName:SSTestFontName fontSize:SSTestFontSize]; 100 | 101 | [SSTestsHelper startMockingPreferredContentSizeCategory:UIContentSizeCategoryExtraExtraLarge]; 102 | 103 | for (SSDynamicTextField *textField in dynamicTextField) { 104 | //Act 105 | textField.font = newFont; 106 | 107 | //Assert 108 | XCTAssertEqualWithAccuracy(textField.font.pointSize, newFontSize + SSTestFontSizeDifferenceForSizeExtraExtraLarge, FLT_EPSILON); 109 | } 110 | } 111 | 112 | - (void)testTextFieldAttributedStringFontSizesShouldBeIncreasedByContentSizeCategoryDelta { 113 | //Arrange 114 | NSAttributedString *attributedString = [SSAttributedStringValidator testAttributedString]; 115 | 116 | NSArray *dynamicTextFields = [self dynamicTextFieldsWithFontName:SSTestFontName fontSize:SSTestFontSize]; 117 | 118 | [SSTestsHelper startMockingPreferredContentSizeCategory:UIContentSizeCategoryExtraExtraLarge]; 119 | 120 | for (SSDynamicTextField *textField in dynamicTextFields) { 121 | //Act 122 | textField.dynamicAttributedText = attributedString; 123 | 124 | //Assert 125 | XCTAssertTrue([SSAttributedStringValidator isValidTestAttributedString:textField.attributedText 126 | changedByDelta:SSTestFontSizeDifferenceForSizeExtraExtraLarge]); 127 | 128 | XCTAssertEqualObjects(textField.dynamicAttributedText, attributedString); 129 | } 130 | } 131 | 132 | @end 133 | -------------------------------------------------------------------------------- /Example/SSDynamicTextTests/SSDynamicButtonTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // SSDynamicButtonTests.m 3 | // SSDynamicTextExample 4 | // 5 | // Created by Remigiusz Herba on 31/08/15. 6 | // Copyright (c) 2015 Splinesoft. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SSTestsHelper.h" 11 | #import "SSAttributedStringValidator.h" 12 | 13 | #import "SSDynamicButton.h" 14 | #import "SSDynamicsView.h" 15 | 16 | @interface SSDynamicButtonTests : XCTestCase 17 | @end 18 | 19 | @implementation SSDynamicButtonTests 20 | 21 | - (void)setUp { 22 | [super setUp]; 23 | 24 | //Default content size category 25 | [SSTestsHelper startMockingPreferredContentSizeCategory:UIContentSizeCategoryLarge]; 26 | } 27 | 28 | - (void)tearDown { 29 | [SSTestsHelper stopMockingPreferredContentSizeCategory]; 30 | [super tearDown]; 31 | } 32 | 33 | - (NSArray *)dynamicButtonsWithFontName:(NSString *)fontName fontSize:(CGFloat)fontSize { 34 | UIFontDescriptor *fontDescriptor = [UIFontDescriptor fontDescriptorWithName:fontName size:fontSize]; 35 | 36 | SSDynamicButton *dynamicButton = [[SSDynamicButton alloc] init]; 37 | dynamicButton.defaultFontDescriptor = fontDescriptor; 38 | 39 | SSDynamicButton *dynamicButtonWithFrame = [[SSDynamicButton alloc] initWithFrame:CGRectZero]; 40 | dynamicButtonWithFrame.titleLabel.font = [UIFont fontWithName:fontName size:fontSize]; 41 | 42 | SSDynamicButton *dynamicButtonWithFont = [SSDynamicButton buttonWithFont:fontName baseSize:fontSize]; 43 | 44 | SSDynamicButton *dynamicButtonWithFontDescriptor = [SSDynamicButton buttonWithFontDescriptor:fontDescriptor]; 45 | 46 | SSDynamicsView *view = [[NSBundle mainBundle] loadNibNamed:@"SSDynamicsView" owner:nil options:nil].firstObject; 47 | SSDynamicButton *dynamicButtonFromXib = view.button; 48 | 49 | return @[ dynamicButton, dynamicButtonWithFrame, dynamicButtonWithFont, dynamicButtonWithFontDescriptor, dynamicButtonFromXib ]; 50 | } 51 | 52 | - (void)testButtonTitleLabelFontNameShouldBeEqualToFontNameFromConstructor { 53 | //Arrange 54 | NSString *expectedFontName = SSTestFontName; 55 | 56 | //Act 57 | NSArray *dynamicButtons = [self dynamicButtonsWithFontName:SSTestFontName fontSize:SSTestFontSize]; 58 | 59 | for (SSDynamicButton *button in dynamicButtons) { 60 | //Assert 61 | XCTAssertEqualObjects(button.titleLabel.font.fontName, expectedFontName); 62 | } 63 | } 64 | 65 | - (void)testButtonTitleLabelFontSizeShouldBeEqualToFontSizeInConstructorForDefaultPreferredContentSizeCategory { 66 | //Arrange 67 | CGFloat expectedFontSize = SSTestFontSize; 68 | 69 | //Act 70 | NSArray *dynamicButtons = [self dynamicButtonsWithFontName:SSTestFontName fontSize:SSTestFontSize]; 71 | 72 | for (SSDynamicButton *button in dynamicButtons) { 73 | //Assert 74 | XCTAssertEqualWithAccuracy(button.titleLabel.font.pointSize, expectedFontSize, FLT_EPSILON); 75 | } 76 | } 77 | 78 | - (void)testButtonTitleLabelFontSizeShouldBeEqualToLabelFontSizeIncreasedByPreferredContentSizeCategoryDelta { 79 | // Arrange 80 | [SSTestsHelper startMockingPreferredContentSizeCategory:UIContentSizeCategoryExtraExtraLarge]; 81 | 82 | CGFloat initialFontSize = SSTestFontSize; 83 | 84 | //Act 85 | NSArray *dynamicButtons = [self dynamicButtonsWithFontName:SSTestFontName fontSize:initialFontSize]; 86 | 87 | for (SSDynamicButton *button in dynamicButtons) { 88 | 89 | //Assert 90 | XCTAssertEqualWithAccuracy(button.titleLabel.font.pointSize, initialFontSize + SSTestFontSizeDifferenceForSizeExtraExtraLarge, FLT_EPSILON); 91 | } 92 | } 93 | 94 | - (void)testButtonTitleLabelFontSizeShouldBeEqualToNewFontSizeIncreasedByContentSizeCategoryDelta { 95 | //Arrange 96 | CGFloat newFontSize = 7.0f; 97 | UIFont *newFont = [UIFont systemFontOfSize:newFontSize]; 98 | 99 | NSArray *dynamicButtons = [self dynamicButtonsWithFontName:SSTestFontName fontSize:SSTestFontSize]; 100 | 101 | [SSTestsHelper startMockingPreferredContentSizeCategory:UIContentSizeCategoryExtraExtraLarge]; 102 | 103 | for (SSDynamicButton *button in dynamicButtons) { 104 | //Act 105 | button.titleLabel.font = newFont; 106 | 107 | //Assert 108 | XCTAssertEqualWithAccuracy(button.titleLabel.font.pointSize, newFontSize + SSTestFontSizeDifferenceForSizeExtraExtraLarge, FLT_EPSILON); 109 | } 110 | } 111 | 112 | - (void)testButtonTitleLabelAttributedTitleFontSizesShouldBeIncreasedByContentSizeCategoryDeltaAfterSetAttributedTitle { 113 | //Arrange 114 | NSAttributedString *attributedString = [SSAttributedStringValidator testAttributedString]; 115 | 116 | NSArray *dynamicButtons = [self dynamicButtonsWithFontName:SSTestFontName fontSize:SSTestFontSize]; 117 | 118 | [SSTestsHelper startMockingPreferredContentSizeCategory:UIContentSizeCategoryExtraExtraLarge]; 119 | 120 | for (SSDynamicButton *button in dynamicButtons) { 121 | //Act 122 | [button setAttributedTitle:attributedString forState:UIControlStateNormal]; 123 | 124 | //Assert 125 | XCTAssertTrue([SSAttributedStringValidator isValidTestAttributedString:[button attributedTitleForState:UIControlStateNormal] 126 | changedByDelta:SSTestFontSizeDifferenceForSizeExtraExtraLarge]); 127 | } 128 | } 129 | 130 | - (void)testButtonTitleLabelAttributedTitleFontSizesShouldBeIncreasedByContentSizeCategoryDeltaAfterPostContentSizeChangeNotification { 131 | //Arrange 132 | NSAttributedString *attributedString = [SSAttributedStringValidator testAttributedString]; 133 | 134 | NSArray *dynamicButtons = [self dynamicButtonsWithFontName:SSTestFontName fontSize:SSTestFontSize]; 135 | 136 | for (SSDynamicButton *button in dynamicButtons) { 137 | [button setAttributedTitle:attributedString forState:UIControlStateNormal]; 138 | } 139 | 140 | [SSTestsHelper startMockingPreferredContentSizeCategory:UIContentSizeCategoryExtraExtraLarge]; 141 | //Act 142 | [SSTestsHelper postContentSizeChangeNotification]; 143 | 144 | for (SSDynamicButton *button in dynamicButtons) { 145 | //Assert 146 | XCTAssertTrue([SSAttributedStringValidator isValidTestAttributedString:[button attributedTitleForState:UIControlStateNormal] 147 | changedByDelta:SSTestFontSizeDifferenceForSizeExtraExtraLarge]); 148 | } 149 | } 150 | 151 | @end 152 | -------------------------------------------------------------------------------- /Example/SSDynamicTextExample/SSViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SSViewController.m 3 | // SSLabelExample 4 | // 5 | // Created by Jonathan Hersh on 10/4/13. 6 | // Copyright (c) 2013 Splinesoft. All rights reserved. 7 | // 8 | 9 | #import "SSViewController.h" 10 | #import 11 | 12 | static NSString * const kLabelText = @"This label, text field, and text view all support custom fonts and respond to changes in preferred text size.\n\nSwitch to Settings.app, change your preferred text size, then switch back here."; 13 | 14 | @interface SSViewController () 15 | 16 | @property (nonatomic, strong) SSDynamicLabel *label; 17 | @property (nonatomic, strong) SSDynamicButton *button; 18 | @property (nonatomic, strong) SSDynamicTextField *textField; 19 | @property (nonatomic, strong) SSDynamicTextView *textView; 20 | @property (nonatomic, assign) BOOL isAttributedTextCurrentlyDisplayed; 21 | 22 | @end 23 | 24 | @implementation SSViewController 25 | 26 | - (void)changeTexts:(UIButton *)sender { 27 | if (self.isAttributedTextCurrentlyDisplayed) { 28 | [self displayNormalTexts]; 29 | } else { 30 | [self displayAttributedTexts]; 31 | } 32 | self.isAttributedTextCurrentlyDisplayed = !self.isAttributedTextCurrentlyDisplayed; 33 | } 34 | 35 | - (void)displayNormalTexts { 36 | self.label.dynamicAttributedText = nil; 37 | self.textField.dynamicAttributedText = nil; 38 | self.textView.dynamicAttributedText = nil; 39 | [self.button setAttributedTitle:nil forState:UIControlStateNormal]; 40 | 41 | self.label.text = kLabelText; 42 | self.textView.text = @"Text View"; 43 | [self.button setTitle:@"Change to attributed" forState:UIControlStateNormal]; 44 | } 45 | 46 | - (void)setLabelAttributedTextWithFirstAttributes:(NSDictionary *)attributes secondAttributes:(NSDictionary *)secondAttributes { 47 | NSMutableAttributedString *labelText = [[NSMutableAttributedString alloc] initWithString:kLabelText 48 | attributes:attributes]; 49 | [labelText addAttributes:secondAttributes range:[kLabelText rangeOfString:@"change your preferred text size"]]; 50 | 51 | self.label.dynamicAttributedText = labelText; 52 | } 53 | 54 | - (void)setTextFieldAttributedTextWithFirstAttributes:(NSDictionary *)attributes secondAttributes:(NSDictionary *)secondAttributes { 55 | NSString *textFieldString = @"TextField support"; 56 | NSMutableAttributedString *textFieldText = [[NSMutableAttributedString alloc] initWithString:textFieldString 57 | attributes:attributes]; 58 | [textFieldText addAttributes:secondAttributes range:[textFieldString rangeOfString:@"TextField"]]; 59 | self.textField.dynamicAttributedText = textFieldText; 60 | } 61 | 62 | - (void)setTextViewAttributedTextWithFirstAttributes:(NSDictionary *)attributes secondAttributes:(NSDictionary *)secondAttributes { 63 | NSString *textViewString = @"I hope this also works for TextView"; 64 | NSMutableAttributedString *textViewText = [[NSMutableAttributedString alloc] initWithString:textViewString 65 | attributes:attributes]; 66 | [textViewText addAttributes:secondAttributes range:[textViewString rangeOfString:@"works for TextView"]]; 67 | self.textView.dynamicAttributedText = textViewText; 68 | } 69 | 70 | - (void)setButtonAttributedTextWithFirstAttributes:(NSDictionary *)attributes secondAttributes:(NSDictionary *)secondAttributes { 71 | NSString *buttonString = @"Change to normal"; 72 | NSMutableAttributedString *buttonText = [[NSMutableAttributedString alloc] initWithString:buttonString 73 | attributes:attributes]; 74 | [buttonText addAttributes:secondAttributes range:[buttonString rangeOfString:@"normal"]]; 75 | [self.button setAttributedTitle:buttonText forState:UIControlStateNormal]; 76 | } 77 | 78 | - (void)displayAttributedTexts { 79 | self.label.text = nil; 80 | self.textField.text = nil; 81 | self.textView.text = nil; 82 | 83 | NSDictionary *attributes = 84 | @{NSForegroundColorAttributeName: [UIColor blackColor], NSFontAttributeName: [UIFont systemFontOfSize:16.0f]}; 85 | 86 | NSDictionary *secondAttributes = 87 | @{NSForegroundColorAttributeName: [UIColor blueColor], NSFontAttributeName: [UIFont fontWithName:@"Courier" size:25.0f]}; 88 | 89 | [self setLabelAttributedTextWithFirstAttributes:attributes secondAttributes:secondAttributes]; 90 | [self setTextFieldAttributedTextWithFirstAttributes:attributes secondAttributes:secondAttributes]; 91 | [self setTextViewAttributedTextWithFirstAttributes:attributes secondAttributes:secondAttributes]; 92 | [self setButtonAttributedTextWithFirstAttributes:attributes secondAttributes:secondAttributes]; 93 | } 94 | 95 | - (void)viewDidLoad { 96 | [super viewDidLoad]; 97 | 98 | self.view.backgroundColor = [UIColor whiteColor]; 99 | 100 | self.label = [SSDynamicLabel labelWithFont:@"Courier" baseSize:16.0f]; 101 | self.label.textColor = [UIColor darkGrayColor]; 102 | self.label.numberOfLines = 0; 103 | self.label.textAlignment = NSTextAlignmentCenter; 104 | [self.label setFrame:(CGRect){ 105 | {10, 25}, 106 | {CGRectGetWidth(self.view.frame) - 20, 220} 107 | }]; 108 | 109 | [self.view addSubview:self.label]; 110 | 111 | self.button = [SSDynamicButton buttonWithFont:@"Courier" baseSize:16.0f]; 112 | [self.button setTitleColor:[UIColor blueColor] forState:UIControlStateNormal]; 113 | self.button.backgroundColor = [UIColor lightGrayColor]; 114 | [self.button setFrame:(CGRect){ 115 | {10, CGRectGetMaxY(self.label.frame) + 10}, 116 | {CGRectGetWidth(self.view.frame) - 20, 44} 117 | }]; 118 | [self.button addTarget:self action:@selector(changeTexts:) forControlEvents:UIControlEventTouchUpInside]; 119 | 120 | [self.view addSubview:self.button]; 121 | 122 | self.textField = [SSDynamicTextField textFieldWithFont:@"Courier" 123 | baseSize:15.0f]; 124 | self.textField.textColor = [UIColor darkGrayColor]; 125 | self.textField.backgroundColor = [UIColor lightGrayColor]; 126 | self.textField.placeholder = @"Text Field"; 127 | [self.textField setFrame:(CGRect){ 128 | {10, CGRectGetMaxY(self.button.frame) + 10}, 129 | {CGRectGetWidth(self.view.frame) - 20, 32} 130 | }]; 131 | 132 | [self.view addSubview:self.textField]; 133 | 134 | self.textView = [SSDynamicTextView textViewWithFont:@"Courier" 135 | baseSize:15.0f]; 136 | self.textView.textColor = [UIColor redColor]; 137 | self.textView.backgroundColor = [UIColor lightGrayColor]; 138 | [self.textView setFrame:(CGRect){ 139 | {10, CGRectGetMaxY(self.textField.frame) + 10}, 140 | {CGRectGetWidth(self.view.frame) - 20, 100} 141 | }]; 142 | 143 | [self.view addSubview:self.textView]; 144 | 145 | [self displayNormalTexts]; 146 | } 147 | 148 | @end 149 | -------------------------------------------------------------------------------- /Example/SSDynamicTextExample/SSDynamicsView.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Nam liber te conscient to factor tum poen legum odioque civiuda. 38 | 39 | 40 | 41 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /SSDynamicText.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 414905791D69BB4D006D86E4 /* SSDynamicText.h in Headers */ = {isa = PBXBuildFile; fileRef = 414905781D69BB4D006D86E4 /* SSDynamicText.h */; settings = {ATTRIBUTES = (Public, ); }; }; 11 | 414905941D69BBA6006D86E4 /* NSAttributedString+SSTextSize.h in Headers */ = {isa = PBXBuildFile; fileRef = 414905801D69BBA6006D86E4 /* NSAttributedString+SSTextSize.h */; }; 12 | 414905951D69BBA6006D86E4 /* NSAttributedString+SSTextSize.m in Sources */ = {isa = PBXBuildFile; fileRef = 414905811D69BBA6006D86E4 /* NSAttributedString+SSTextSize.m */; }; 13 | 414905961D69BBA6006D86E4 /* SSDynamicAttributedTextSizable.h in Headers */ = {isa = PBXBuildFile; fileRef = 414905821D69BBA6006D86E4 /* SSDynamicAttributedTextSizable.h */; }; 14 | 414905971D69BBA6006D86E4 /* SSDynamicButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 414905831D69BBA6006D86E4 /* SSDynamicButton.h */; }; 15 | 414905981D69BBA6006D86E4 /* SSDynamicButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 414905841D69BBA6006D86E4 /* SSDynamicButton.m */; }; 16 | 414905991D69BBA6006D86E4 /* SSDynamicLabel.h in Headers */ = {isa = PBXBuildFile; fileRef = 414905851D69BBA6006D86E4 /* SSDynamicLabel.h */; }; 17 | 4149059A1D69BBA6006D86E4 /* SSDynamicLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = 414905861D69BBA6006D86E4 /* SSDynamicLabel.m */; }; 18 | 4149059C1D69BBA6006D86E4 /* SSDynamicTextField.h in Headers */ = {isa = PBXBuildFile; fileRef = 414905881D69BBA6006D86E4 /* SSDynamicTextField.h */; }; 19 | 4149059D1D69BBA6006D86E4 /* SSDynamicTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 414905891D69BBA6006D86E4 /* SSDynamicTextField.m */; }; 20 | 4149059E1D69BBA6006D86E4 /* SSDynamicTextSizeChanger.h in Headers */ = {isa = PBXBuildFile; fileRef = 4149058A1D69BBA6006D86E4 /* SSDynamicTextSizeChanger.h */; }; 21 | 4149059F1D69BBA6006D86E4 /* SSDynamicTextSizeChanger.m in Sources */ = {isa = PBXBuildFile; fileRef = 4149058B1D69BBA6006D86E4 /* SSDynamicTextSizeChanger.m */; }; 22 | 414905A01D69BBA6006D86E4 /* SSDynamicTextView.h in Headers */ = {isa = PBXBuildFile; fileRef = 4149058C1D69BBA6006D86E4 /* SSDynamicTextView.h */; }; 23 | 414905A11D69BBA6006D86E4 /* SSDynamicTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4149058D1D69BBA6006D86E4 /* SSDynamicTextView.m */; }; 24 | 414905A21D69BBA6006D86E4 /* UIApplication+SSTextSize.h in Headers */ = {isa = PBXBuildFile; fileRef = 4149058E1D69BBA6006D86E4 /* UIApplication+SSTextSize.h */; }; 25 | 414905A31D69BBA6006D86E4 /* UIApplication+SSTextSize.m in Sources */ = {isa = PBXBuildFile; fileRef = 4149058F1D69BBA6006D86E4 /* UIApplication+SSTextSize.m */; }; 26 | 414905A41D69BBA6006D86E4 /* UIFont+SSTextSize.h in Headers */ = {isa = PBXBuildFile; fileRef = 414905901D69BBA6006D86E4 /* UIFont+SSTextSize.h */; }; 27 | 414905A51D69BBA6006D86E4 /* UIFont+SSTextSize.m in Sources */ = {isa = PBXBuildFile; fileRef = 414905911D69BBA6006D86E4 /* UIFont+SSTextSize.m */; }; 28 | 414905A61D69BBA6006D86E4 /* UIView+SSTextSize.h in Headers */ = {isa = PBXBuildFile; fileRef = 414905921D69BBA6006D86E4 /* UIView+SSTextSize.h */; }; 29 | 414905A71D69BBA6006D86E4 /* UIView+SSTextSize.m in Sources */ = {isa = PBXBuildFile; fileRef = 414905931D69BBA6006D86E4 /* UIView+SSTextSize.m */; }; 30 | /* End PBXBuildFile section */ 31 | 32 | /* Begin PBXFileReference section */ 33 | 414905751D69BB4D006D86E4 /* SSDynamicText.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SSDynamicText.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 34 | 414905781D69BB4D006D86E4 /* SSDynamicText.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SSDynamicText.h; sourceTree = ""; }; 35 | 4149057A1D69BB4D006D86E4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 36 | 414905801D69BBA6006D86E4 /* NSAttributedString+SSTextSize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSAttributedString+SSTextSize.h"; sourceTree = ""; }; 37 | 414905811D69BBA6006D86E4 /* NSAttributedString+SSTextSize.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSAttributedString+SSTextSize.m"; sourceTree = ""; }; 38 | 414905821D69BBA6006D86E4 /* SSDynamicAttributedTextSizable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SSDynamicAttributedTextSizable.h; sourceTree = ""; }; 39 | 414905831D69BBA6006D86E4 /* SSDynamicButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SSDynamicButton.h; sourceTree = ""; }; 40 | 414905841D69BBA6006D86E4 /* SSDynamicButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SSDynamicButton.m; sourceTree = ""; }; 41 | 414905851D69BBA6006D86E4 /* SSDynamicLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SSDynamicLabel.h; sourceTree = ""; }; 42 | 414905861D69BBA6006D86E4 /* SSDynamicLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SSDynamicLabel.m; sourceTree = ""; }; 43 | 414905881D69BBA6006D86E4 /* SSDynamicTextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SSDynamicTextField.h; sourceTree = ""; }; 44 | 414905891D69BBA6006D86E4 /* SSDynamicTextField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SSDynamicTextField.m; sourceTree = ""; }; 45 | 4149058A1D69BBA6006D86E4 /* SSDynamicTextSizeChanger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SSDynamicTextSizeChanger.h; sourceTree = ""; }; 46 | 4149058B1D69BBA6006D86E4 /* SSDynamicTextSizeChanger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SSDynamicTextSizeChanger.m; sourceTree = ""; }; 47 | 4149058C1D69BBA6006D86E4 /* SSDynamicTextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SSDynamicTextView.h; sourceTree = ""; }; 48 | 4149058D1D69BBA6006D86E4 /* SSDynamicTextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SSDynamicTextView.m; sourceTree = ""; }; 49 | 4149058E1D69BBA6006D86E4 /* UIApplication+SSTextSize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIApplication+SSTextSize.h"; sourceTree = ""; }; 50 | 4149058F1D69BBA6006D86E4 /* UIApplication+SSTextSize.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIApplication+SSTextSize.m"; sourceTree = ""; }; 51 | 414905901D69BBA6006D86E4 /* UIFont+SSTextSize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIFont+SSTextSize.h"; sourceTree = ""; }; 52 | 414905911D69BBA6006D86E4 /* UIFont+SSTextSize.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIFont+SSTextSize.m"; sourceTree = ""; }; 53 | 414905921D69BBA6006D86E4 /* UIView+SSTextSize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+SSTextSize.h"; sourceTree = ""; }; 54 | 414905931D69BBA6006D86E4 /* UIView+SSTextSize.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+SSTextSize.m"; sourceTree = ""; }; 55 | /* End PBXFileReference section */ 56 | 57 | /* Begin PBXFrameworksBuildPhase section */ 58 | 414905711D69BB4D006D86E4 /* Frameworks */ = { 59 | isa = PBXFrameworksBuildPhase; 60 | buildActionMask = 2147483647; 61 | files = ( 62 | ); 63 | runOnlyForDeploymentPostprocessing = 0; 64 | }; 65 | /* End PBXFrameworksBuildPhase section */ 66 | 67 | /* Begin PBXGroup section */ 68 | 4149056B1D69BB4D006D86E4 = { 69 | isa = PBXGroup; 70 | children = ( 71 | 414905771D69BB4D006D86E4 /* SSDynamicText */, 72 | 414905761D69BB4D006D86E4 /* Products */, 73 | ); 74 | sourceTree = ""; 75 | }; 76 | 414905761D69BB4D006D86E4 /* Products */ = { 77 | isa = PBXGroup; 78 | children = ( 79 | 414905751D69BB4D006D86E4 /* SSDynamicText.framework */, 80 | ); 81 | name = Products; 82 | sourceTree = ""; 83 | }; 84 | 414905771D69BB4D006D86E4 /* SSDynamicText */ = { 85 | isa = PBXGroup; 86 | children = ( 87 | 414905801D69BBA6006D86E4 /* NSAttributedString+SSTextSize.h */, 88 | 414905811D69BBA6006D86E4 /* NSAttributedString+SSTextSize.m */, 89 | 414905821D69BBA6006D86E4 /* SSDynamicAttributedTextSizable.h */, 90 | 414905831D69BBA6006D86E4 /* SSDynamicButton.h */, 91 | 414905841D69BBA6006D86E4 /* SSDynamicButton.m */, 92 | 414905851D69BBA6006D86E4 /* SSDynamicLabel.h */, 93 | 414905861D69BBA6006D86E4 /* SSDynamicLabel.m */, 94 | 414905781D69BB4D006D86E4 /* SSDynamicText.h */, 95 | 414905881D69BBA6006D86E4 /* SSDynamicTextField.h */, 96 | 414905891D69BBA6006D86E4 /* SSDynamicTextField.m */, 97 | 4149058A1D69BBA6006D86E4 /* SSDynamicTextSizeChanger.h */, 98 | 4149058B1D69BBA6006D86E4 /* SSDynamicTextSizeChanger.m */, 99 | 4149058C1D69BBA6006D86E4 /* SSDynamicTextView.h */, 100 | 4149058D1D69BBA6006D86E4 /* SSDynamicTextView.m */, 101 | 4149058E1D69BBA6006D86E4 /* UIApplication+SSTextSize.h */, 102 | 4149058F1D69BBA6006D86E4 /* UIApplication+SSTextSize.m */, 103 | 414905901D69BBA6006D86E4 /* UIFont+SSTextSize.h */, 104 | 414905911D69BBA6006D86E4 /* UIFont+SSTextSize.m */, 105 | 414905921D69BBA6006D86E4 /* UIView+SSTextSize.h */, 106 | 414905931D69BBA6006D86E4 /* UIView+SSTextSize.m */, 107 | 4149057A1D69BB4D006D86E4 /* Info.plist */, 108 | ); 109 | path = SSDynamicText; 110 | sourceTree = ""; 111 | }; 112 | /* End PBXGroup section */ 113 | 114 | /* Begin PBXHeadersBuildPhase section */ 115 | 414905721D69BB4D006D86E4 /* Headers */ = { 116 | isa = PBXHeadersBuildPhase; 117 | buildActionMask = 2147483647; 118 | files = ( 119 | 414905A01D69BBA6006D86E4 /* SSDynamicTextView.h in Headers */, 120 | 414905941D69BBA6006D86E4 /* NSAttributedString+SSTextSize.h in Headers */, 121 | 414905A61D69BBA6006D86E4 /* UIView+SSTextSize.h in Headers */, 122 | 414905A21D69BBA6006D86E4 /* UIApplication+SSTextSize.h in Headers */, 123 | 414905991D69BBA6006D86E4 /* SSDynamicLabel.h in Headers */, 124 | 4149059E1D69BBA6006D86E4 /* SSDynamicTextSizeChanger.h in Headers */, 125 | 4149059C1D69BBA6006D86E4 /* SSDynamicTextField.h in Headers */, 126 | 414905791D69BB4D006D86E4 /* SSDynamicText.h in Headers */, 127 | 414905971D69BBA6006D86E4 /* SSDynamicButton.h in Headers */, 128 | 414905A41D69BBA6006D86E4 /* UIFont+SSTextSize.h in Headers */, 129 | 414905961D69BBA6006D86E4 /* SSDynamicAttributedTextSizable.h in Headers */, 130 | ); 131 | runOnlyForDeploymentPostprocessing = 0; 132 | }; 133 | /* End PBXHeadersBuildPhase section */ 134 | 135 | /* Begin PBXNativeTarget section */ 136 | 414905741D69BB4D006D86E4 /* SSDynamicText */ = { 137 | isa = PBXNativeTarget; 138 | buildConfigurationList = 4149057D1D69BB4D006D86E4 /* Build configuration list for PBXNativeTarget "SSDynamicText" */; 139 | buildPhases = ( 140 | 414905701D69BB4D006D86E4 /* Sources */, 141 | 414905711D69BB4D006D86E4 /* Frameworks */, 142 | 414905721D69BB4D006D86E4 /* Headers */, 143 | 414905731D69BB4D006D86E4 /* Resources */, 144 | ); 145 | buildRules = ( 146 | ); 147 | dependencies = ( 148 | ); 149 | name = SSDynamicText; 150 | productName = SSDynamicText; 151 | productReference = 414905751D69BB4D006D86E4 /* SSDynamicText.framework */; 152 | productType = "com.apple.product-type.framework"; 153 | }; 154 | /* End PBXNativeTarget section */ 155 | 156 | /* Begin PBXProject section */ 157 | 4149056C1D69BB4D006D86E4 /* Project object */ = { 158 | isa = PBXProject; 159 | attributes = { 160 | LastUpgradeCheck = 0730; 161 | ORGANIZATIONNAME = splinesoft; 162 | TargetAttributes = { 163 | 414905741D69BB4D006D86E4 = { 164 | CreatedOnToolsVersion = 7.3.1; 165 | }; 166 | }; 167 | }; 168 | buildConfigurationList = 4149056F1D69BB4D006D86E4 /* Build configuration list for PBXProject "SSDynamicText" */; 169 | compatibilityVersion = "Xcode 3.2"; 170 | developmentRegion = English; 171 | hasScannedForEncodings = 0; 172 | knownRegions = ( 173 | en, 174 | ); 175 | mainGroup = 4149056B1D69BB4D006D86E4; 176 | productRefGroup = 414905761D69BB4D006D86E4 /* Products */; 177 | projectDirPath = ""; 178 | projectRoot = ""; 179 | targets = ( 180 | 414905741D69BB4D006D86E4 /* SSDynamicText */, 181 | ); 182 | }; 183 | /* End PBXProject section */ 184 | 185 | /* Begin PBXResourcesBuildPhase section */ 186 | 414905731D69BB4D006D86E4 /* Resources */ = { 187 | isa = PBXResourcesBuildPhase; 188 | buildActionMask = 2147483647; 189 | files = ( 190 | ); 191 | runOnlyForDeploymentPostprocessing = 0; 192 | }; 193 | /* End PBXResourcesBuildPhase section */ 194 | 195 | /* Begin PBXSourcesBuildPhase section */ 196 | 414905701D69BB4D006D86E4 /* Sources */ = { 197 | isa = PBXSourcesBuildPhase; 198 | buildActionMask = 2147483647; 199 | files = ( 200 | 414905A71D69BBA6006D86E4 /* UIView+SSTextSize.m in Sources */, 201 | 4149059A1D69BBA6006D86E4 /* SSDynamicLabel.m in Sources */, 202 | 414905951D69BBA6006D86E4 /* NSAttributedString+SSTextSize.m in Sources */, 203 | 414905981D69BBA6006D86E4 /* SSDynamicButton.m in Sources */, 204 | 414905A11D69BBA6006D86E4 /* SSDynamicTextView.m in Sources */, 205 | 414905A51D69BBA6006D86E4 /* UIFont+SSTextSize.m in Sources */, 206 | 414905A31D69BBA6006D86E4 /* UIApplication+SSTextSize.m in Sources */, 207 | 4149059D1D69BBA6006D86E4 /* SSDynamicTextField.m in Sources */, 208 | 4149059F1D69BBA6006D86E4 /* SSDynamicTextSizeChanger.m in Sources */, 209 | ); 210 | runOnlyForDeploymentPostprocessing = 0; 211 | }; 212 | /* End PBXSourcesBuildPhase section */ 213 | 214 | /* Begin XCBuildConfiguration section */ 215 | 4149057B1D69BB4D006D86E4 /* Debug */ = { 216 | isa = XCBuildConfiguration; 217 | buildSettings = { 218 | ALWAYS_SEARCH_USER_PATHS = NO; 219 | CLANG_ANALYZER_NONNULL = YES; 220 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 221 | CLANG_CXX_LIBRARY = "libc++"; 222 | CLANG_ENABLE_MODULES = YES; 223 | CLANG_ENABLE_OBJC_ARC = YES; 224 | CLANG_WARN_BOOL_CONVERSION = YES; 225 | CLANG_WARN_CONSTANT_CONVERSION = YES; 226 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 227 | CLANG_WARN_EMPTY_BODY = YES; 228 | CLANG_WARN_ENUM_CONVERSION = YES; 229 | CLANG_WARN_INT_CONVERSION = YES; 230 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 231 | CLANG_WARN_UNREACHABLE_CODE = YES; 232 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 233 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 234 | COPY_PHASE_STRIP = NO; 235 | CURRENT_PROJECT_VERSION = 1; 236 | DEBUG_INFORMATION_FORMAT = dwarf; 237 | ENABLE_STRICT_OBJC_MSGSEND = YES; 238 | ENABLE_TESTABILITY = YES; 239 | GCC_C_LANGUAGE_STANDARD = gnu99; 240 | GCC_DYNAMIC_NO_PIC = NO; 241 | GCC_NO_COMMON_BLOCKS = YES; 242 | GCC_OPTIMIZATION_LEVEL = 0; 243 | GCC_PREPROCESSOR_DEFINITIONS = ( 244 | "DEBUG=1", 245 | "$(inherited)", 246 | ); 247 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 248 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 249 | GCC_WARN_UNDECLARED_SELECTOR = YES; 250 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 251 | GCC_WARN_UNUSED_FUNCTION = YES; 252 | GCC_WARN_UNUSED_VARIABLE = YES; 253 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 254 | MTL_ENABLE_DEBUG_INFO = YES; 255 | ONLY_ACTIVE_ARCH = YES; 256 | SDKROOT = iphoneos; 257 | TARGETED_DEVICE_FAMILY = "1,2"; 258 | VERSIONING_SYSTEM = "apple-generic"; 259 | VERSION_INFO_PREFIX = ""; 260 | }; 261 | name = Debug; 262 | }; 263 | 4149057C1D69BB4D006D86E4 /* Release */ = { 264 | isa = XCBuildConfiguration; 265 | buildSettings = { 266 | ALWAYS_SEARCH_USER_PATHS = NO; 267 | CLANG_ANALYZER_NONNULL = YES; 268 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 269 | CLANG_CXX_LIBRARY = "libc++"; 270 | CLANG_ENABLE_MODULES = YES; 271 | CLANG_ENABLE_OBJC_ARC = YES; 272 | CLANG_WARN_BOOL_CONVERSION = YES; 273 | CLANG_WARN_CONSTANT_CONVERSION = YES; 274 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 275 | CLANG_WARN_EMPTY_BODY = YES; 276 | CLANG_WARN_ENUM_CONVERSION = YES; 277 | CLANG_WARN_INT_CONVERSION = YES; 278 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 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 | CURRENT_PROJECT_VERSION = 1; 284 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 285 | ENABLE_NS_ASSERTIONS = NO; 286 | ENABLE_STRICT_OBJC_MSGSEND = YES; 287 | GCC_C_LANGUAGE_STANDARD = gnu99; 288 | GCC_NO_COMMON_BLOCKS = YES; 289 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 290 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 291 | GCC_WARN_UNDECLARED_SELECTOR = YES; 292 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 293 | GCC_WARN_UNUSED_FUNCTION = YES; 294 | GCC_WARN_UNUSED_VARIABLE = YES; 295 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 296 | MTL_ENABLE_DEBUG_INFO = NO; 297 | SDKROOT = iphoneos; 298 | TARGETED_DEVICE_FAMILY = "1,2"; 299 | VALIDATE_PRODUCT = YES; 300 | VERSIONING_SYSTEM = "apple-generic"; 301 | VERSION_INFO_PREFIX = ""; 302 | }; 303 | name = Release; 304 | }; 305 | 4149057E1D69BB4D006D86E4 /* Debug */ = { 306 | isa = XCBuildConfiguration; 307 | buildSettings = { 308 | CODE_SIGN_IDENTITY = "iPhone Developer"; 309 | DEFINES_MODULE = YES; 310 | DYLIB_COMPATIBILITY_VERSION = 1; 311 | DYLIB_CURRENT_VERSION = 1; 312 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 313 | INFOPLIST_FILE = SSDynamicText/Info.plist; 314 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 315 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 316 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 317 | PRODUCT_BUNDLE_IDENTIFIER = net.splinesoft.SSDynamicText; 318 | PRODUCT_NAME = "$(TARGET_NAME)"; 319 | SKIP_INSTALL = YES; 320 | }; 321 | name = Debug; 322 | }; 323 | 4149057F1D69BB4D006D86E4 /* Release */ = { 324 | isa = XCBuildConfiguration; 325 | buildSettings = { 326 | CODE_SIGN_IDENTITY = "iPhone Developer"; 327 | DEFINES_MODULE = YES; 328 | DYLIB_COMPATIBILITY_VERSION = 1; 329 | DYLIB_CURRENT_VERSION = 1; 330 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 331 | INFOPLIST_FILE = SSDynamicText/Info.plist; 332 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 333 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 334 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 335 | PRODUCT_BUNDLE_IDENTIFIER = net.splinesoft.SSDynamicText; 336 | PRODUCT_NAME = "$(TARGET_NAME)"; 337 | SKIP_INSTALL = YES; 338 | }; 339 | name = Release; 340 | }; 341 | /* End XCBuildConfiguration section */ 342 | 343 | /* Begin XCConfigurationList section */ 344 | 4149056F1D69BB4D006D86E4 /* Build configuration list for PBXProject "SSDynamicText" */ = { 345 | isa = XCConfigurationList; 346 | buildConfigurations = ( 347 | 4149057B1D69BB4D006D86E4 /* Debug */, 348 | 4149057C1D69BB4D006D86E4 /* Release */, 349 | ); 350 | defaultConfigurationIsVisible = 0; 351 | defaultConfigurationName = Release; 352 | }; 353 | 4149057D1D69BB4D006D86E4 /* Build configuration list for PBXNativeTarget "SSDynamicText" */ = { 354 | isa = XCConfigurationList; 355 | buildConfigurations = ( 356 | 4149057E1D69BB4D006D86E4 /* Debug */, 357 | 4149057F1D69BB4D006D86E4 /* Release */, 358 | ); 359 | defaultConfigurationIsVisible = 0; 360 | defaultConfigurationName = Release; 361 | }; 362 | /* End XCConfigurationList section */ 363 | }; 364 | rootObject = 4149056C1D69BB4D006D86E4 /* Project object */; 365 | } 366 | -------------------------------------------------------------------------------- /Example/SSDynamicTextExample.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 4181AA311C30229E0000DDC1 /* SSDynamicsView.m in Sources */ = {isa = PBXBuildFile; fileRef = B74328F41B9461E60098E793 /* SSDynamicsView.m */; }; 11 | 5EE286D7180239B800D286ED /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5EE286D6180239B800D286ED /* Foundation.framework */; }; 12 | 5EE286D9180239B800D286ED /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5EE286D8180239B800D286ED /* CoreGraphics.framework */; }; 13 | 5EE286DB180239B800D286ED /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5EE286DA180239B800D286ED /* UIKit.framework */; }; 14 | 5EE286E1180239B800D286ED /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5EE286DF180239B800D286ED /* InfoPlist.strings */; }; 15 | 5EE286E3180239B800D286ED /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EE286E2180239B800D286ED /* main.m */; }; 16 | 5EE286E7180239B800D286ED /* SSAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EE286E6180239B800D286ED /* SSAppDelegate.m */; }; 17 | 5EE286F0180239B900D286ED /* SSViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EE286EF180239B900D286ED /* SSViewController.m */; }; 18 | 5EE286F2180239B900D286ED /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5EE286F1180239B900D286ED /* Images.xcassets */; }; 19 | 6611CBF51C0E52CC003E68A3 /* UIView+SSTextSizeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6611CBF41C0E52CC003E68A3 /* UIView+SSTextSizeTests.m */; }; 20 | 661812031C0CED6C00F558EC /* UIFont+SSTextSizeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 661812021C0CED6C00F558EC /* UIFont+SSTextSizeTests.m */; }; 21 | 667FF3881C0E4B0A00973E4C /* UIApplication+SSTextSizeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 667FF3871C0E4B0A00973E4C /* UIApplication+SSTextSizeTests.m */; }; 22 | 6696C9C21C14E7880067D4A4 /* SSDynamicViewsReleaseTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6696C9C11C14E7880067D4A4 /* SSDynamicViewsReleaseTests.m */; settings = {COMPILER_FLAGS = "-w"; }; }; 23 | A8E3A0653C3F6162E41DA870 /* libPods-SSDynamicTextExample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 0E2159830340851187ABBF61 /* libPods-SSDynamicTextExample.a */; }; 24 | B70414E61BAAF5750055958F /* SSTestsHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = B70414E51BAAF5750055958F /* SSTestsHelper.m */; }; 25 | B74328F01B9455DC0098E793 /* SSDynamicLabelTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B74328EF1B9455DC0098E793 /* SSDynamicLabelTests.m */; }; 26 | B74328F21B9461CB0098E793 /* SSDynamicsView.xib in Resources */ = {isa = PBXBuildFile; fileRef = B74328F11B9461CB0098E793 /* SSDynamicsView.xib */; }; 27 | B74328F51B9461E60098E793 /* SSDynamicsView.m in Sources */ = {isa = PBXBuildFile; fileRef = B74328F41B9461E60098E793 /* SSDynamicsView.m */; }; 28 | B74328F71B946E2A0098E793 /* SSDynamicTextFieldTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B74328F61B946E2A0098E793 /* SSDynamicTextFieldTests.m */; }; 29 | B74328F91B946EEB0098E793 /* SSDynamicTextViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B74328F81B946EEB0098E793 /* SSDynamicTextViewTests.m */; }; 30 | B74328FB1B946FE90098E793 /* SSDynamicButtonTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B74328FA1B946FE90098E793 /* SSDynamicButtonTests.m */; }; 31 | B74328FE1B9476010098E793 /* SSAttributedStringValidator.m in Sources */ = {isa = PBXBuildFile; fileRef = B74328FD1B9476010098E793 /* SSAttributedStringValidator.m */; }; 32 | C8FE42998DC35A897E622A17 /* libPods-SSDynamicTextTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 514C3AADC3AD1C801B243A28 /* libPods-SSDynamicTextTests.a */; }; 33 | /* End PBXBuildFile section */ 34 | 35 | /* Begin PBXContainerItemProxy section */ 36 | 5E90DACE19F9655600257F8E /* PBXContainerItemProxy */ = { 37 | isa = PBXContainerItemProxy; 38 | containerPortal = 5EE286CB180239B800D286ED /* Project object */; 39 | proxyType = 1; 40 | remoteGlobalIDString = 5EE286D2180239B800D286ED; 41 | remoteInfo = SSDynamicTextExample; 42 | }; 43 | /* End PBXContainerItemProxy section */ 44 | 45 | /* Begin PBXFileReference section */ 46 | 0E2159830340851187ABBF61 /* libPods-SSDynamicTextExample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-SSDynamicTextExample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 47 | 5136338D4A373052CC15BB7D /* Pods-SSDynamicTextTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SSDynamicTextTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-SSDynamicTextTests/Pods-SSDynamicTextTests.release.xcconfig"; sourceTree = ""; }; 48 | 514C3AADC3AD1C801B243A28 /* libPods-SSDynamicTextTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-SSDynamicTextTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 49 | 5E90DAC819F9655600257F8E /* SSDynamicTextTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SSDynamicTextTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 50 | 5E90DACB19F9655600257F8E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 51 | 5EE286D3180239B800D286ED /* SSDynamicTextExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SSDynamicTextExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 52 | 5EE286D6180239B800D286ED /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 53 | 5EE286D8180239B800D286ED /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 54 | 5EE286DA180239B800D286ED /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 55 | 5EE286DE180239B800D286ED /* SSDynamicTextExample-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "SSDynamicTextExample-Info.plist"; sourceTree = ""; }; 56 | 5EE286E0180239B800D286ED /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 57 | 5EE286E2180239B800D286ED /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 58 | 5EE286E4180239B800D286ED /* SSDynamicTextExample-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SSDynamicTextExample-Prefix.pch"; sourceTree = ""; }; 59 | 5EE286E5180239B800D286ED /* SSAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SSAppDelegate.h; sourceTree = ""; }; 60 | 5EE286E6180239B800D286ED /* SSAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SSAppDelegate.m; sourceTree = ""; }; 61 | 5EE286EE180239B900D286ED /* SSViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SSViewController.h; sourceTree = ""; }; 62 | 5EE286EF180239B900D286ED /* SSViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SSViewController.m; sourceTree = ""; }; 63 | 5EE286F1180239B900D286ED /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 64 | 5EE286F8180239B900D286ED /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 65 | 6611CBF41C0E52CC003E68A3 /* UIView+SSTextSizeTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+SSTextSizeTests.m"; sourceTree = ""; }; 66 | 661812021C0CED6C00F558EC /* UIFont+SSTextSizeTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIFont+SSTextSizeTests.m"; sourceTree = ""; }; 67 | 667FF3871C0E4B0A00973E4C /* UIApplication+SSTextSizeTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIApplication+SSTextSizeTests.m"; sourceTree = ""; }; 68 | 6696C9C11C14E7880067D4A4 /* SSDynamicViewsReleaseTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SSDynamicViewsReleaseTests.m; sourceTree = ""; }; 69 | 8624741A93A8C2A0AAD84CD1 /* Pods-SSDynamicTextTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SSDynamicTextTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SSDynamicTextTests/Pods-SSDynamicTextTests.debug.xcconfig"; sourceTree = ""; }; 70 | B70414E41BAAF5750055958F /* SSTestsHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SSTestsHelper.h; sourceTree = ""; }; 71 | B70414E51BAAF5750055958F /* SSTestsHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SSTestsHelper.m; sourceTree = ""; }; 72 | B74328EF1B9455DC0098E793 /* SSDynamicLabelTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SSDynamicLabelTests.m; sourceTree = ""; }; 73 | B74328F11B9461CB0098E793 /* SSDynamicsView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SSDynamicsView.xib; sourceTree = ""; }; 74 | B74328F31B9461E60098E793 /* SSDynamicsView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SSDynamicsView.h; sourceTree = ""; }; 75 | B74328F41B9461E60098E793 /* SSDynamicsView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SSDynamicsView.m; sourceTree = ""; }; 76 | B74328F61B946E2A0098E793 /* SSDynamicTextFieldTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SSDynamicTextFieldTests.m; sourceTree = ""; }; 77 | B74328F81B946EEB0098E793 /* SSDynamicTextViewTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SSDynamicTextViewTests.m; sourceTree = ""; }; 78 | B74328FA1B946FE90098E793 /* SSDynamicButtonTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SSDynamicButtonTests.m; sourceTree = ""; }; 79 | B74328FC1B9476010098E793 /* SSAttributedStringValidator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SSAttributedStringValidator.h; sourceTree = ""; }; 80 | B74328FD1B9476010098E793 /* SSAttributedStringValidator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SSAttributedStringValidator.m; sourceTree = ""; }; 81 | EF12F61553483957D4BC1A52 /* Pods-SSDynamicTextExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SSDynamicTextExample.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SSDynamicTextExample/Pods-SSDynamicTextExample.debug.xcconfig"; sourceTree = ""; }; 82 | F79AFF3911624A2DE41F785F /* Pods-SSDynamicTextExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SSDynamicTextExample.release.xcconfig"; path = "Pods/Target Support Files/Pods-SSDynamicTextExample/Pods-SSDynamicTextExample.release.xcconfig"; sourceTree = ""; }; 83 | /* End PBXFileReference section */ 84 | 85 | /* Begin PBXFrameworksBuildPhase section */ 86 | 5E90DAC519F9655600257F8E /* Frameworks */ = { 87 | isa = PBXFrameworksBuildPhase; 88 | buildActionMask = 2147483647; 89 | files = ( 90 | C8FE42998DC35A897E622A17 /* libPods-SSDynamicTextTests.a in Frameworks */, 91 | ); 92 | runOnlyForDeploymentPostprocessing = 0; 93 | }; 94 | 5EE286D0180239B800D286ED /* Frameworks */ = { 95 | isa = PBXFrameworksBuildPhase; 96 | buildActionMask = 2147483647; 97 | files = ( 98 | 5EE286D9180239B800D286ED /* CoreGraphics.framework in Frameworks */, 99 | 5EE286DB180239B800D286ED /* UIKit.framework in Frameworks */, 100 | 5EE286D7180239B800D286ED /* Foundation.framework in Frameworks */, 101 | A8E3A0653C3F6162E41DA870 /* libPods-SSDynamicTextExample.a in Frameworks */, 102 | ); 103 | runOnlyForDeploymentPostprocessing = 0; 104 | }; 105 | /* End PBXFrameworksBuildPhase section */ 106 | 107 | /* Begin PBXGroup section */ 108 | 5E90DAC919F9655600257F8E /* SSDynamicTextTests */ = { 109 | isa = PBXGroup; 110 | children = ( 111 | B74328EF1B9455DC0098E793 /* SSDynamicLabelTests.m */, 112 | B74328F61B946E2A0098E793 /* SSDynamicTextFieldTests.m */, 113 | B74328F81B946EEB0098E793 /* SSDynamicTextViewTests.m */, 114 | B74328FA1B946FE90098E793 /* SSDynamicButtonTests.m */, 115 | 661812021C0CED6C00F558EC /* UIFont+SSTextSizeTests.m */, 116 | 6696C9C11C14E7880067D4A4 /* SSDynamicViewsReleaseTests.m */, 117 | 667FF3871C0E4B0A00973E4C /* UIApplication+SSTextSizeTests.m */, 118 | 6611CBF41C0E52CC003E68A3 /* UIView+SSTextSizeTests.m */, 119 | B70414E41BAAF5750055958F /* SSTestsHelper.h */, 120 | B70414E51BAAF5750055958F /* SSTestsHelper.m */, 121 | B74328FC1B9476010098E793 /* SSAttributedStringValidator.h */, 122 | B74328FD1B9476010098E793 /* SSAttributedStringValidator.m */, 123 | 5E90DACA19F9655600257F8E /* Supporting Files */, 124 | ); 125 | path = SSDynamicTextTests; 126 | sourceTree = ""; 127 | }; 128 | 5E90DACA19F9655600257F8E /* Supporting Files */ = { 129 | isa = PBXGroup; 130 | children = ( 131 | 5E90DACB19F9655600257F8E /* Info.plist */, 132 | ); 133 | name = "Supporting Files"; 134 | sourceTree = ""; 135 | }; 136 | 5EE286CA180239B800D286ED = { 137 | isa = PBXGroup; 138 | children = ( 139 | 5EE286DC180239B800D286ED /* SSDynamicTextExample */, 140 | 5E90DAC919F9655600257F8E /* SSDynamicTextTests */, 141 | 5EE286D5180239B800D286ED /* Frameworks */, 142 | 5EE286D4180239B800D286ED /* Products */, 143 | 6C7DA71C3E16BF3548FD13C4 /* Pods */, 144 | ); 145 | sourceTree = ""; 146 | }; 147 | 5EE286D4180239B800D286ED /* Products */ = { 148 | isa = PBXGroup; 149 | children = ( 150 | 5EE286D3180239B800D286ED /* SSDynamicTextExample.app */, 151 | 5E90DAC819F9655600257F8E /* SSDynamicTextTests.xctest */, 152 | ); 153 | name = Products; 154 | sourceTree = ""; 155 | }; 156 | 5EE286D5180239B800D286ED /* Frameworks */ = { 157 | isa = PBXGroup; 158 | children = ( 159 | 5EE286D6180239B800D286ED /* Foundation.framework */, 160 | 5EE286D8180239B800D286ED /* CoreGraphics.framework */, 161 | 5EE286DA180239B800D286ED /* UIKit.framework */, 162 | 5EE286F8180239B900D286ED /* XCTest.framework */, 163 | 0E2159830340851187ABBF61 /* libPods-SSDynamicTextExample.a */, 164 | 514C3AADC3AD1C801B243A28 /* libPods-SSDynamicTextTests.a */, 165 | ); 166 | name = Frameworks; 167 | sourceTree = ""; 168 | }; 169 | 5EE286DC180239B800D286ED /* SSDynamicTextExample */ = { 170 | isa = PBXGroup; 171 | children = ( 172 | 5EE286E5180239B800D286ED /* SSAppDelegate.h */, 173 | 5EE286E6180239B800D286ED /* SSAppDelegate.m */, 174 | 5EE286EE180239B900D286ED /* SSViewController.h */, 175 | 5EE286EF180239B900D286ED /* SSViewController.m */, 176 | 5EE286F1180239B900D286ED /* Images.xcassets */, 177 | 5EE286DD180239B800D286ED /* Supporting Files */, 178 | B74328F31B9461E60098E793 /* SSDynamicsView.h */, 179 | B74328F41B9461E60098E793 /* SSDynamicsView.m */, 180 | B74328F11B9461CB0098E793 /* SSDynamicsView.xib */, 181 | ); 182 | path = SSDynamicTextExample; 183 | sourceTree = ""; 184 | }; 185 | 5EE286DD180239B800D286ED /* Supporting Files */ = { 186 | isa = PBXGroup; 187 | children = ( 188 | 5EE286DE180239B800D286ED /* SSDynamicTextExample-Info.plist */, 189 | 5EE286DF180239B800D286ED /* InfoPlist.strings */, 190 | 5EE286E2180239B800D286ED /* main.m */, 191 | 5EE286E4180239B800D286ED /* SSDynamicTextExample-Prefix.pch */, 192 | ); 193 | name = "Supporting Files"; 194 | sourceTree = ""; 195 | }; 196 | 6C7DA71C3E16BF3548FD13C4 /* Pods */ = { 197 | isa = PBXGroup; 198 | children = ( 199 | EF12F61553483957D4BC1A52 /* Pods-SSDynamicTextExample.debug.xcconfig */, 200 | F79AFF3911624A2DE41F785F /* Pods-SSDynamicTextExample.release.xcconfig */, 201 | 8624741A93A8C2A0AAD84CD1 /* Pods-SSDynamicTextTests.debug.xcconfig */, 202 | 5136338D4A373052CC15BB7D /* Pods-SSDynamicTextTests.release.xcconfig */, 203 | ); 204 | name = Pods; 205 | sourceTree = ""; 206 | }; 207 | /* End PBXGroup section */ 208 | 209 | /* Begin PBXNativeTarget section */ 210 | 5E90DAC719F9655600257F8E /* SSDynamicTextTests */ = { 211 | isa = PBXNativeTarget; 212 | buildConfigurationList = 5E90DAD019F9655600257F8E /* Build configuration list for PBXNativeTarget "SSDynamicTextTests" */; 213 | buildPhases = ( 214 | 444194254D86E2464792CC92 /* [CP] Check Pods Manifest.lock */, 215 | 5E90DAC419F9655600257F8E /* Sources */, 216 | 5E90DAC519F9655600257F8E /* Frameworks */, 217 | 5E90DAC619F9655600257F8E /* Resources */, 218 | FC932F9DD8127662F810E588 /* [CP] Embed Pods Frameworks */, 219 | 2F2FACE19979CFCAD33B6008 /* [CP] Copy Pods Resources */, 220 | ); 221 | buildRules = ( 222 | ); 223 | dependencies = ( 224 | 5E90DACF19F9655600257F8E /* PBXTargetDependency */, 225 | ); 226 | name = SSDynamicTextTests; 227 | productName = SSDynamicTextTests; 228 | productReference = 5E90DAC819F9655600257F8E /* SSDynamicTextTests.xctest */; 229 | productType = "com.apple.product-type.bundle.unit-test"; 230 | }; 231 | 5EE286D2180239B800D286ED /* SSDynamicTextExample */ = { 232 | isa = PBXNativeTarget; 233 | buildConfigurationList = 5EE28708180239B900D286ED /* Build configuration list for PBXNativeTarget "SSDynamicTextExample" */; 234 | buildPhases = ( 235 | EB6F676944BE6E9D3543D151 /* [CP] Check Pods Manifest.lock */, 236 | 5EE286CF180239B800D286ED /* Sources */, 237 | 5EE286D0180239B800D286ED /* Frameworks */, 238 | 5EE286D1180239B800D286ED /* Resources */, 239 | 19E8353FD05FA860EA48635F /* [CP] Embed Pods Frameworks */, 240 | 0C91A7A1CB8E1199D5B02A4B /* [CP] Copy Pods Resources */, 241 | ); 242 | buildRules = ( 243 | ); 244 | dependencies = ( 245 | ); 246 | name = SSDynamicTextExample; 247 | productName = SSDynamicTextExample; 248 | productReference = 5EE286D3180239B800D286ED /* SSDynamicTextExample.app */; 249 | productType = "com.apple.product-type.application"; 250 | }; 251 | /* End PBXNativeTarget section */ 252 | 253 | /* Begin PBXProject section */ 254 | 5EE286CB180239B800D286ED /* Project object */ = { 255 | isa = PBXProject; 256 | attributes = { 257 | CLASSPREFIX = SS; 258 | LastUpgradeCheck = 0610; 259 | ORGANIZATIONNAME = Splinesoft; 260 | TargetAttributes = { 261 | 5E90DAC719F9655600257F8E = { 262 | CreatedOnToolsVersion = 6.1; 263 | TestTargetID = 5EE286D2180239B800D286ED; 264 | }; 265 | }; 266 | }; 267 | buildConfigurationList = 5EE286CE180239B800D286ED /* Build configuration list for PBXProject "SSDynamicTextExample" */; 268 | compatibilityVersion = "Xcode 3.2"; 269 | developmentRegion = English; 270 | hasScannedForEncodings = 0; 271 | knownRegions = ( 272 | en, 273 | Base, 274 | ); 275 | mainGroup = 5EE286CA180239B800D286ED; 276 | productRefGroup = 5EE286D4180239B800D286ED /* Products */; 277 | projectDirPath = ""; 278 | projectRoot = ""; 279 | targets = ( 280 | 5EE286D2180239B800D286ED /* SSDynamicTextExample */, 281 | 5E90DAC719F9655600257F8E /* SSDynamicTextTests */, 282 | ); 283 | }; 284 | /* End PBXProject section */ 285 | 286 | /* Begin PBXResourcesBuildPhase section */ 287 | 5E90DAC619F9655600257F8E /* Resources */ = { 288 | isa = PBXResourcesBuildPhase; 289 | buildActionMask = 2147483647; 290 | files = ( 291 | ); 292 | runOnlyForDeploymentPostprocessing = 0; 293 | }; 294 | 5EE286D1180239B800D286ED /* Resources */ = { 295 | isa = PBXResourcesBuildPhase; 296 | buildActionMask = 2147483647; 297 | files = ( 298 | 5EE286F2180239B900D286ED /* Images.xcassets in Resources */, 299 | B74328F21B9461CB0098E793 /* SSDynamicsView.xib in Resources */, 300 | 5EE286E1180239B800D286ED /* InfoPlist.strings in Resources */, 301 | ); 302 | runOnlyForDeploymentPostprocessing = 0; 303 | }; 304 | /* End PBXResourcesBuildPhase section */ 305 | 306 | /* Begin PBXShellScriptBuildPhase section */ 307 | 0C91A7A1CB8E1199D5B02A4B /* [CP] Copy Pods Resources */ = { 308 | isa = PBXShellScriptBuildPhase; 309 | buildActionMask = 2147483647; 310 | files = ( 311 | ); 312 | inputPaths = ( 313 | ); 314 | name = "[CP] Copy Pods Resources"; 315 | outputPaths = ( 316 | ); 317 | runOnlyForDeploymentPostprocessing = 0; 318 | shellPath = /bin/sh; 319 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SSDynamicTextExample/Pods-SSDynamicTextExample-resources.sh\"\n"; 320 | showEnvVarsInLog = 0; 321 | }; 322 | 19E8353FD05FA860EA48635F /* [CP] Embed Pods Frameworks */ = { 323 | isa = PBXShellScriptBuildPhase; 324 | buildActionMask = 2147483647; 325 | files = ( 326 | ); 327 | inputPaths = ( 328 | ); 329 | name = "[CP] Embed Pods Frameworks"; 330 | outputPaths = ( 331 | ); 332 | runOnlyForDeploymentPostprocessing = 0; 333 | shellPath = /bin/sh; 334 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SSDynamicTextExample/Pods-SSDynamicTextExample-frameworks.sh\"\n"; 335 | showEnvVarsInLog = 0; 336 | }; 337 | 2F2FACE19979CFCAD33B6008 /* [CP] Copy Pods Resources */ = { 338 | isa = PBXShellScriptBuildPhase; 339 | buildActionMask = 2147483647; 340 | files = ( 341 | ); 342 | inputPaths = ( 343 | ); 344 | name = "[CP] Copy Pods Resources"; 345 | outputPaths = ( 346 | ); 347 | runOnlyForDeploymentPostprocessing = 0; 348 | shellPath = /bin/sh; 349 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SSDynamicTextTests/Pods-SSDynamicTextTests-resources.sh\"\n"; 350 | showEnvVarsInLog = 0; 351 | }; 352 | 444194254D86E2464792CC92 /* [CP] Check Pods Manifest.lock */ = { 353 | isa = PBXShellScriptBuildPhase; 354 | buildActionMask = 2147483647; 355 | files = ( 356 | ); 357 | inputPaths = ( 358 | ); 359 | name = "[CP] Check Pods Manifest.lock"; 360 | outputPaths = ( 361 | ); 362 | runOnlyForDeploymentPostprocessing = 0; 363 | shellPath = /bin/sh; 364 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; 365 | showEnvVarsInLog = 0; 366 | }; 367 | EB6F676944BE6E9D3543D151 /* [CP] Check Pods Manifest.lock */ = { 368 | isa = PBXShellScriptBuildPhase; 369 | buildActionMask = 2147483647; 370 | files = ( 371 | ); 372 | inputPaths = ( 373 | ); 374 | name = "[CP] Check Pods Manifest.lock"; 375 | outputPaths = ( 376 | ); 377 | runOnlyForDeploymentPostprocessing = 0; 378 | shellPath = /bin/sh; 379 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; 380 | showEnvVarsInLog = 0; 381 | }; 382 | FC932F9DD8127662F810E588 /* [CP] Embed Pods Frameworks */ = { 383 | isa = PBXShellScriptBuildPhase; 384 | buildActionMask = 2147483647; 385 | files = ( 386 | ); 387 | inputPaths = ( 388 | ); 389 | name = "[CP] Embed Pods Frameworks"; 390 | outputPaths = ( 391 | ); 392 | runOnlyForDeploymentPostprocessing = 0; 393 | shellPath = /bin/sh; 394 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SSDynamicTextTests/Pods-SSDynamicTextTests-frameworks.sh\"\n"; 395 | showEnvVarsInLog = 0; 396 | }; 397 | /* End PBXShellScriptBuildPhase section */ 398 | 399 | /* Begin PBXSourcesBuildPhase section */ 400 | 5E90DAC419F9655600257F8E /* Sources */ = { 401 | isa = PBXSourcesBuildPhase; 402 | buildActionMask = 2147483647; 403 | files = ( 404 | B74328F01B9455DC0098E793 /* SSDynamicLabelTests.m in Sources */, 405 | B74328F91B946EEB0098E793 /* SSDynamicTextViewTests.m in Sources */, 406 | 4181AA311C30229E0000DDC1 /* SSDynamicsView.m in Sources */, 407 | B74328F71B946E2A0098E793 /* SSDynamicTextFieldTests.m in Sources */, 408 | B74328FE1B9476010098E793 /* SSAttributedStringValidator.m in Sources */, 409 | 6696C9C21C14E7880067D4A4 /* SSDynamicViewsReleaseTests.m in Sources */, 410 | 661812031C0CED6C00F558EC /* UIFont+SSTextSizeTests.m in Sources */, 411 | 6611CBF51C0E52CC003E68A3 /* UIView+SSTextSizeTests.m in Sources */, 412 | 667FF3881C0E4B0A00973E4C /* UIApplication+SSTextSizeTests.m in Sources */, 413 | B70414E61BAAF5750055958F /* SSTestsHelper.m in Sources */, 414 | B74328FB1B946FE90098E793 /* SSDynamicButtonTests.m in Sources */, 415 | ); 416 | runOnlyForDeploymentPostprocessing = 0; 417 | }; 418 | 5EE286CF180239B800D286ED /* Sources */ = { 419 | isa = PBXSourcesBuildPhase; 420 | buildActionMask = 2147483647; 421 | files = ( 422 | B74328F51B9461E60098E793 /* SSDynamicsView.m in Sources */, 423 | 5EE286F0180239B900D286ED /* SSViewController.m in Sources */, 424 | 5EE286E7180239B800D286ED /* SSAppDelegate.m in Sources */, 425 | 5EE286E3180239B800D286ED /* main.m in Sources */, 426 | ); 427 | runOnlyForDeploymentPostprocessing = 0; 428 | }; 429 | /* End PBXSourcesBuildPhase section */ 430 | 431 | /* Begin PBXTargetDependency section */ 432 | 5E90DACF19F9655600257F8E /* PBXTargetDependency */ = { 433 | isa = PBXTargetDependency; 434 | target = 5EE286D2180239B800D286ED /* SSDynamicTextExample */; 435 | targetProxy = 5E90DACE19F9655600257F8E /* PBXContainerItemProxy */; 436 | }; 437 | /* End PBXTargetDependency section */ 438 | 439 | /* Begin PBXVariantGroup section */ 440 | 5EE286DF180239B800D286ED /* InfoPlist.strings */ = { 441 | isa = PBXVariantGroup; 442 | children = ( 443 | 5EE286E0180239B800D286ED /* en */, 444 | ); 445 | name = InfoPlist.strings; 446 | sourceTree = ""; 447 | }; 448 | /* End PBXVariantGroup section */ 449 | 450 | /* Begin XCBuildConfiguration section */ 451 | 5E90DAD119F9655600257F8E /* Debug */ = { 452 | isa = XCBuildConfiguration; 453 | baseConfigurationReference = 8624741A93A8C2A0AAD84CD1 /* Pods-SSDynamicTextTests.debug.xcconfig */; 454 | buildSettings = { 455 | BUNDLE_LOADER = "$(TEST_HOST)"; 456 | CLANG_WARN_UNREACHABLE_CODE = YES; 457 | ENABLE_STRICT_OBJC_MSGSEND = YES; 458 | FRAMEWORK_SEARCH_PATHS = ( 459 | "$(SDKROOT)/Developer/Library/Frameworks", 460 | "$(inherited)", 461 | ); 462 | GCC_PREPROCESSOR_DEFINITIONS = ( 463 | "DEBUG=1", 464 | "$(inherited)", 465 | ); 466 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 467 | INFOPLIST_FILE = SSDynamicTextTests/Info.plist; 468 | IPHONEOS_DEPLOYMENT_TARGET = 8.1; 469 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 470 | MTL_ENABLE_DEBUG_INFO = YES; 471 | ONLY_ACTIVE_ARCH = YES; 472 | PRODUCT_NAME = "$(TARGET_NAME)"; 473 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SSDynamicTextExample.app/SSDynamicTextExample"; 474 | }; 475 | name = Debug; 476 | }; 477 | 5E90DAD219F9655600257F8E /* Release */ = { 478 | isa = XCBuildConfiguration; 479 | baseConfigurationReference = 5136338D4A373052CC15BB7D /* Pods-SSDynamicTextTests.release.xcconfig */; 480 | buildSettings = { 481 | BUNDLE_LOADER = "$(TEST_HOST)"; 482 | CLANG_WARN_UNREACHABLE_CODE = YES; 483 | ENABLE_STRICT_OBJC_MSGSEND = YES; 484 | FRAMEWORK_SEARCH_PATHS = ( 485 | "$(SDKROOT)/Developer/Library/Frameworks", 486 | "$(inherited)", 487 | ); 488 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 489 | INFOPLIST_FILE = SSDynamicTextTests/Info.plist; 490 | IPHONEOS_DEPLOYMENT_TARGET = 8.1; 491 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 492 | MTL_ENABLE_DEBUG_INFO = NO; 493 | PRODUCT_NAME = "$(TARGET_NAME)"; 494 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SSDynamicTextExample.app/SSDynamicTextExample"; 495 | }; 496 | name = Release; 497 | }; 498 | 5EE28706180239B900D286ED /* Debug */ = { 499 | isa = XCBuildConfiguration; 500 | buildSettings = { 501 | ALWAYS_SEARCH_USER_PATHS = NO; 502 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 503 | CLANG_CXX_LIBRARY = "libc++"; 504 | CLANG_ENABLE_MODULES = YES; 505 | CLANG_ENABLE_OBJC_ARC = YES; 506 | CLANG_WARN_BOOL_CONVERSION = YES; 507 | CLANG_WARN_CONSTANT_CONVERSION = YES; 508 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 509 | CLANG_WARN_EMPTY_BODY = YES; 510 | CLANG_WARN_ENUM_CONVERSION = YES; 511 | CLANG_WARN_INT_CONVERSION = YES; 512 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 513 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 514 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 515 | COPY_PHASE_STRIP = NO; 516 | GCC_C_LANGUAGE_STANDARD = gnu99; 517 | GCC_DYNAMIC_NO_PIC = NO; 518 | GCC_OPTIMIZATION_LEVEL = 0; 519 | GCC_PREPROCESSOR_DEFINITIONS = ( 520 | "DEBUG=1", 521 | "$(inherited)", 522 | ); 523 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 524 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 525 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 526 | GCC_WARN_UNDECLARED_SELECTOR = YES; 527 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 528 | GCC_WARN_UNUSED_FUNCTION = YES; 529 | GCC_WARN_UNUSED_VARIABLE = YES; 530 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 531 | ONLY_ACTIVE_ARCH = YES; 532 | SDKROOT = iphoneos; 533 | TARGETED_DEVICE_FAMILY = "1,2"; 534 | }; 535 | name = Debug; 536 | }; 537 | 5EE28707180239B900D286ED /* Release */ = { 538 | isa = XCBuildConfiguration; 539 | buildSettings = { 540 | ALWAYS_SEARCH_USER_PATHS = NO; 541 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 542 | CLANG_CXX_LIBRARY = "libc++"; 543 | CLANG_ENABLE_MODULES = YES; 544 | CLANG_ENABLE_OBJC_ARC = YES; 545 | CLANG_WARN_BOOL_CONVERSION = YES; 546 | CLANG_WARN_CONSTANT_CONVERSION = YES; 547 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 548 | CLANG_WARN_EMPTY_BODY = YES; 549 | CLANG_WARN_ENUM_CONVERSION = YES; 550 | CLANG_WARN_INT_CONVERSION = YES; 551 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 552 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 553 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 554 | COPY_PHASE_STRIP = YES; 555 | ENABLE_NS_ASSERTIONS = NO; 556 | GCC_C_LANGUAGE_STANDARD = gnu99; 557 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 558 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 559 | GCC_WARN_UNDECLARED_SELECTOR = YES; 560 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 561 | GCC_WARN_UNUSED_FUNCTION = YES; 562 | GCC_WARN_UNUSED_VARIABLE = YES; 563 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 564 | SDKROOT = iphoneos; 565 | TARGETED_DEVICE_FAMILY = "1,2"; 566 | VALIDATE_PRODUCT = YES; 567 | }; 568 | name = Release; 569 | }; 570 | 5EE28709180239B900D286ED /* Debug */ = { 571 | isa = XCBuildConfiguration; 572 | baseConfigurationReference = EF12F61553483957D4BC1A52 /* Pods-SSDynamicTextExample.debug.xcconfig */; 573 | buildSettings = { 574 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 575 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 576 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 577 | GCC_PREFIX_HEADER = "SSDynamicTextExample/SSDynamicTextExample-Prefix.pch"; 578 | INFOPLIST_FILE = "SSDynamicTextExample/SSDynamicTextExample-Info.plist"; 579 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 580 | ONLY_ACTIVE_ARCH = YES; 581 | PRODUCT_NAME = "$(TARGET_NAME)"; 582 | WRAPPER_EXTENSION = app; 583 | }; 584 | name = Debug; 585 | }; 586 | 5EE2870A180239B900D286ED /* Release */ = { 587 | isa = XCBuildConfiguration; 588 | baseConfigurationReference = F79AFF3911624A2DE41F785F /* Pods-SSDynamicTextExample.release.xcconfig */; 589 | buildSettings = { 590 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 591 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 592 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 593 | GCC_PREFIX_HEADER = "SSDynamicTextExample/SSDynamicTextExample-Prefix.pch"; 594 | INFOPLIST_FILE = "SSDynamicTextExample/SSDynamicTextExample-Info.plist"; 595 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 596 | PRODUCT_NAME = "$(TARGET_NAME)"; 597 | WRAPPER_EXTENSION = app; 598 | }; 599 | name = Release; 600 | }; 601 | /* End XCBuildConfiguration section */ 602 | 603 | /* Begin XCConfigurationList section */ 604 | 5E90DAD019F9655600257F8E /* Build configuration list for PBXNativeTarget "SSDynamicTextTests" */ = { 605 | isa = XCConfigurationList; 606 | buildConfigurations = ( 607 | 5E90DAD119F9655600257F8E /* Debug */, 608 | 5E90DAD219F9655600257F8E /* Release */, 609 | ); 610 | defaultConfigurationIsVisible = 0; 611 | defaultConfigurationName = Release; 612 | }; 613 | 5EE286CE180239B800D286ED /* Build configuration list for PBXProject "SSDynamicTextExample" */ = { 614 | isa = XCConfigurationList; 615 | buildConfigurations = ( 616 | 5EE28706180239B900D286ED /* Debug */, 617 | 5EE28707180239B900D286ED /* Release */, 618 | ); 619 | defaultConfigurationIsVisible = 0; 620 | defaultConfigurationName = Release; 621 | }; 622 | 5EE28708180239B900D286ED /* Build configuration list for PBXNativeTarget "SSDynamicTextExample" */ = { 623 | isa = XCConfigurationList; 624 | buildConfigurations = ( 625 | 5EE28709180239B900D286ED /* Debug */, 626 | 5EE2870A180239B900D286ED /* Release */, 627 | ); 628 | defaultConfigurationIsVisible = 0; 629 | defaultConfigurationName = Release; 630 | }; 631 | /* End XCConfigurationList section */ 632 | }; 633 | rootObject = 5EE286CB180239B800D286ED /* Project object */; 634 | } 635 | --------------------------------------------------------------------------------