├── TextAttributes.xcodeproj ├── xcuserdata │ └── damien.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ └── xcschememanagement.plist ├── project.xcworkspace │ └── contents.xcworkspacedata ├── xcshareddata │ └── xcschemes │ │ ├── TextAttributes iOS Tests.xcscheme │ │ ├── TextAttributes iOS.xcscheme │ │ ├── TextAttributes watchOS.xcscheme │ │ ├── TextAttributes OSX.xcscheme │ │ └── TextAttributes tvOS.xcscheme └── project.pbxproj ├── .travis.yml ├── .gitignore ├── TextAttributes.podspec ├── Tests ├── Supporting Files │ └── Info.plist └── TextAttributesTests.swift ├── Source ├── Supporting Files │ ├── Info.plist │ ├── TextAttributes.h │ └── Utilities.swift ├── Extensions │ ├── NSRange+TextAttributes.swift │ ├── NSAttributedString+TextAttributes.swift │ ├── NSMutableParagraphStyle+TextAttributes.swift │ └── NSMutableAttributedString+TextAttributes.swift └── TextAttributes.swift ├── LICENSE ├── Package.swift └── README.md /TextAttributes.xcodeproj/xcuserdata/damien.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /TextAttributes.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: swift 2 | 3 | branches: 4 | only: 5 | - master 6 | 7 | xcode_project: TextAttributes.xcodeproj 8 | xcode_scheme: TextAttributesTests 9 | osx_image: xcode11.2 10 | 11 | script: 12 | - xcodebuild test -project TextAttributes.xcodeproj -scheme "TextAttributes iOS Tests" -destination "platform=iOS Simulator,name=iPhone 11" 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, 4 | # Objective-C.gitignore & Swift.gitignore 5 | 6 | ## Build generated 7 | build/ 8 | DerivedData 9 | 10 | ## Various settings 11 | *.pbxuser 12 | !default.pbxuser 13 | *.mode1v3 14 | !default.mode1v3 15 | *.mode2v3 16 | !default.mode2v3 17 | *.perspectivev3 18 | !default.perspectivev3 19 | xcuserdata 20 | 21 | ## Other 22 | *.xccheckout 23 | *.moved-aside 24 | *.xcuserstate 25 | *.xcscmblueprint 26 | 27 | ## Obj-C/Swift specific 28 | *.hmap 29 | *.ipa 30 | 31 | # Carthage 32 | Carthage/Build 33 | -------------------------------------------------------------------------------- /TextAttributes.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'TextAttributes' 3 | s.version = '2.0.2' 4 | s.license = 'MIT' 5 | s.homepage = 'https://github.com/delba/TextAttributes' 6 | s.author = { 'Damien' => 'damien@delba.io' } 7 | s.summary = 'An easier way to compose attributed strings' 8 | s.source = { :git => 'https://github.com/delba/TextAttributes.git', :tag => s.version } 9 | s.swift_version = '5.0' 10 | 11 | s.ios.deployment_target = '8.0' 12 | s.osx.deployment_target = '10.10' 13 | s.tvos.deployment_target = '9.0' 14 | s.watchos.deployment_target = '2.0' 15 | 16 | s.source_files = 'Source/**/*.{swift,h}' 17 | end 18 | -------------------------------------------------------------------------------- /Tests/Supporting Files/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Source/Supporting Files/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.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 Damien (http://delba.io) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /Source/Supporting Files/TextAttributes.h: -------------------------------------------------------------------------------- 1 | // 2 | // TextAttributes.h 3 | // 4 | // Copyright (c) 2016-2019 Damien (http://delba.io) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | #import 26 | 27 | #if TARGET_OS_IPHONE 28 | @import UIKit; 29 | #else 30 | @import AppKit; 31 | #endif 32 | 33 | FOUNDATION_EXPORT double TextAttributesVersionNumber; 34 | FOUNDATION_EXPORT const unsigned char TextAttributesVersionString[]; 35 | -------------------------------------------------------------------------------- /Source/Extensions/NSRange+TextAttributes.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NSRange+TextAttributes.swift 3 | // 4 | // Copyright (c) 2016-2019 Damien (http://delba.io) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | extension NSRange { 28 | init(_ range: Range) { 29 | self = NSRange(location: range.lowerBound, length: range.count) 30 | } 31 | 32 | init(_ string: NSString) { 33 | self = NSRange(location: 0, length: string.length) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.0 2 | // 3 | // Package.swift 4 | // 5 | // Copyright (c) 2016-2019 Damien (http://delba.io) 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in all 15 | // copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | // SOFTWARE. 24 | // 25 | 26 | import PackageDescription 27 | 28 | let package = Package( 29 | name: "TextAttributes", 30 | products: [ 31 | .library( 32 | name: "TextAttributes", 33 | targets: ["TextAttributes"]), 34 | ], 35 | targets: [ 36 | .target( 37 | name: "TextAttributes", 38 | path: "Source") 39 | ] 40 | ) 41 | -------------------------------------------------------------------------------- /Source/Supporting Files/Utilities.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Utilities.swift 3 | // 4 | // Copyright (c) 2016-2019 Damien (http://delba.io) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | #if canImport(UIKit) 26 | import UIKit 27 | 28 | public typealias Font = UIFont 29 | public typealias Color = UIColor 30 | public typealias Image = UIImage 31 | #elseif canImport(AppKit) 32 | import AppKit 33 | 34 | public typealias Font = NSFont 35 | public typealias Color = NSColor 36 | public typealias Image = NSImage 37 | 38 | extension NSColor { 39 | public convenience init(red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) { 40 | self.init(srgbRed: red, green: green, blue: blue, alpha: alpha) 41 | } 42 | } 43 | #endif 44 | -------------------------------------------------------------------------------- /TextAttributes.xcodeproj/xcuserdata/damien.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | TextAttributes OSX.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 4 11 | 12 | TextAttributes iOS Tests.xcscheme_^#shared#^_ 13 | 14 | isShown 15 | 16 | orderHint 17 | 3 18 | 19 | TextAttributes iOS.xcscheme_^#shared#^_ 20 | 21 | orderHint 22 | 0 23 | 24 | TextAttributes tvOS.xcscheme_^#shared#^_ 25 | 26 | orderHint 27 | 1 28 | 29 | TextAttributes watchOS.xcscheme_^#shared#^_ 30 | 31 | orderHint 32 | 2 33 | 34 | 35 | SuppressBuildableAutocreation 36 | 37 | 6D2475361CAAB1050044D223 38 | 39 | primary 40 | 41 | 42 | 6D2475401CAAB1050044D223 43 | 44 | primary 45 | 46 | 47 | 6DB519771CCA7F30005C3E83 48 | 49 | primary 50 | 51 | 52 | 6DB5198B1CCA8CEF005C3E83 53 | 54 | primary 55 | 56 | 57 | 6DB519941CCA8CEF005C3E83 58 | 59 | primary 60 | 61 | 62 | 6DDF4E2F1CD1260A002AA459 63 | 64 | primary 65 | 66 | 67 | 6DDF4E381CD1260B002AA459 68 | 69 | primary 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /TextAttributes.xcodeproj/xcshareddata/xcschemes/TextAttributes iOS Tests.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 14 | 15 | 17 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 39 | 40 | 41 | 42 | 48 | 49 | 51 | 52 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /Source/Extensions/NSAttributedString+TextAttributes.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NSAttributedString+TextAttributes.swift 3 | // 4 | // Copyright (c) 2016-2019 Damien (http://delba.io) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | extension NSAttributedString { 28 | /** 29 | Returns an NSAttributedString object initialized with a given string and attributes. 30 | 31 | - parameter string: The string for the new attributed string. 32 | - parameter attributes: The attributes for the new attributed string. 33 | 34 | - returns: The newly created NSAttributedString. 35 | */ 36 | public convenience init(string: NSString, attributes: TextAttributes) { 37 | self.init(string: string as String, attributes: attributes) 38 | } 39 | 40 | /** 41 | Returns an NSAttributedString object initialized with a given string and attributes. 42 | 43 | - parameter string: The string for the new attributed string. 44 | - parameter attributes: The attributes for the new attributed string. 45 | 46 | - returns: The newly created NSAttributedString. 47 | */ 48 | public convenience init(string: String, attributes: TextAttributes) { 49 | self.init(string: string, attributes: attributes.dictionary) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Source/Extensions/NSMutableParagraphStyle+TextAttributes.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NSMutableParagraphStyle+TextAttributes.swift 3 | // 4 | // Copyright (c) 2016-2019 Damien (http://delba.io) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | #if canImport(UIKit) 26 | import UIKit 27 | #elseif canImport(AppKit) 28 | import AppKit 29 | #endif 30 | 31 | extension NSMutableParagraphStyle { 32 | func clone() -> NSMutableParagraphStyle { 33 | let clone = NSMutableParagraphStyle() 34 | 35 | if #available(iOS 9.0, *) { 36 | clone.setParagraphStyle(self) 37 | } else { 38 | clone.cloneParagraphStyle(self) 39 | } 40 | 41 | return clone 42 | } 43 | 44 | private func cloneParagraphStyle(_ other: NSMutableParagraphStyle) { 45 | alignment = other.alignment 46 | firstLineHeadIndent = other.firstLineHeadIndent 47 | headIndent = other.headIndent 48 | tailIndent = other.tailIndent 49 | lineBreakMode = other.lineBreakMode 50 | maximumLineHeight = other.maximumLineHeight 51 | minimumLineHeight = other.minimumLineHeight 52 | lineSpacing = other.lineSpacing 53 | paragraphSpacing = other.paragraphSpacing 54 | paragraphSpacingBefore = other.paragraphSpacingBefore 55 | baseWritingDirection = other.baseWritingDirection 56 | lineHeightMultiple = other.lineHeightMultiple 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /TextAttributes.xcodeproj/xcshareddata/xcschemes/TextAttributes iOS.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 | -------------------------------------------------------------------------------- /TextAttributes.xcodeproj/xcshareddata/xcschemes/TextAttributes watchOS.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 | -------------------------------------------------------------------------------- /Source/Extensions/NSMutableAttributedString+TextAttributes.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NSMutableAttributedString+TextAttributes.swift 3 | // 4 | // Copyright (c) 2016-2019 Damien (http://delba.io) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | import Foundation 26 | 27 | extension NSMutableAttributedString { 28 | /** 29 | Sets the attributes to the specified attributes. 30 | 31 | - parameter attributes: The attributes to set. 32 | */ 33 | open func setAttributes(_ attributes: TextAttributes) { 34 | setAttributes(attributes, range: NSRange(mutableString)) 35 | } 36 | 37 | /** 38 | Sets the attributes for the characters in the specified range to the specified attributes. 39 | 40 | - parameter attributes: The attributes to set. 41 | - parameter range: The range of characters whose attributes are set. 42 | */ 43 | open func setAttributes(_ attributes: TextAttributes, range: Range) { 44 | setAttributes(attributes, range: NSRange(range)) 45 | } 46 | 47 | /** 48 | Sets the attributes for the characters in the specified range to the specified attributes. 49 | 50 | - parameter attributes: The attributes to set. 51 | - parameter range: The range of characters whose attributes are set. 52 | */ 53 | open func setAttributes(_ attributes: TextAttributes, range: NSRange) { 54 | setAttributes(attributes.dictionary, range: range) 55 | } 56 | 57 | /** 58 | Adds the given attributes. 59 | 60 | - parameter attributes: The attributes to add. 61 | */ 62 | open func addAttributes(_ attributes: TextAttributes) { 63 | addAttributes(attributes, range: NSRange(mutableString)) 64 | } 65 | 66 | /** 67 | Adds the given collection of attributes to the characters in the specified range. 68 | 69 | - parameter attributes: The attributes to add. 70 | - parameter range: he range of characters to which the specified attributes apply. 71 | */ 72 | open func addAttributes(_ attributes: TextAttributes, range: Range) { 73 | addAttributes(attributes, range: NSRange(range)) 74 | } 75 | 76 | /** 77 | Adds the given collection of attributes to the characters in the specified range. 78 | 79 | - parameter attributes: The attributes to add. 80 | - parameter range: he range of characters to which the specified attributes apply. 81 | */ 82 | open func addAttributes(_ attributes: TextAttributes, range: NSRange) { 83 | addAttributes(attributes.dictionary, range: range) 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /TextAttributes.xcodeproj/xcshareddata/xcschemes/TextAttributes OSX.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 65 | 71 | 72 | 73 | 74 | 75 | 76 | 82 | 83 | 89 | 90 | 91 | 92 | 94 | 95 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /TextAttributes.xcodeproj/xcshareddata/xcschemes/TextAttributes tvOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 65 | 71 | 72 | 73 | 74 | 75 | 76 | 82 | 83 | 89 | 90 | 91 | 92 | 94 | 95 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /Tests/TextAttributesTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TextAttributesTests.swift 3 | // 4 | // Copyright (c) 2016-2019 Damien (http://delba.io) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | import XCTest 26 | @testable import TextAttributes 27 | 28 | class TextAttributesTests: XCTestCase { 29 | let string = "The quick brown fox jumps over the lazy dog" 30 | 31 | func testSetAttributes() { 32 | let font = Font(name: "Avenir", size: 16) 33 | let color = Color(white: 0.42, alpha: 1) 34 | let ligature: LigatureStyle = .all 35 | let float: CGFloat = 0.42 36 | let underlineStyle: NSUnderlineStyle = .single 37 | let textEffect: NSAttributedString.TextEffectStyle = .letterpressStyle 38 | let form: VerticalGlyphForm = .vertical 39 | let link = URL(string: "https://github.com/delba/TextAttributes")! 40 | 41 | let attrs = TextAttributes() 42 | .font(font) 43 | .foregroundColor(color) 44 | .backgroundColor(color) 45 | .ligature(ligature) 46 | .kern(float) 47 | .strikethroughStyle(underlineStyle) 48 | .strikethroughColor(color) 49 | .underlineStyle(underlineStyle) 50 | .underlineColor(color) 51 | .strokeWidth(float) 52 | .strokeColor(color) 53 | .shadow(nil) 54 | .textEffect(textEffect) 55 | .attachment(nil) 56 | .obliqueness(float) 57 | .expansion(float) 58 | .verticalGlyphForm(form) 59 | .link(link) 60 | .baselineOffset(float) 61 | 62 | XCTAssertEqual(font, attrs.font) 63 | XCTAssertEqual(ligature, attrs.ligature) 64 | XCTAssertEqual(textEffect, attrs.textEffect) 65 | XCTAssertEqual(form, attrs.verticalGlyphForm) 66 | 67 | XCTAssertEqual(color, attrs.foregroundColor) 68 | XCTAssertEqual(color, attrs.backgroundColor) 69 | XCTAssertEqual(color, attrs.strikethroughColor) 70 | XCTAssertEqual(color, attrs.underlineColor) 71 | XCTAssertEqual(color, attrs.strokeColor) 72 | 73 | XCTAssertEqual(float, attrs.kern) 74 | XCTAssertEqual(float, attrs.obliqueness) 75 | XCTAssertEqual(float, attrs.expansion) 76 | XCTAssertEqual(float, attrs.strokeWidth) 77 | XCTAssertEqual(float, attrs.baselineOffset) 78 | 79 | XCTAssertEqual(underlineStyle, attrs.strikethroughStyle) 80 | XCTAssertEqual(underlineStyle, attrs.underlineStyle) 81 | 82 | XCTAssertEqual(link, attrs.link) 83 | 84 | XCTAssertEqual(nil, attrs.shadow) 85 | XCTAssertEqual(nil, attrs.attachment) 86 | } 87 | 88 | func testSetShadowAndAttachment() { 89 | let color = Color(white: 0.2, alpha: 1) 90 | let offset = CGSize(width: 0.42, height: 0.42) 91 | let blurRadius: CGFloat = 0.42 92 | 93 | let shadow = NSShadow() 94 | shadow.shadowColor = color 95 | shadow.shadowOffset = offset 96 | shadow.shadowBlurRadius = blurRadius 97 | 98 | let attachment = NSTextAttachment() 99 | attachment.bounds = CGRect(x: 0, y: 0, width: 42, height: 42) 100 | 101 | let attrs = TextAttributes() 102 | .shadow(shadow) 103 | .attachment(attachment) 104 | 105 | XCTAssertEqual(shadow, attrs.shadow) 106 | XCTAssertEqual(attachment, attrs.attachment) 107 | } 108 | 109 | func testSetParagraphStyle() { 110 | let style = NSMutableParagraphStyle() 111 | style.lineHeightMultiple = 1.42 112 | 113 | let attrs = TextAttributes() 114 | .paragraphStyle(style) 115 | 116 | XCTAssertEqual(style, attrs.paragraphStyle) 117 | } 118 | 119 | func testSetParagraphStyleProperties() { 120 | let float: CGFloat = 0.42 121 | 122 | let attrs = TextAttributes() 123 | .lineHeightMultiple(float) 124 | 125 | XCTAssertEqual(float, attrs.lineHeightMultiple) 126 | } 127 | 128 | func testClone() { 129 | let font = Font(name: "Avenir", size: 16) 130 | let color = Color(white: 0.42, alpha: 1) 131 | let ligature: LigatureStyle = .all 132 | let float: CGFloat = 0.42 133 | let underlineStyle: NSUnderlineStyle = .single 134 | let textEffect: NSAttributedString.TextEffectStyle = .letterpressStyle 135 | let form: VerticalGlyphForm = .vertical 136 | let link = URL(string: "https://github.com/delba/TextAttributes")! 137 | 138 | let attrs = TextAttributes() 139 | .font(font) 140 | .foregroundColor(color) 141 | .backgroundColor(color) 142 | .ligature(ligature) 143 | .kern(float) 144 | .strikethroughStyle(underlineStyle) 145 | .strikethroughColor(color) 146 | .underlineStyle(underlineStyle) 147 | .underlineColor(color) 148 | .strokeWidth(float) 149 | .strokeColor(color) 150 | .shadow(nil) 151 | .textEffect(textEffect) 152 | .attachment(nil) 153 | .obliqueness(float) 154 | .expansion(float) 155 | .verticalGlyphForm(form) 156 | .link(link) 157 | .baselineOffset(float) 158 | 159 | let second = attrs.clone() 160 | 161 | XCTAssertEqual(attrs.font, second.font) 162 | XCTAssertEqual(attrs.foregroundColor, second.foregroundColor) 163 | XCTAssertEqual(attrs.backgroundColor, second.backgroundColor) 164 | XCTAssertEqual(attrs.ligature, second.ligature) 165 | XCTAssertEqual(attrs.kern, second.kern) 166 | XCTAssertEqual(attrs.strikethroughStyle, second.strikethroughStyle) 167 | XCTAssertEqual(attrs.strikethroughColor, second.strikethroughColor) 168 | XCTAssertEqual(attrs.underlineStyle, second.underlineStyle) 169 | XCTAssertEqual(attrs.underlineColor, second.underlineColor) 170 | XCTAssertEqual(attrs.strokeWidth, second.strokeWidth) 171 | XCTAssertEqual(attrs.strokeColor, second.strokeColor) 172 | XCTAssertEqual(attrs.shadow, second.shadow) 173 | XCTAssertEqual(attrs.textEffect, second.textEffect) 174 | XCTAssertEqual(attrs.attachment, second.attachment) 175 | XCTAssertEqual(attrs.obliqueness, second.obliqueness) 176 | XCTAssertEqual(attrs.expansion, second.expansion) 177 | XCTAssertEqual(attrs.link, second.link) 178 | XCTAssertEqual(attrs.baselineOffset, second.baselineOffset) 179 | 180 | XCTAssertEqual(font, attrs.font) 181 | } 182 | 183 | func testCloneShadowAndAttachment() { 184 | let color = Color(white: 0.2, alpha: 1) 185 | let offset = CGSize(width: 0.42, height: 0.42) 186 | let blurRadius: CGFloat = 0.42 187 | 188 | let shadow = NSShadow() 189 | shadow.shadowColor = color 190 | shadow.shadowOffset = offset 191 | shadow.shadowBlurRadius = blurRadius 192 | 193 | let bounds = CGRect(x: 0, y: 0, width: 42, height: 42) 194 | 195 | let attachment = NSTextAttachment() 196 | attachment.bounds = bounds 197 | 198 | let attrs = TextAttributes() 199 | .shadow(shadow) 200 | .attachment(attachment) 201 | 202 | let clone = attrs.clone() 203 | 204 | XCTAssertEqual(attrs.shadow, clone.shadow) 205 | XCTAssertEqual(attrs.attachment, clone.attachment) 206 | 207 | clone.shadow?.shadowBlurRadius = 42 208 | clone.attachment?.bounds = .zero 209 | 210 | XCTAssertEqual(blurRadius, attrs.shadow?.shadowBlurRadius) 211 | // XCTAssertEqual(bounds, attrs.attachment?.bounds) 212 | } 213 | 214 | func testCloneParagraphStyle() { 215 | let first = TextAttributes().lineHeightMultiple(1.5) 216 | let firstStyle = first.paragraphStyle 217 | 218 | XCTAssertEqual(1.5, firstStyle.lineHeightMultiple) 219 | 220 | let second = first.clone() 221 | 222 | let secondStyle = second.paragraphStyle 223 | 224 | XCTAssertEqual(1.5, secondStyle.lineHeightMultiple) 225 | 226 | second.lineHeightMultiple = 1.4 227 | 228 | XCTAssertEqual(1.5, firstStyle.lineHeightMultiple) 229 | XCTAssertEqual(1.4, secondStyle.lineHeightMultiple) 230 | } 231 | } 232 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | 5 |

6 | Travis Status 7 | CocoaPods compatible 8 | Carthage compatible 9 | Platform 10 |

11 | 12 | **TextAttributes** makes it easy to compose attributed strings. 13 | 14 | ```swift 15 | let attrs = TextAttributes() 16 | .font(name: "HelveticaNeue", size: 16) 17 | .foregroundColor(white: 0.2, alpha: 1) 18 | .lineHeightMultiple(1.5) 19 | 20 | NSAttributedString(string: "The quick brown fox jumps over the lazy dog", attributes: attrs) 21 | ``` 22 | 23 |

24 | FeaturesUsageDemoReferencesInstallationLicense 25 |

26 | 27 | ## Features 28 | 29 | - [x] Strongly typed properties 30 | - [x] Chainable setter methods 31 | - [x] A direct access to the `NSParagraphStyle` properties 32 | - [x] Better autocompletion 33 | 34 | ## Usage 35 | 36 | - **Get or set the `TextAttributes` properties:** 37 | 38 | ```swift 39 | attrs.font = UIFont(name: "HelveticaNeue", size: 16) 40 | attrs.backgroundColor = .white 41 | ``` 42 | 43 | > See [all the properties](#references) 44 | 45 | - **Method chaining:** 46 | 47 | The `TextAttributes` methods return `Self` to allow method chaining: 48 | 49 | ```swift 50 | attrs 51 | .lineHeightMultiple(1.5) 52 | .underlineStyle(.styleSingle) 53 | ``` 54 | 55 | > See [all the methods](#references) 56 | 57 | - **The methods are also constructors:** 58 | 59 | The following are equivalent: 60 | 61 | ```swift 62 | attrs 63 | .font(name: "HelveticaNeue", size: 16) 64 | .foregroundColor(white: 0.2, alpha: 1) 65 | ``` 66 | 67 | ```swift 68 | let font = UIFont(name: "HelveticaNeue", size: 16) 69 | let color = UIColor(white: 0.2, alpha: 1) 70 | 71 | attrs 72 | .font(font) 73 | .foregroundColor(color) 74 | ``` 75 | 76 | - **Access the underlying dictionary:** 77 | 78 | ```swift 79 | attrs.dictionary // Returns the attributes dictionary of type [NSAttributedString.Key: Any] 80 | ``` 81 | 82 | #### Third-party libraries: 83 | 84 | - [muukii/**TextAttributesUtil**](https://github.com/muukii/TextAttributesUtil) Quickly create NSAttributedString with TextAttributes 85 | 86 | ## Demo 87 | 88 |

89 | 90 | Live updates with Injection for Xcode 91 |

92 | 93 | ## References 94 | 95 | ### Attributes dictionary 96 | 97 | | Dictionary Key | `TextAttributes` Property | `TextAttributes` Method | 98 | | ----------------------------------- | ------------------------- | ------------------------------------------------------ | 99 | | `NSFontAttributeName` | `font` | `font(name:size:)` | 100 | | | | `font(_:)` | 101 | | `NSParagraphStyleAttributeName` | `paragraphStyle` | `paragraphStyle(_:)` | 102 | | `NSForegroundColorAttributeName` | `foregroundColor` | `foregroundColor(_:)` | 103 | | | | `foregroundColor(white:alpha:)` | 104 | | | | `foregroundColor(hue:saturation:brightness:alpha:)` | 105 | | | | `foregroundColor(red:green:blue:alpha:)` | 106 | | | | `foregroundColor(patternImage:)` | 107 | | `NSBackgroundColorAttributeName` | `backgroundColor` | `backgroundColor(_:)` | 108 | | | | `backgroundColor(white:alpha:)` | 109 | | | | `backgroundColor(hue:saturation:brightness:alpha:)` | 110 | | | | `backgroundColor(red:green:blue:alpha:)` | 111 | | | | `backgroundColor(patternImage:)` | 112 | | `NSLigatureAttributeName` | `ligature` | `ligature(_:)` | 113 | | `NSKernAttributeName` | `kern` | `kern(_:)` | 114 | | `NSStrikethroughStyleAttributeName` | `strikethroughStyle` | `strikethroughStyle(_:)` | 115 | | `NSStrikethroughColorAttributeName` | `strikethroughColor` | `strikethroughColor(_:)` | 116 | | | | `strikethroughColor(white:alpha:)` | 117 | | | | `strikethroughColor(hue:saturation:brightness:alpha:)` | 118 | | | | `strikethroughColor(red:green:blue:alpha:)` | 119 | | | | `strikethroughColor(patternImage:)` | 120 | | `NSUnderlineStyleAttributeName` | `underlineStyle` | `underlineStyle(_:)` | 121 | | `NSUnderlineColorAttributeName` | `underlineColor` | `underlineColor(_:)` | 122 | | | | `underlineColor(white:alpha:)` | 123 | | | | `underlineColor(hue:saturation:brightness:alpha:)` | 124 | | | | `underlineColor(red:green:blue:alpha:)` | 125 | | | | `underlineColor(patternImage:)` | 126 | | `NSStrokeWidthAttributeName` | `strokeWidth` | `strokeWidth(_:)` | 127 | | `NSStrokeColorAttributeName` | `strokeColor` | `strokeColor(_:)` | 128 | | | | `strokeColor(white:alpha:)` | 129 | | | | `strokeColor(hue:saturation:brightness:alpha:)` | 130 | | | | `strokeColor(red:green:blue:alpha:)` | 131 | | | | `strokeColor(patternImage:)` | 132 | | `NSShadowAttributeName` | `shadow` | `shadow(_:)` | 133 | | | | `shadow(color:offset:blurRadius:)` | 134 | | `NSTextEffectAttributeName` | `textEffect` | `textEffect(_:)` | 135 | | `NSAttachmentAttributeName` | `attachment` | `attachment(_:)` | 136 | | `NSLinkAttributeName` | `link` | `link(_:)` | 137 | | | | `link(string:)` | 138 | | | | `link(string:relativeToURL:)` | 139 | | `NSBaselineOffsetAttributeName` | `baselineOffset` | `baselineOffset(_:)` | 140 | | `NSObliquenessAttributeName` | `obliqueness` | `obliqueness(_:)` | 141 | | `NSExpansionAttributeName` | `expansion` | `expansion(_:)` | 142 | | `NSVerticalGlyphFormAttributeName` | `verticalGlyphForm` | `verticalGlyphForm(_:)` | 143 | 144 | ### Paragraph style 145 | 146 | | `NSMutableParagraphStyle` Property | `TextAttributes` Property | `TextAttributes` Method | 147 | | ---------------------------------- | ------------------------- | ---------------------------- | 148 | | `alignment` | `alignment` | `alignment(_:)` | 149 | | `firstLineHeadIndent` | `firstLineHeadIndent` | `firstLineHeadIndent(_:)` | 150 | | `headIndent` | `headIndent` | `headIndent(_:)` | 151 | | `tailIndent` | `tailIndent` | `tailIndent(_:)` | 152 | | `lineBreakMode` | `lineBreakMode` | `lineBreakMode(_:)` | 153 | | `maximumLineHeight` | `maximumLineHeight` | `maximumLineHeight(_:)` | 154 | | `lineSpacing` | `lineSpacing` | `lineSpacing(_:)` | 155 | | `paragraphSpacing` | `paragraphSpacing` | `paragraphSpacing(_:)` | 156 | | `paragraphSpacingBefore` | `paragraphSpacingBefore` | `paragraphSpacingBefore(_:)` | 157 | | `baseWritingDirection` | `baseWritingDirection` | `baseWritingDirection(_:)` | 158 | | `lineHeightMultiple` | `lineHeightMultiple` | `lineHeightMultiple(_:)` | 159 | 160 | ## Installation 161 | 162 | ### Carthage 163 | 164 | [Carthage](https://github.com/Carthage/Carthage) is a decentralized dependency manager that automates the process of adding frameworks to your Cocoa application. 165 | 166 | You can install Carthage with [Homebrew](http://brew.sh/) using the following command: 167 | 168 | ```bash 169 | $ brew update 170 | $ brew install carthage 171 | ``` 172 | 173 | To integrate TextAttributes into your Xcode project using Carthage, specify it in your `Cartfile`: 174 | 175 | ```ogdl 176 | github "delba/TextAttributes" 177 | ``` 178 | 179 | ### Cocoapods 180 | 181 | [CocoaPods](http://cocoapods.org) is a dependency manager for Cocoa projects. 182 | 183 | You can install it with the following command: 184 | 185 | ```bash 186 | $ gem install cocoapods 187 | ``` 188 | 189 | To integrate TextAttributes into your Xcode project using CocoaPods, specify it in your `Podfile`: 190 | 191 | ```ruby 192 | use_frameworks! 193 | 194 | pod 'TextAttributes' 195 | ``` 196 | 197 | ## License 198 | 199 | Copyright (c) 2016-2019 Damien (http://delba.io) 200 | 201 | Permission is hereby granted, free of charge, to any person obtaining a copy 202 | of this software and associated documentation files (the "Software"), to deal 203 | in the Software without restriction, including without limitation the rights 204 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 205 | copies of the Software, and to permit persons to whom the Software is 206 | furnished to do so, subject to the following conditions: 207 | 208 | The above copyright notice and this permission notice shall be included in all 209 | copies or substantial portions of the Software. 210 | 211 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 212 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 213 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 214 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 215 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 216 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 217 | SOFTWARE. 218 | -------------------------------------------------------------------------------- /Source/TextAttributes.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TextAttributes.swift 3 | // 4 | // Copyright (c) 2016-2019 Damien (http://delba.io) 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in all 14 | // copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | // 24 | 25 | #if canImport(UIKit) 26 | import UIKit 27 | #elseif canImport(AppKit) 28 | import AppKit 29 | #endif 30 | 31 | public enum LigatureStyle { 32 | case none 33 | case `default` 34 | case all 35 | } 36 | 37 | public enum VerticalGlyphForm { 38 | case horizontal 39 | case vertical 40 | } 41 | 42 | open class TextAttributes { 43 | /// The attributes dictionary. 44 | open private(set) var dictionary: [NSAttributedString.Key: Any] = [:] 45 | 46 | /** 47 | Create an instance of TextAttributes. 48 | 49 | - returns: The created TextAttributes. 50 | */ 51 | public init() { 52 | dictionary[.paragraphStyle] = paragraphStyle 53 | } 54 | 55 | /** 56 | Creates a copy of the receiver. 57 | 58 | - returns: A copy of the receiver. 59 | */ 60 | open func clone() -> TextAttributes { 61 | let clone = TextAttributes() 62 | 63 | clone.dictionary = dictionary 64 | 65 | #if !os(watchOS) 66 | if let shadow = shadow?.copy() as? NSShadow { 67 | clone.shadow = shadow 68 | } 69 | 70 | clone.attachment = attachment 71 | 72 | clone.paragraphStyle = paragraphStyle.clone() 73 | #endif 74 | 75 | return clone 76 | } 77 | 78 | // MARK: - Font 79 | 80 | /// The font attribute. 81 | open var font: Font? { 82 | get { 83 | return dictionary[.font] as? Font 84 | } 85 | set { 86 | dictionary[.font] = newValue 87 | } 88 | } 89 | 90 | /** 91 | Sets the font attribute and returns the receiver. 92 | 93 | - parameter name: The fully specified name of the font. 94 | - parameter size: The size (in points) to which the font is scaled. 95 | 96 | - returns: The receiver. 97 | */ 98 | @discardableResult 99 | open func font(name: String, size: CGFloat) -> Self { 100 | return font(Font(name: name, size: size)) 101 | } 102 | 103 | /** 104 | Sets the font attribute and returns the receiver. 105 | 106 | - parameter font: The font. 107 | 108 | - returns: The receiver. 109 | */ 110 | @discardableResult 111 | open func font(_ font: Font?) -> Self { 112 | self.font = font 113 | return self 114 | } 115 | 116 | // MARK: - Ligature 117 | 118 | /// The ligature attribute. 119 | open var ligature: LigatureStyle { 120 | get { 121 | return dictionary[.ligature] as? LigatureStyle ?? .default 122 | } 123 | set { 124 | dictionary[.ligature] = newValue 125 | } 126 | } 127 | 128 | /** 129 | Sets the ligature attribute and returns the receiver. 130 | 131 | - parameter style: The ligature style. 132 | 133 | - returns: The receiver. 134 | */ 135 | @discardableResult 136 | open func ligature(_ style: LigatureStyle) -> Self { 137 | self.ligature = style 138 | return self 139 | } 140 | 141 | // MARK: - Kern 142 | 143 | /// The number of points by which to adjust kern-pair characters. 144 | open var kern: CGFloat { 145 | get { 146 | return dictionary[.kern] as? CGFloat ?? 0 147 | } 148 | set { 149 | dictionary[.kern] = newValue 150 | } 151 | } 152 | 153 | /** 154 | Sets the number of points by which to adjust kern-pair characters and returns the receiver. 155 | 156 | - parameter value: The number of points by which to adjust kern-pair characters. 157 | 158 | - returns: The receiver. 159 | */ 160 | @discardableResult 161 | open func kern(_ value: CGFloat) -> Self { 162 | self.kern = value 163 | return self 164 | } 165 | 166 | // MARK: - Striketrough style 167 | 168 | /// The strikethrough style attribute. 169 | open var strikethroughStyle: NSUnderlineStyle { 170 | get { 171 | guard let rawValue = dictionary[.strikethroughStyle] as? Int else { return [] } 172 | return NSUnderlineStyle(rawValue: rawValue) 173 | } 174 | set { 175 | dictionary[.strikethroughStyle] = newValue.rawValue 176 | } 177 | } 178 | 179 | /** 180 | Sets the strikethrough style attribute and returns the receiver. 181 | 182 | - parameter style: The strikethrough style. 183 | 184 | - returns: The receiver. 185 | */ 186 | @discardableResult 187 | open func strikethroughStyle(_ style: NSUnderlineStyle) -> Self { 188 | self.strikethroughStyle = style 189 | return self 190 | } 191 | 192 | // MARK: - Strikethrough color 193 | 194 | /// The strikethrough color attribute. 195 | var strikethroughColor: Color? { 196 | get { 197 | return dictionary[.strikethroughColor] as? Color 198 | } 199 | set { 200 | dictionary[.strikethroughColor] = newValue 201 | } 202 | } 203 | 204 | /** 205 | Sets the strikethrough color attribute and returns the receiver. 206 | 207 | - parameter white: The grayscale value of the color object. 208 | - parameter alpha: The opacity value of the color object. 209 | 210 | - returns: The receiver. 211 | */ 212 | @discardableResult 213 | open func strikethroughColor(white: CGFloat, alpha: CGFloat) -> Self { 214 | return strikethroughColor(Color(white: white, alpha: alpha)) 215 | } 216 | 217 | /** 218 | Sets the strikethrough color attribute and returns the receiver. 219 | 220 | - parameter hue: The hue component of the color object. 221 | - parameter saturation: The saturation component of the color object. 222 | - parameter brightness: The brightness component of the color object. 223 | - parameter alpha: The opacity value of the color object. 224 | 225 | - returns: The receiver. 226 | */ 227 | @discardableResult 228 | open func strikethroughColor(hue: CGFloat, saturation: CGFloat, brightness: CGFloat, alpha: CGFloat) -> Self { 229 | return strikethroughColor(Color(hue: hue, saturation: saturation, brightness: brightness, alpha: alpha)) 230 | } 231 | 232 | /** 233 | Sets the strikethrough color attribute and returns the receiver. 234 | 235 | - parameter red: The red component of the color object. 236 | - parameter green: The green component of the color object. 237 | - parameter blue: The blue component of the color object. 238 | - parameter alpha: The opacity value of the color object. 239 | 240 | - returns: The receiver. 241 | */ 242 | @discardableResult 243 | open func strikethroughColor(red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) -> Self { 244 | return strikethroughColor(Color(red: red, green: green, blue: blue, alpha: alpha)) 245 | } 246 | 247 | /** 248 | Sets the strikethrough color attribute and returns the receiver. 249 | 250 | - parameter image: The image to use when creating the pattern color. 251 | 252 | - returns: The receiver. 253 | */ 254 | @discardableResult 255 | open func strikethroughColor(patternImage image: Image) -> Self { 256 | return strikethroughColor(Color(patternImage: image)) 257 | } 258 | 259 | /** 260 | Sets the strikethrough color attribute and returns the receiver. 261 | 262 | - parameter color: The color. 263 | 264 | - returns: The receiver. 265 | */ 266 | @discardableResult 267 | open func strikethroughColor(_ color: Color?) -> Self { 268 | self.strikethroughColor = color 269 | return self 270 | } 271 | 272 | // MARK: - Underline style 273 | 274 | /// The underline style attribute. 275 | open var underlineStyle: NSUnderlineStyle { 276 | get { 277 | guard let rawValue = dictionary[.underlineStyle] as? Int else { return [] } 278 | return NSUnderlineStyle(rawValue: rawValue) 279 | } 280 | set { 281 | dictionary[.underlineStyle] = newValue.rawValue 282 | } 283 | } 284 | 285 | /** 286 | Sets the underline style attribute and returns the receiver. 287 | 288 | - parameter style: The underline style. 289 | 290 | - returns: The receiver. 291 | */ 292 | @discardableResult 293 | open func underlineStyle(_ style: NSUnderlineStyle) -> Self { 294 | self.underlineStyle = style 295 | return self 296 | } 297 | 298 | // MARK: - Underline color 299 | 300 | /// The underline color attribute. 301 | open var underlineColor: Color? { 302 | get { 303 | return dictionary[.underlineColor] as? Color 304 | } 305 | set { 306 | dictionary[.underlineColor] = newValue 307 | } 308 | } 309 | 310 | /** 311 | Sets the underline color attribute and returns the receiver. 312 | 313 | - parameter white: The grayscale value of the color object. 314 | - parameter alpha: The opacity value of the color object. 315 | 316 | - returns: The receiver. 317 | */ 318 | @discardableResult 319 | open func underlineColor(white: CGFloat, alpha: CGFloat) -> Self { 320 | return underlineColor(Color(white: white, alpha: alpha)) 321 | } 322 | 323 | /** 324 | Sets the underline color attribute and returns the receiver. 325 | 326 | - parameter hue: The hue component of the color object. 327 | - parameter saturation: The saturation component of the color object. 328 | - parameter brightness: The brightness component of the color object. 329 | - parameter alpha: The opacity value of the color object. 330 | 331 | - returns: The receiver. 332 | */ 333 | @discardableResult 334 | open func underlineColor(hue: CGFloat, saturation: CGFloat, brightness: CGFloat, alpha: CGFloat) -> Self { 335 | return underlineColor(Color(hue: hue, saturation: saturation, brightness: brightness, alpha: alpha)) 336 | } 337 | 338 | /** 339 | Sets the underline color attribute and returns the receiver. 340 | 341 | - parameter red: The red component of the color object. 342 | - parameter green: The green component of the color object. 343 | - parameter blue: The blue component of the color object. 344 | - parameter alpha: The opacity value of the color object. 345 | 346 | - returns: The receiver. 347 | */ 348 | @discardableResult 349 | open func underlineColor(red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) -> Self { 350 | return underlineColor(Color(red: red, green: green, blue: blue, alpha: alpha)) 351 | } 352 | 353 | /** 354 | Sets the underline color attribute and returns the receiver. 355 | 356 | - parameter image: The image to use when creating the pattern color. 357 | 358 | - returns: The receiver. 359 | */ 360 | @discardableResult 361 | open func underlineColor(patternImage image: Image) -> Self { 362 | return underlineColor(Color(patternImage: image)) 363 | } 364 | 365 | /** 366 | Sets the underline color attribute and returns the receiver. 367 | 368 | - parameter color: The color. 369 | 370 | - returns: The receiver. 371 | */ 372 | @discardableResult 373 | open func underlineColor(_ color: Color?) -> Self { 374 | self.underlineColor = color 375 | return self 376 | } 377 | 378 | // MARK: - Stroke color 379 | 380 | /// The stroke color attribute. 381 | open var strokeColor: Color? { 382 | get { 383 | return dictionary[.strokeColor] as? Color 384 | } 385 | set { 386 | dictionary[.strokeColor] = newValue 387 | } 388 | } 389 | 390 | /** 391 | Sets the stroke color attribute and returns the receiver. 392 | 393 | - parameter white: The grayscale value of the color object. 394 | - parameter alpha: The opacity value of the color object. 395 | 396 | - returns: The receiver. 397 | */ 398 | @discardableResult 399 | open func strokeColor(white: CGFloat, alpha: CGFloat) -> Self { 400 | return strokeColor(Color(white: white, alpha: alpha)) 401 | } 402 | 403 | /** 404 | Sets the stroke color attribute and returns the receiver. 405 | 406 | - parameter hue: The hue component of the color object. 407 | - parameter saturation: The saturation component of the color object. 408 | - parameter brightness: The brightness component of the color object. 409 | - parameter alpha: The opacity value of the color object. 410 | 411 | - returns: The receiver. 412 | */ 413 | @discardableResult 414 | open func strokeColor(hue: CGFloat, saturation: CGFloat, brightness: CGFloat, alpha: CGFloat) -> Self { 415 | return strokeColor(Color(hue: hue, saturation: saturation, brightness: brightness, alpha: alpha)) 416 | } 417 | 418 | /** 419 | Sets the stroke color attribute and returns the receiver. 420 | 421 | - parameter red: The red component of the color object. 422 | - parameter green: The green component of the color object. 423 | - parameter blue: The blue component of the color object. 424 | - parameter alpha: The opacity value of the color object. 425 | 426 | - returns: The receiver. 427 | */ 428 | @discardableResult 429 | open func strokeColor(red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) -> Self { 430 | return strokeColor(Color(red: red, green: green, blue: blue, alpha: alpha)) 431 | } 432 | 433 | /** 434 | Sets the stroke color attribute and returns the receiver. 435 | 436 | - parameter image: The image to use when creating the pattern color. 437 | 438 | - returns: The receiver. 439 | */ 440 | @discardableResult 441 | open func strokeColor(patternImage image: Image) -> Self { 442 | return strokeColor(Color(patternImage: image)) 443 | } 444 | 445 | /** 446 | Sets the underline color attribute and returns the receiver. 447 | 448 | - parameter color: The color. 449 | 450 | - returns: The receiver. 451 | */ 452 | @discardableResult 453 | open func strokeColor(_ color: Color?) -> Self { 454 | self.strokeColor = color 455 | return self 456 | } 457 | 458 | // MARK: - Stroke width 459 | 460 | /// The stroke width attribute. 461 | open var strokeWidth: CGFloat { 462 | get { 463 | return dictionary[.strokeWidth] as? CGFloat ?? 0 464 | } 465 | set { 466 | dictionary[.strokeWidth] = newValue 467 | } 468 | } 469 | 470 | /** 471 | Sets the stroke width attribute and returns the receiver. 472 | 473 | - parameter width: The stroke width. 474 | 475 | - returns: The receiver. 476 | */ 477 | @discardableResult 478 | open func strokeWidth(_ width: CGFloat) -> Self { 479 | self.strokeWidth = width 480 | return self 481 | } 482 | 483 | // MARK: - Foreground color 484 | 485 | /// The foreground color attribute. 486 | open var foregroundColor: Color? { 487 | get { 488 | return dictionary[.foregroundColor] as? Color 489 | } 490 | set { 491 | dictionary[.foregroundColor] = newValue 492 | } 493 | } 494 | 495 | /** 496 | Sets the foreground color attribute and returns the receiver. 497 | 498 | - parameter white: The grayscale value of the color object. 499 | - parameter alpha: The opacity value of the color object. 500 | 501 | - returns: The receiver. 502 | */ 503 | @discardableResult 504 | open func foregroundColor(white: CGFloat, alpha: CGFloat) -> Self { 505 | return foregroundColor(Color(white: white, alpha: alpha)) 506 | } 507 | 508 | /** 509 | Sets the foreground color attribute and returns the receiver. 510 | 511 | - parameter hue: The hue component of the color object. 512 | - parameter saturation: The saturation component of the color object. 513 | - parameter brightness: The brightness component of the color object. 514 | - parameter alpha: The opacity value of the color object. 515 | 516 | - returns: The receiver. 517 | */ 518 | @discardableResult 519 | open func foregroundColor(hue: CGFloat, saturation: CGFloat, brightness: CGFloat, alpha: CGFloat) -> Self { 520 | return foregroundColor(Color(hue: hue, saturation: saturation, brightness: brightness, alpha: alpha)) 521 | } 522 | 523 | /** 524 | Sets the foreground color attribute and returns the receiver. 525 | 526 | - parameter red: The red component of the color object. 527 | - parameter green: The green component of the color object. 528 | - parameter blue: The blue component of the color object. 529 | - parameter alpha: The opacity value of the color object. 530 | 531 | - returns: The receiver. 532 | */ 533 | @discardableResult 534 | open func foregroundColor(red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) -> Self { 535 | return foregroundColor(Color(red: red, green: green, blue: blue, alpha: alpha)) 536 | } 537 | 538 | /** 539 | Sets the foreground color attribute and returns the receiver. 540 | 541 | - parameter image: The image to use when creating the pattern color. 542 | 543 | - returns: The receiver. 544 | */ 545 | @discardableResult 546 | open func foregroundColor(patternImage image: Image) -> Self { 547 | return foregroundColor(Color(patternImage: image)) 548 | } 549 | 550 | /** 551 | Sets the foreground color attribute and returns the receiver. 552 | 553 | - parameter color: The color. 554 | 555 | - returns: The receiver. 556 | */ 557 | @discardableResult 558 | open func foregroundColor(_ color: Color?) -> Self { 559 | self.foregroundColor = color 560 | return self 561 | } 562 | 563 | // MARK: - TextEffect 564 | 565 | /// The text effect attribute. 566 | open var textEffect: NSAttributedString.TextEffectStyle? { 567 | get { 568 | return dictionary[.textEffect] as? NSAttributedString.TextEffectStyle 569 | } 570 | set { 571 | dictionary[.textEffect] = newValue 572 | } 573 | } 574 | 575 | /** 576 | Sets the text effect attribute and returns the receiver. 577 | 578 | - parameter style: The text effect. 579 | 580 | - returns: The receiver. 581 | */ 582 | @discardableResult 583 | open func textEffect(_ style: NSAttributedString.TextEffectStyle?) -> Self { 584 | self.textEffect = style 585 | return self 586 | } 587 | 588 | // MARK: - Link 589 | 590 | /// The link attribute. 591 | open var link: URL? { 592 | get { 593 | return dictionary[.link] as? URL 594 | } 595 | set { 596 | dictionary[.link] = newValue 597 | } 598 | } 599 | 600 | /** 601 | Sets the link attribute and returns the receiver. 602 | 603 | - parameter string: The URL string with which to initialize the NSURL object. 604 | 605 | - returns: The receiver. 606 | */ 607 | @discardableResult 608 | open func link(string: String) -> Self { 609 | return link(URL(string: string)) 610 | } 611 | 612 | /** 613 | Sets the link attribute and returns the receiver. 614 | 615 | - parameter string: The URL string with which to initialize the NSURL object. 616 | - parameter baseURL: The base URL for the NSURL object. 617 | 618 | - returns: The receiver. 619 | */ 620 | @discardableResult 621 | open func link(string: String, relativeToURL baseURL: URL) -> Self { 622 | return link(URL(string: string, relativeTo: baseURL)) 623 | } 624 | 625 | /** 626 | Sets the link attribute and returns the receiver. 627 | 628 | - parameter URL: The URL. 629 | 630 | - returns: The receiver. 631 | */ 632 | @discardableResult 633 | open func link(_ URL: URL?) -> Self { 634 | self.link = URL 635 | return self 636 | } 637 | 638 | // MARK: - Baseline offset 639 | 640 | /// The baseline offset attribute. 641 | open var baselineOffset: CGFloat { 642 | get { 643 | return dictionary[.baselineOffset] as? CGFloat ?? 0 644 | } 645 | set { 646 | dictionary[.baselineOffset] = newValue 647 | } 648 | } 649 | 650 | /** 651 | Sets the baseline offset attribute and return the receiver. 652 | 653 | - parameter value: The baseline offset. 654 | 655 | - returns: The receiver. 656 | */ 657 | @discardableResult 658 | open func baselineOffset(_ value: CGFloat) -> Self { 659 | self.baselineOffset = value 660 | return self 661 | } 662 | 663 | // MARK: - Obliqueness 664 | 665 | /// The obliqueness attribute. 666 | open var obliqueness: CGFloat { 667 | get { 668 | return dictionary[.obliqueness] as? CGFloat ?? 0 669 | } 670 | set { 671 | dictionary[.obliqueness] = newValue 672 | } 673 | } 674 | 675 | /** 676 | Sets the obliqueness attribute and returns the receiver. 677 | 678 | - parameter value: The obliqueness. 679 | 680 | - returns: The receiver. 681 | */ 682 | @discardableResult 683 | open func obliqueness(_ value: CGFloat) -> Self { 684 | self.obliqueness = value 685 | return self 686 | } 687 | 688 | // MARK: - Expansion 689 | 690 | /// The expansion attribute. 691 | open var expansion: CGFloat { 692 | get { 693 | return dictionary[.expansion] as? CGFloat ?? 0 694 | } 695 | set { 696 | dictionary[.expansion] = newValue 697 | } 698 | } 699 | 700 | /** 701 | Sets the expansion attribute and returns the receiver. 702 | 703 | - parameter value: The expansion attribute. 704 | 705 | - returns: The receiver. 706 | */ 707 | @discardableResult 708 | open func expansion(_ value: CGFloat) -> Self { 709 | self.expansion = value 710 | return self 711 | } 712 | 713 | // MARK: - Vertical glyph form 714 | 715 | /// The vertical glyph form attribute. 716 | open var verticalGlyphForm: VerticalGlyphForm { 717 | get { 718 | return dictionary[.verticalGlyphForm] as? VerticalGlyphForm ?? .horizontal 719 | } 720 | set { 721 | dictionary[.verticalGlyphForm] = newValue 722 | } 723 | } 724 | 725 | /** 726 | Sets the vertical glyph form attribute and returns the receiver. 727 | 728 | - parameter value: The vertical glyph form. 729 | 730 | - returns: The receiver. 731 | */ 732 | @discardableResult 733 | open func verticalGlyphForm(_ value: VerticalGlyphForm) -> Self { 734 | self.verticalGlyphForm = value 735 | return self 736 | } 737 | 738 | // MARK: - Background color 739 | 740 | /// The background color attribute. 741 | var backgroundColor: Color? { 742 | get { 743 | return dictionary[.backgroundColor] as? Color 744 | } 745 | set { 746 | dictionary[.backgroundColor] = newValue 747 | } 748 | } 749 | 750 | /** 751 | Sets the background color attribute and returns the receiver. 752 | 753 | - parameter white: The grayscale value of the color object. 754 | - parameter alpha: The opacity value of the color object. 755 | 756 | - returns: The receiver. 757 | */ 758 | @discardableResult 759 | open func backgroundColor(white: CGFloat, alpha: CGFloat) -> Self { 760 | return backgroundColor(Color(white: white, alpha: alpha)) 761 | } 762 | 763 | /** 764 | Sets the background color attribute and returns the receiver. 765 | 766 | - parameter hue: The hue component of the color object. 767 | - parameter saturation: The saturation component of the color object. 768 | - parameter brightness: The brightness component of the color object. 769 | - parameter alpha: The opacity value of the color object. 770 | 771 | - returns: The receiver. 772 | */ 773 | @discardableResult 774 | open func backgroundColor(hue: CGFloat, saturation: CGFloat, brightness: CGFloat, alpha: CGFloat) -> Self { 775 | return backgroundColor(Color(hue: hue, saturation: saturation, brightness: brightness, alpha: alpha)) 776 | } 777 | 778 | /** 779 | Sets the background color attribute and returns the receiver. 780 | 781 | - parameter red: The red component of the color object. 782 | - parameter green: The green component of the color object. 783 | - parameter blue: The blue component of the color object. 784 | - parameter alpha: The opacity value of the color object. 785 | 786 | - returns: The receiver. 787 | */ 788 | @discardableResult 789 | open func backgroundColor(red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) -> Self { 790 | return backgroundColor(Color(red: red, green: green, blue: blue, alpha: alpha)) 791 | } 792 | 793 | /** 794 | Sets the background color attribute and returns the receiver. 795 | 796 | - parameter image: The image to use when creating the pattern color. 797 | 798 | - returns: The receiver. 799 | */ 800 | @discardableResult 801 | open func backgroundColor(patternImage image: Image) -> Self { 802 | return backgroundColor(Color(patternImage: image)) 803 | } 804 | 805 | /** 806 | Sets the background color attribute and returns the receiver. 807 | 808 | - parameter color: The color. 809 | 810 | - returns: The receiver. 811 | */ 812 | @discardableResult 813 | open func backgroundColor(_ color: Color?) -> Self { 814 | self.backgroundColor = color 815 | return self 816 | } 817 | 818 | // MARK: - Paragraph style 819 | 820 | /// The paragraph style attribute. 821 | open var paragraphStyle: NSMutableParagraphStyle = NSMutableParagraphStyle() { 822 | didSet { 823 | dictionary[.paragraphStyle] = paragraphStyle 824 | } 825 | } 826 | 827 | /** 828 | Sets the paragraph style attribute and returns the receiver. 829 | 830 | - parameter style: The paragraph style. 831 | 832 | - returns: The receiver. 833 | */ 834 | @discardableResult 835 | open func paragraphStyle(_ style: NSMutableParagraphStyle) -> Self { 836 | self.paragraphStyle = style 837 | return self 838 | } 839 | 840 | // MARK: - Alignment 841 | 842 | /// The text alignment of the paragraph style. 843 | open var alignment: NSTextAlignment { 844 | get { return paragraphStyle.alignment } 845 | set { paragraphStyle.alignment = newValue } 846 | } 847 | 848 | /** 849 | Sets the text alignment of the paragraph style and returns the receiver. 850 | 851 | - parameter alignment: The text alignment. 852 | 853 | - returns: The receiver. 854 | */ 855 | @discardableResult 856 | open func alignment(_ alignment: NSTextAlignment) -> Self { 857 | self.alignment = alignment 858 | return self 859 | } 860 | 861 | // MARK: - First line head indent 862 | 863 | /// The indentation of the first line of the paragraph style. 864 | open var firstLineHeadIndent: CGFloat { 865 | get { return paragraphStyle.firstLineHeadIndent } 866 | set { paragraphStyle.firstLineHeadIndent = newValue } 867 | } 868 | 869 | /** 870 | Sets the indentation of the first line of the paragraph style and returns the receiver. 871 | 872 | - parameter value: The indentation. 873 | 874 | - returns: The receiver. 875 | */ 876 | @discardableResult 877 | open func firstLineHeadIndent(_ value: CGFloat) -> Self { 878 | self.firstLineHeadIndent = value 879 | return self 880 | } 881 | 882 | // MARK: - Head indent 883 | 884 | /// The indentation of the paragraph style lines other than the first. 885 | open var headIndent: CGFloat { 886 | get { return paragraphStyle.headIndent } 887 | set { paragraphStyle.headIndent = newValue } 888 | } 889 | 890 | /** 891 | Sets the indentation of the paragraph style lines other than the first and returns the receiver. 892 | 893 | - parameter value: The indentation of the lines other than the first. 894 | 895 | - returns: The receiver. 896 | */ 897 | @discardableResult 898 | open func headIndent(_ value: CGFloat) -> Self { 899 | self.headIndent = value 900 | return self 901 | } 902 | 903 | // MARK: - Tail indent 904 | 905 | /// The trailing indentation of the paragraph style. 906 | open var tailIndent: CGFloat { 907 | get { return paragraphStyle.tailIndent } 908 | set { paragraphStyle.tailIndent = newValue } 909 | } 910 | 911 | /** 912 | Sets the trailing indentation of the paragraph style and returns the receiver. 913 | 914 | - parameter value: The trailing indentation. 915 | 916 | - returns: The receiver. 917 | */ 918 | @discardableResult 919 | open func tailIndent(_ value: CGFloat) -> Self { 920 | self.tailIndent = value 921 | return self 922 | } 923 | 924 | // MARK: - Line height multiple 925 | 926 | /// The line height multiple of the paragraph style. 927 | open var lineHeightMultiple: CGFloat { 928 | get { return paragraphStyle.lineHeightMultiple } 929 | set { paragraphStyle.lineHeightMultiple = newValue } 930 | } 931 | 932 | /** 933 | Sets the line height multiple of the paragraph style and returns the receiver. 934 | 935 | - parameter value: The line height multiple. 936 | 937 | - returns: The receiver. 938 | */ 939 | @discardableResult 940 | open func lineHeightMultiple(_ value: CGFloat) -> Self { 941 | self.lineHeightMultiple = value 942 | return self 943 | } 944 | 945 | // MARK: - Maximum line height 946 | 947 | /// The maximum line height of the paragraph style. 948 | open var maximumLineHeight: CGFloat { 949 | get { return paragraphStyle.maximumLineHeight } 950 | set { paragraphStyle.maximumLineHeight = newValue } 951 | } 952 | 953 | /** 954 | Sets the maximum line height of the paragraph style and returns the receiver. 955 | 956 | - parameter value: The maximum line height. 957 | 958 | - returns: The receiver. 959 | */ 960 | @discardableResult 961 | open func maximumLineHeight(_ value: CGFloat) -> Self { 962 | self.maximumLineHeight = value 963 | return self 964 | } 965 | 966 | // MARK: - Minimum line height 967 | 968 | /// The minimum line height of the paragraph style. 969 | open var minimumLineHeight: CGFloat { 970 | get { return paragraphStyle.minimumLineHeight } 971 | set { paragraphStyle.minimumLineHeight = newValue } 972 | } 973 | 974 | /** 975 | Sets the minimum line height of the paragraph style and returns the receiver. 976 | 977 | - parameter value: The minimum line height. 978 | 979 | - returns: The receiver. 980 | */ 981 | @discardableResult 982 | open func minimumLineHeight(_ value: CGFloat) -> Self { 983 | self.minimumLineHeight = value 984 | return self 985 | } 986 | 987 | // MARK: - Line spacing 988 | 989 | /// The line spacing of the paragraph style. 990 | open var lineSpacing: CGFloat { 991 | get { return paragraphStyle.lineSpacing } 992 | set { paragraphStyle.lineSpacing = newValue } 993 | } 994 | 995 | /** 996 | Sets the line spacing of the paragraph style and returns the receiver. 997 | 998 | - parameter value: The line spacing. 999 | 1000 | - returns: The receiver. 1001 | */ 1002 | @discardableResult 1003 | open func lineSpacing(_ value: CGFloat) -> Self { 1004 | self.lineSpacing = value 1005 | return self 1006 | } 1007 | 1008 | // MARK: - Paragraph spacing 1009 | 1010 | /// The paragraph spacing of the paragraph style. 1011 | open var paragraphSpacing: CGFloat { 1012 | get { return paragraphStyle.paragraphSpacing } 1013 | set { paragraphStyle.paragraphSpacing = newValue } 1014 | } 1015 | 1016 | /** 1017 | Sets the paragraph spacing of the paragraph style and returns the receiver. 1018 | 1019 | - parameter value: The paragraph spacing. 1020 | 1021 | - returns: The receiver. 1022 | */ 1023 | @discardableResult 1024 | open func paragraphSpacing(_ value: CGFloat) -> Self { 1025 | self.paragraphSpacing = value 1026 | return self 1027 | } 1028 | 1029 | // MARK: - Paragraph spacing before 1030 | 1031 | /// The distance between the paragraph's top and the beginning of its text content. 1032 | open var paragraphSpacingBefore: CGFloat { 1033 | get { return paragraphStyle.paragraphSpacingBefore } 1034 | set { paragraphStyle.paragraphSpacingBefore = newValue } 1035 | } 1036 | 1037 | /** 1038 | Sets the distance between the paragraph's top and the beginning of its text content and returns the receiver. 1039 | 1040 | - parameter value: The distance between the paragraph's top and the beginning of its text content. 1041 | 1042 | - returns: The receiver. 1043 | */ 1044 | @discardableResult 1045 | open func paragraphSpacingBefore(_ value: CGFloat) -> Self { 1046 | self.paragraphSpacingBefore = value 1047 | return self 1048 | } 1049 | 1050 | // MARK: - Line Break Mode 1051 | 1052 | /// The mode that should be used to break lines. 1053 | open var lineBreakMode: NSLineBreakMode { 1054 | get { return paragraphStyle.lineBreakMode } 1055 | set { paragraphStyle.lineBreakMode = newValue } 1056 | } 1057 | 1058 | /** 1059 | Sets the mode that should be used to break lines and returns the receiver. 1060 | 1061 | - parameter value: The mode that should be used to break lines. 1062 | 1063 | - returns: The receiver. 1064 | */ 1065 | @discardableResult 1066 | open func lineBreakMode(_ value: NSLineBreakMode) -> Self { 1067 | self.lineBreakMode = value 1068 | return self 1069 | } 1070 | } 1071 | 1072 | #if !os(watchOS) 1073 | extension TextAttributes { 1074 | // MARK: - Shadow 1075 | 1076 | /// The shadow attribute. 1077 | open var shadow: NSShadow? { 1078 | get { 1079 | return dictionary[.shadow] as? NSShadow 1080 | } 1081 | set { 1082 | dictionary[.shadow] = newValue 1083 | } 1084 | } 1085 | 1086 | #if os(OSX) 1087 | /** 1088 | Sets the shadow attribute and returns the receiver. 1089 | 1090 | - parameter color: The color of the shadow. 1091 | - parameter offset: The offset values of the shadow. 1092 | - parameter blurRadius: The blur radius of the shadow. 1093 | 1094 | - returns: The receiver. 1095 | */ 1096 | @discardableResult 1097 | open func shadow(color: NSColor?, offset: CGSize, blurRadius: CGFloat) -> Self { 1098 | return shadow({ 1099 | let shadow = NSShadow() 1100 | shadow.shadowColor = color 1101 | shadow.shadowOffset = offset 1102 | shadow.shadowBlurRadius = blurRadius 1103 | return shadow 1104 | }() as NSShadow) 1105 | } 1106 | #else 1107 | /** 1108 | Sets the shadow attribute and returns the receiver. 1109 | 1110 | - parameter color: The color of the shadow. 1111 | - parameter offset: The offset values of the shadow. 1112 | - parameter blurRadius: The blur radius of the shadow. 1113 | 1114 | - returns: The receiver. 1115 | */ 1116 | @discardableResult 1117 | open func shadow(color: AnyObject?, offset: CGSize, blurRadius: CGFloat) -> Self { 1118 | return shadow({ 1119 | let shadow = NSShadow() 1120 | shadow.shadowColor = color 1121 | shadow.shadowOffset = offset 1122 | shadow.shadowBlurRadius = blurRadius 1123 | return shadow 1124 | }() as NSShadow) 1125 | } 1126 | #endif 1127 | 1128 | /** 1129 | Sets the shadow attribute and returns the receiver. 1130 | 1131 | - parameter shadow: The shadow. 1132 | 1133 | - returns: The receiver. 1134 | */ 1135 | @discardableResult 1136 | open func shadow(_ shadow: NSShadow?) -> Self { 1137 | self.shadow = shadow 1138 | return self 1139 | } 1140 | 1141 | // MARK: - Attachment 1142 | 1143 | /// The attachment attribute. 1144 | open var attachment: NSTextAttachment? { 1145 | get { 1146 | return dictionary[.attachment] as? NSTextAttachment 1147 | } 1148 | set { 1149 | dictionary[.attachment] = newValue 1150 | } 1151 | } 1152 | 1153 | /** 1154 | Sets the attachment attribute and returns the receiver. 1155 | 1156 | - parameter attachment: The text attachment. 1157 | 1158 | - returns: The receiver. 1159 | */ 1160 | @discardableResult 1161 | open func attachment(_ attachment: NSTextAttachment?) -> Self { 1162 | self.attachment = attachment 1163 | return self 1164 | } 1165 | } 1166 | #endif 1167 | -------------------------------------------------------------------------------- /TextAttributes.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 6D24753B1CAAB1050044D223 /* TextAttributes.h in Headers */ = {isa = PBXBuildFile; fileRef = 6D24753A1CAAB1050044D223 /* TextAttributes.h */; settings = {ATTRIBUTES = (Public, ); }; }; 11 | 6D2475421CAAB1050044D223 /* TextAttributes.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D2475371CAAB1050044D223 /* TextAttributes.framework */; }; 12 | 6D2475471CAAB1050044D223 /* TextAttributesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D2475461CAAB1050044D223 /* TextAttributesTests.swift */; }; 13 | 6D2475521CAAB1140044D223 /* TextAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D2475511CAAB1140044D223 /* TextAttributes.swift */; }; 14 | 6DB519801CCA8189005C3E83 /* TextAttributes.h in Headers */ = {isa = PBXBuildFile; fileRef = 6D24753A1CAAB1050044D223 /* TextAttributes.h */; settings = {ATTRIBUTES = (Public, ); }; }; 15 | 6DB519811CCA8195005C3E83 /* Utilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DB8402C1CB1F398002AB94E /* Utilities.swift */; }; 16 | 6DB519861CCA8AD9005C3E83 /* TextAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D2475511CAAB1140044D223 /* TextAttributes.swift */; }; 17 | 6DB519961CCA8CEF005C3E83 /* TextAttributes.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6DB5198C1CCA8CEF005C3E83 /* TextAttributes.framework */; }; 18 | 6DB519A31CCA8D8F005C3E83 /* TextAttributes.h in Headers */ = {isa = PBXBuildFile; fileRef = 6D24753A1CAAB1050044D223 /* TextAttributes.h */; settings = {ATTRIBUTES = (Public, ); }; }; 19 | 6DB519C91CCA90FB005C3E83 /* TextAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D2475511CAAB1140044D223 /* TextAttributes.swift */; }; 20 | 6DB519CA1CCA9101005C3E83 /* Utilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DB8402C1CB1F398002AB94E /* Utilities.swift */; }; 21 | 6DB519CC1CCA9107005C3E83 /* TextAttributesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D2475461CAAB1050044D223 /* TextAttributesTests.swift */; }; 22 | 6DB8402D1CB1F398002AB94E /* Utilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DB8402C1CB1F398002AB94E /* Utilities.swift */; }; 23 | 6DDF4E3A1CD1260B002AA459 /* TextAttributes.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6DDF4E301CD1260A002AA459 /* TextAttributes.framework */; }; 24 | 6DDF4E471CD203A3002AA459 /* TextAttributes.h in Headers */ = {isa = PBXBuildFile; fileRef = 6D24753A1CAAB1050044D223 /* TextAttributes.h */; settings = {ATTRIBUTES = (Public, ); }; }; 25 | 6DDF4E481CD20452002AA459 /* TextAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D2475511CAAB1140044D223 /* TextAttributes.swift */; }; 26 | 6DDF4E4A1CD2045A002AA459 /* Utilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DB8402C1CB1F398002AB94E /* Utilities.swift */; }; 27 | 6DDF4E4B1CD20817002AA459 /* TextAttributesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D2475461CAAB1050044D223 /* TextAttributesTests.swift */; }; 28 | 8474276E230876DD007A7922 /* NSRange+TextAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8474276D230876DD007A7922 /* NSRange+TextAttributes.swift */; }; 29 | 84742770230876F7007A7922 /* NSMutableParagraphStyle+TextAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8474276F230876F7007A7922 /* NSMutableParagraphStyle+TextAttributes.swift */; }; 30 | 847427722308770B007A7922 /* NSAttributedString+TextAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847427712308770B007A7922 /* NSAttributedString+TextAttributes.swift */; }; 31 | 847427742308772D007A7922 /* NSMutableAttributedString+TextAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847427732308772D007A7922 /* NSMutableAttributedString+TextAttributes.swift */; }; 32 | 8474277523087735007A7922 /* NSRange+TextAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8474276D230876DD007A7922 /* NSRange+TextAttributes.swift */; }; 33 | 8474277623087736007A7922 /* NSRange+TextAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8474276D230876DD007A7922 /* NSRange+TextAttributes.swift */; }; 34 | 8474277723087737007A7922 /* NSRange+TextAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8474276D230876DD007A7922 /* NSRange+TextAttributes.swift */; }; 35 | 847427782308773B007A7922 /* NSMutableParagraphStyle+TextAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8474276F230876F7007A7922 /* NSMutableParagraphStyle+TextAttributes.swift */; }; 36 | 847427792308773D007A7922 /* NSMutableParagraphStyle+TextAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8474276F230876F7007A7922 /* NSMutableParagraphStyle+TextAttributes.swift */; }; 37 | 8474277A2308773E007A7922 /* NSMutableParagraphStyle+TextAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8474276F230876F7007A7922 /* NSMutableParagraphStyle+TextAttributes.swift */; }; 38 | 8474277B23087742007A7922 /* NSAttributedString+TextAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847427712308770B007A7922 /* NSAttributedString+TextAttributes.swift */; }; 39 | 8474277C23087743007A7922 /* NSAttributedString+TextAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847427712308770B007A7922 /* NSAttributedString+TextAttributes.swift */; }; 40 | 8474277D23087745007A7922 /* NSAttributedString+TextAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847427712308770B007A7922 /* NSAttributedString+TextAttributes.swift */; }; 41 | 8474277E23087748007A7922 /* NSMutableAttributedString+TextAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847427732308772D007A7922 /* NSMutableAttributedString+TextAttributes.swift */; }; 42 | 8474277F23087749007A7922 /* NSMutableAttributedString+TextAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847427732308772D007A7922 /* NSMutableAttributedString+TextAttributes.swift */; }; 43 | 847427802308774B007A7922 /* NSMutableAttributedString+TextAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 847427732308772D007A7922 /* NSMutableAttributedString+TextAttributes.swift */; }; 44 | /* End PBXBuildFile section */ 45 | 46 | /* Begin PBXContainerItemProxy section */ 47 | 6D2475431CAAB1050044D223 /* PBXContainerItemProxy */ = { 48 | isa = PBXContainerItemProxy; 49 | containerPortal = 6D24752E1CAAB1050044D223 /* Project object */; 50 | proxyType = 1; 51 | remoteGlobalIDString = 6D2475361CAAB1050044D223; 52 | remoteInfo = TextAttributes; 53 | }; 54 | 6DB519971CCA8CEF005C3E83 /* PBXContainerItemProxy */ = { 55 | isa = PBXContainerItemProxy; 56 | containerPortal = 6D24752E1CAAB1050044D223 /* Project object */; 57 | proxyType = 1; 58 | remoteGlobalIDString = 6DB5198B1CCA8CEF005C3E83; 59 | remoteInfo = "TextAttributes tvOS"; 60 | }; 61 | 6DDF4E3B1CD1260B002AA459 /* PBXContainerItemProxy */ = { 62 | isa = PBXContainerItemProxy; 63 | containerPortal = 6D24752E1CAAB1050044D223 /* Project object */; 64 | proxyType = 1; 65 | remoteGlobalIDString = 6DDF4E2F1CD1260A002AA459; 66 | remoteInfo = TextAttributes; 67 | }; 68 | /* End PBXContainerItemProxy section */ 69 | 70 | /* Begin PBXFileReference section */ 71 | 6D2475371CAAB1050044D223 /* TextAttributes.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TextAttributes.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 72 | 6D24753A1CAAB1050044D223 /* TextAttributes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TextAttributes.h; sourceTree = ""; }; 73 | 6D24753C1CAAB1050044D223 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 74 | 6D2475411CAAB1050044D223 /* TextAttributes iOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "TextAttributes iOS Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 75 | 6D2475461CAAB1050044D223 /* TextAttributesTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextAttributesTests.swift; sourceTree = ""; }; 76 | 6D2475481CAAB1050044D223 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 77 | 6D2475511CAAB1140044D223 /* TextAttributes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextAttributes.swift; sourceTree = ""; }; 78 | 6DB519781CCA7F30005C3E83 /* TextAttributes.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TextAttributes.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 79 | 6DB5198C1CCA8CEF005C3E83 /* TextAttributes.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TextAttributes.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 80 | 6DB519951CCA8CEF005C3E83 /* TextAttributes tvOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "TextAttributes tvOS Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 81 | 6DB8402C1CB1F398002AB94E /* Utilities.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Utilities.swift; sourceTree = ""; }; 82 | 6DDF4E301CD1260A002AA459 /* TextAttributes.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TextAttributes.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 83 | 6DDF4E391CD1260B002AA459 /* TextAttributes OSX Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "TextAttributes OSX Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 84 | 8474276D230876DD007A7922 /* NSRange+TextAttributes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSRange+TextAttributes.swift"; sourceTree = ""; }; 85 | 8474276F230876F7007A7922 /* NSMutableParagraphStyle+TextAttributes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSMutableParagraphStyle+TextAttributes.swift"; sourceTree = ""; }; 86 | 847427712308770B007A7922 /* NSAttributedString+TextAttributes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSAttributedString+TextAttributes.swift"; sourceTree = ""; }; 87 | 847427732308772D007A7922 /* NSMutableAttributedString+TextAttributes.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSMutableAttributedString+TextAttributes.swift"; sourceTree = ""; }; 88 | /* End PBXFileReference section */ 89 | 90 | /* Begin PBXFrameworksBuildPhase section */ 91 | 6D2475331CAAB1050044D223 /* Frameworks */ = { 92 | isa = PBXFrameworksBuildPhase; 93 | buildActionMask = 2147483647; 94 | files = ( 95 | ); 96 | runOnlyForDeploymentPostprocessing = 0; 97 | }; 98 | 6D24753E1CAAB1050044D223 /* Frameworks */ = { 99 | isa = PBXFrameworksBuildPhase; 100 | buildActionMask = 2147483647; 101 | files = ( 102 | 6D2475421CAAB1050044D223 /* TextAttributes.framework in Frameworks */, 103 | ); 104 | runOnlyForDeploymentPostprocessing = 0; 105 | }; 106 | 6DB519741CCA7F30005C3E83 /* Frameworks */ = { 107 | isa = PBXFrameworksBuildPhase; 108 | buildActionMask = 2147483647; 109 | files = ( 110 | ); 111 | runOnlyForDeploymentPostprocessing = 0; 112 | }; 113 | 6DB519881CCA8CEF005C3E83 /* Frameworks */ = { 114 | isa = PBXFrameworksBuildPhase; 115 | buildActionMask = 2147483647; 116 | files = ( 117 | ); 118 | runOnlyForDeploymentPostprocessing = 0; 119 | }; 120 | 6DB519921CCA8CEF005C3E83 /* Frameworks */ = { 121 | isa = PBXFrameworksBuildPhase; 122 | buildActionMask = 2147483647; 123 | files = ( 124 | 6DB519961CCA8CEF005C3E83 /* TextAttributes.framework in Frameworks */, 125 | ); 126 | runOnlyForDeploymentPostprocessing = 0; 127 | }; 128 | 6DDF4E2C1CD1260A002AA459 /* Frameworks */ = { 129 | isa = PBXFrameworksBuildPhase; 130 | buildActionMask = 2147483647; 131 | files = ( 132 | ); 133 | runOnlyForDeploymentPostprocessing = 0; 134 | }; 135 | 6DDF4E361CD1260B002AA459 /* Frameworks */ = { 136 | isa = PBXFrameworksBuildPhase; 137 | buildActionMask = 2147483647; 138 | files = ( 139 | 6DDF4E3A1CD1260B002AA459 /* TextAttributes.framework in Frameworks */, 140 | ); 141 | runOnlyForDeploymentPostprocessing = 0; 142 | }; 143 | /* End PBXFrameworksBuildPhase section */ 144 | 145 | /* Begin PBXGroup section */ 146 | 6D24752D1CAAB1050044D223 = { 147 | isa = PBXGroup; 148 | children = ( 149 | 6D2475381CAAB1050044D223 /* Products */, 150 | 6D2475391CAAB1050044D223 /* Source */, 151 | 6D2475451CAAB1050044D223 /* Tests */, 152 | ); 153 | indentWidth = 4; 154 | sourceTree = ""; 155 | tabWidth = 4; 156 | }; 157 | 6D2475381CAAB1050044D223 /* Products */ = { 158 | isa = PBXGroup; 159 | children = ( 160 | 6D2475371CAAB1050044D223 /* TextAttributes.framework */, 161 | 6D2475411CAAB1050044D223 /* TextAttributes iOS Tests.xctest */, 162 | 6DB519781CCA7F30005C3E83 /* TextAttributes.framework */, 163 | 6DB5198C1CCA8CEF005C3E83 /* TextAttributes.framework */, 164 | 6DB519951CCA8CEF005C3E83 /* TextAttributes tvOS Tests.xctest */, 165 | 6DDF4E301CD1260A002AA459 /* TextAttributes.framework */, 166 | 6DDF4E391CD1260B002AA459 /* TextAttributes OSX Tests.xctest */, 167 | ); 168 | name = Products; 169 | sourceTree = ""; 170 | }; 171 | 6D2475391CAAB1050044D223 /* Source */ = { 172 | isa = PBXGroup; 173 | children = ( 174 | 8474276C230876C8007A7922 /* Extensions */, 175 | 6D5F82CF1CADCD2300237532 /* Supporting Files */, 176 | 6D2475511CAAB1140044D223 /* TextAttributes.swift */, 177 | ); 178 | path = Source; 179 | sourceTree = ""; 180 | }; 181 | 6D2475451CAAB1050044D223 /* Tests */ = { 182 | isa = PBXGroup; 183 | children = ( 184 | 6D5F82D01CADCD3400237532 /* Supporting Files */, 185 | 6D2475461CAAB1050044D223 /* TextAttributesTests.swift */, 186 | ); 187 | path = Tests; 188 | sourceTree = ""; 189 | }; 190 | 6D5F82CF1CADCD2300237532 /* Supporting Files */ = { 191 | isa = PBXGroup; 192 | children = ( 193 | 6D24753C1CAAB1050044D223 /* Info.plist */, 194 | 6D24753A1CAAB1050044D223 /* TextAttributes.h */, 195 | 6DB8402C1CB1F398002AB94E /* Utilities.swift */, 196 | ); 197 | path = "Supporting Files"; 198 | sourceTree = ""; 199 | }; 200 | 6D5F82D01CADCD3400237532 /* Supporting Files */ = { 201 | isa = PBXGroup; 202 | children = ( 203 | 6D2475481CAAB1050044D223 /* Info.plist */, 204 | ); 205 | path = "Supporting Files"; 206 | sourceTree = ""; 207 | }; 208 | 8474276C230876C8007A7922 /* Extensions */ = { 209 | isa = PBXGroup; 210 | children = ( 211 | 847427712308770B007A7922 /* NSAttributedString+TextAttributes.swift */, 212 | 847427732308772D007A7922 /* NSMutableAttributedString+TextAttributes.swift */, 213 | 8474276F230876F7007A7922 /* NSMutableParagraphStyle+TextAttributes.swift */, 214 | 8474276D230876DD007A7922 /* NSRange+TextAttributes.swift */, 215 | ); 216 | path = Extensions; 217 | sourceTree = ""; 218 | }; 219 | /* End PBXGroup section */ 220 | 221 | /* Begin PBXHeadersBuildPhase section */ 222 | 6D2475341CAAB1050044D223 /* Headers */ = { 223 | isa = PBXHeadersBuildPhase; 224 | buildActionMask = 2147483647; 225 | files = ( 226 | 6D24753B1CAAB1050044D223 /* TextAttributes.h in Headers */, 227 | ); 228 | runOnlyForDeploymentPostprocessing = 0; 229 | }; 230 | 6DB519751CCA7F30005C3E83 /* Headers */ = { 231 | isa = PBXHeadersBuildPhase; 232 | buildActionMask = 2147483647; 233 | files = ( 234 | 6DB519801CCA8189005C3E83 /* TextAttributes.h in Headers */, 235 | ); 236 | runOnlyForDeploymentPostprocessing = 0; 237 | }; 238 | 6DB519891CCA8CEF005C3E83 /* Headers */ = { 239 | isa = PBXHeadersBuildPhase; 240 | buildActionMask = 2147483647; 241 | files = ( 242 | 6DB519A31CCA8D8F005C3E83 /* TextAttributes.h in Headers */, 243 | ); 244 | runOnlyForDeploymentPostprocessing = 0; 245 | }; 246 | 6DDF4E2D1CD1260A002AA459 /* Headers */ = { 247 | isa = PBXHeadersBuildPhase; 248 | buildActionMask = 2147483647; 249 | files = ( 250 | 6DDF4E471CD203A3002AA459 /* TextAttributes.h in Headers */, 251 | ); 252 | runOnlyForDeploymentPostprocessing = 0; 253 | }; 254 | /* End PBXHeadersBuildPhase section */ 255 | 256 | /* Begin PBXNativeTarget section */ 257 | 6D2475361CAAB1050044D223 /* TextAttributes iOS */ = { 258 | isa = PBXNativeTarget; 259 | buildConfigurationList = 6D24754B1CAAB1050044D223 /* Build configuration list for PBXNativeTarget "TextAttributes iOS" */; 260 | buildPhases = ( 261 | 6D2475321CAAB1050044D223 /* Sources */, 262 | 6D2475331CAAB1050044D223 /* Frameworks */, 263 | 6D2475341CAAB1050044D223 /* Headers */, 264 | 6D2475351CAAB1050044D223 /* Resources */, 265 | ); 266 | buildRules = ( 267 | ); 268 | dependencies = ( 269 | ); 270 | name = "TextAttributes iOS"; 271 | productName = TextAttributes; 272 | productReference = 6D2475371CAAB1050044D223 /* TextAttributes.framework */; 273 | productType = "com.apple.product-type.framework"; 274 | }; 275 | 6D2475401CAAB1050044D223 /* TextAttributes iOS Tests */ = { 276 | isa = PBXNativeTarget; 277 | buildConfigurationList = 6D24754E1CAAB1050044D223 /* Build configuration list for PBXNativeTarget "TextAttributes iOS Tests" */; 278 | buildPhases = ( 279 | 6D24753D1CAAB1050044D223 /* Sources */, 280 | 6D24753E1CAAB1050044D223 /* Frameworks */, 281 | 6D24753F1CAAB1050044D223 /* Resources */, 282 | ); 283 | buildRules = ( 284 | ); 285 | dependencies = ( 286 | 6D2475441CAAB1050044D223 /* PBXTargetDependency */, 287 | ); 288 | name = "TextAttributes iOS Tests"; 289 | productName = TextAttributesTests; 290 | productReference = 6D2475411CAAB1050044D223 /* TextAttributes iOS Tests.xctest */; 291 | productType = "com.apple.product-type.bundle.unit-test"; 292 | }; 293 | 6DB519771CCA7F30005C3E83 /* TextAttributes watchOS */ = { 294 | isa = PBXNativeTarget; 295 | buildConfigurationList = 6DB5197F1CCA7F31005C3E83 /* Build configuration list for PBXNativeTarget "TextAttributes watchOS" */; 296 | buildPhases = ( 297 | 6DB519731CCA7F30005C3E83 /* Sources */, 298 | 6DB519741CCA7F30005C3E83 /* Frameworks */, 299 | 6DB519751CCA7F30005C3E83 /* Headers */, 300 | 6DB519761CCA7F30005C3E83 /* Resources */, 301 | ); 302 | buildRules = ( 303 | ); 304 | dependencies = ( 305 | ); 306 | name = "TextAttributes watchOS"; 307 | productName = "TextAttributes watchOS"; 308 | productReference = 6DB519781CCA7F30005C3E83 /* TextAttributes.framework */; 309 | productType = "com.apple.product-type.framework"; 310 | }; 311 | 6DB5198B1CCA8CEF005C3E83 /* TextAttributes tvOS */ = { 312 | isa = PBXNativeTarget; 313 | buildConfigurationList = 6DB519A11CCA8CEF005C3E83 /* Build configuration list for PBXNativeTarget "TextAttributes tvOS" */; 314 | buildPhases = ( 315 | 6DB519871CCA8CEF005C3E83 /* Sources */, 316 | 6DB519881CCA8CEF005C3E83 /* Frameworks */, 317 | 6DB519891CCA8CEF005C3E83 /* Headers */, 318 | 6DB5198A1CCA8CEF005C3E83 /* Resources */, 319 | ); 320 | buildRules = ( 321 | ); 322 | dependencies = ( 323 | ); 324 | name = "TextAttributes tvOS"; 325 | productName = "TextAttributes tvOS"; 326 | productReference = 6DB5198C1CCA8CEF005C3E83 /* TextAttributes.framework */; 327 | productType = "com.apple.product-type.framework"; 328 | }; 329 | 6DB519941CCA8CEF005C3E83 /* TextAttributes tvOS Tests */ = { 330 | isa = PBXNativeTarget; 331 | buildConfigurationList = 6DB519A21CCA8CEF005C3E83 /* Build configuration list for PBXNativeTarget "TextAttributes tvOS Tests" */; 332 | buildPhases = ( 333 | 6DB519911CCA8CEF005C3E83 /* Sources */, 334 | 6DB519921CCA8CEF005C3E83 /* Frameworks */, 335 | 6DB519931CCA8CEF005C3E83 /* Resources */, 336 | ); 337 | buildRules = ( 338 | ); 339 | dependencies = ( 340 | 6DB519981CCA8CEF005C3E83 /* PBXTargetDependency */, 341 | ); 342 | name = "TextAttributes tvOS Tests"; 343 | productName = "TextAttributes tvOSTests"; 344 | productReference = 6DB519951CCA8CEF005C3E83 /* TextAttributes tvOS Tests.xctest */; 345 | productType = "com.apple.product-type.bundle.unit-test"; 346 | }; 347 | 6DDF4E2F1CD1260A002AA459 /* TextAttributes OSX */ = { 348 | isa = PBXNativeTarget; 349 | buildConfigurationList = 6DDF4E451CD1260B002AA459 /* Build configuration list for PBXNativeTarget "TextAttributes OSX" */; 350 | buildPhases = ( 351 | 6DDF4E2B1CD1260A002AA459 /* Sources */, 352 | 6DDF4E2C1CD1260A002AA459 /* Frameworks */, 353 | 6DDF4E2D1CD1260A002AA459 /* Headers */, 354 | 6DDF4E2E1CD1260A002AA459 /* Resources */, 355 | ); 356 | buildRules = ( 357 | ); 358 | dependencies = ( 359 | ); 360 | name = "TextAttributes OSX"; 361 | productName = TextAttributes; 362 | productReference = 6DDF4E301CD1260A002AA459 /* TextAttributes.framework */; 363 | productType = "com.apple.product-type.framework"; 364 | }; 365 | 6DDF4E381CD1260B002AA459 /* TextAttributes OSX Tests */ = { 366 | isa = PBXNativeTarget; 367 | buildConfigurationList = 6DDF4E461CD1260B002AA459 /* Build configuration list for PBXNativeTarget "TextAttributes OSX Tests" */; 368 | buildPhases = ( 369 | 6DDF4E351CD1260B002AA459 /* Sources */, 370 | 6DDF4E361CD1260B002AA459 /* Frameworks */, 371 | 6DDF4E371CD1260B002AA459 /* Resources */, 372 | ); 373 | buildRules = ( 374 | ); 375 | dependencies = ( 376 | 6DDF4E3C1CD1260B002AA459 /* PBXTargetDependency */, 377 | ); 378 | name = "TextAttributes OSX Tests"; 379 | productName = TextAttributesTests; 380 | productReference = 6DDF4E391CD1260B002AA459 /* TextAttributes OSX Tests.xctest */; 381 | productType = "com.apple.product-type.bundle.unit-test"; 382 | }; 383 | /* End PBXNativeTarget section */ 384 | 385 | /* Begin PBXProject section */ 386 | 6D24752E1CAAB1050044D223 /* Project object */ = { 387 | isa = PBXProject; 388 | attributes = { 389 | LastSwiftUpdateCheck = 0730; 390 | LastUpgradeCheck = 1030; 391 | ORGANIZATIONNAME = delba; 392 | TargetAttributes = { 393 | 6D2475361CAAB1050044D223 = { 394 | CreatedOnToolsVersion = 7.2; 395 | LastSwiftMigration = 0800; 396 | }; 397 | 6D2475401CAAB1050044D223 = { 398 | CreatedOnToolsVersion = 7.2; 399 | }; 400 | 6DB519771CCA7F30005C3E83 = { 401 | CreatedOnToolsVersion = 7.3; 402 | }; 403 | 6DB5198B1CCA8CEF005C3E83 = { 404 | CreatedOnToolsVersion = 7.3; 405 | }; 406 | 6DB519941CCA8CEF005C3E83 = { 407 | CreatedOnToolsVersion = 7.3; 408 | }; 409 | 6DDF4E2F1CD1260A002AA459 = { 410 | CreatedOnToolsVersion = 7.3; 411 | LastSwiftMigration = 0800; 412 | }; 413 | 6DDF4E381CD1260B002AA459 = { 414 | CreatedOnToolsVersion = 7.3; 415 | LastSwiftMigration = 0800; 416 | }; 417 | }; 418 | }; 419 | buildConfigurationList = 6D2475311CAAB1050044D223 /* Build configuration list for PBXProject "TextAttributes" */; 420 | compatibilityVersion = "Xcode 3.2"; 421 | developmentRegion = en; 422 | hasScannedForEncodings = 0; 423 | knownRegions = ( 424 | en, 425 | Base, 426 | ); 427 | mainGroup = 6D24752D1CAAB1050044D223; 428 | productRefGroup = 6D2475381CAAB1050044D223 /* Products */; 429 | projectDirPath = ""; 430 | projectRoot = ""; 431 | targets = ( 432 | 6D2475361CAAB1050044D223 /* TextAttributes iOS */, 433 | 6D2475401CAAB1050044D223 /* TextAttributes iOS Tests */, 434 | 6DB5198B1CCA8CEF005C3E83 /* TextAttributes tvOS */, 435 | 6DB519941CCA8CEF005C3E83 /* TextAttributes tvOS Tests */, 436 | 6DDF4E2F1CD1260A002AA459 /* TextAttributes OSX */, 437 | 6DDF4E381CD1260B002AA459 /* TextAttributes OSX Tests */, 438 | 6DB519771CCA7F30005C3E83 /* TextAttributes watchOS */, 439 | ); 440 | }; 441 | /* End PBXProject section */ 442 | 443 | /* Begin PBXResourcesBuildPhase section */ 444 | 6D2475351CAAB1050044D223 /* Resources */ = { 445 | isa = PBXResourcesBuildPhase; 446 | buildActionMask = 2147483647; 447 | files = ( 448 | ); 449 | runOnlyForDeploymentPostprocessing = 0; 450 | }; 451 | 6D24753F1CAAB1050044D223 /* Resources */ = { 452 | isa = PBXResourcesBuildPhase; 453 | buildActionMask = 2147483647; 454 | files = ( 455 | ); 456 | runOnlyForDeploymentPostprocessing = 0; 457 | }; 458 | 6DB519761CCA7F30005C3E83 /* Resources */ = { 459 | isa = PBXResourcesBuildPhase; 460 | buildActionMask = 2147483647; 461 | files = ( 462 | ); 463 | runOnlyForDeploymentPostprocessing = 0; 464 | }; 465 | 6DB5198A1CCA8CEF005C3E83 /* Resources */ = { 466 | isa = PBXResourcesBuildPhase; 467 | buildActionMask = 2147483647; 468 | files = ( 469 | ); 470 | runOnlyForDeploymentPostprocessing = 0; 471 | }; 472 | 6DB519931CCA8CEF005C3E83 /* Resources */ = { 473 | isa = PBXResourcesBuildPhase; 474 | buildActionMask = 2147483647; 475 | files = ( 476 | ); 477 | runOnlyForDeploymentPostprocessing = 0; 478 | }; 479 | 6DDF4E2E1CD1260A002AA459 /* Resources */ = { 480 | isa = PBXResourcesBuildPhase; 481 | buildActionMask = 2147483647; 482 | files = ( 483 | ); 484 | runOnlyForDeploymentPostprocessing = 0; 485 | }; 486 | 6DDF4E371CD1260B002AA459 /* Resources */ = { 487 | isa = PBXResourcesBuildPhase; 488 | buildActionMask = 2147483647; 489 | files = ( 490 | ); 491 | runOnlyForDeploymentPostprocessing = 0; 492 | }; 493 | /* End PBXResourcesBuildPhase section */ 494 | 495 | /* Begin PBXSourcesBuildPhase section */ 496 | 6D2475321CAAB1050044D223 /* Sources */ = { 497 | isa = PBXSourcesBuildPhase; 498 | buildActionMask = 2147483647; 499 | files = ( 500 | 847427742308772D007A7922 /* NSMutableAttributedString+TextAttributes.swift in Sources */, 501 | 8474276E230876DD007A7922 /* NSRange+TextAttributes.swift in Sources */, 502 | 6D2475521CAAB1140044D223 /* TextAttributes.swift in Sources */, 503 | 84742770230876F7007A7922 /* NSMutableParagraphStyle+TextAttributes.swift in Sources */, 504 | 6DB8402D1CB1F398002AB94E /* Utilities.swift in Sources */, 505 | 847427722308770B007A7922 /* NSAttributedString+TextAttributes.swift in Sources */, 506 | ); 507 | runOnlyForDeploymentPostprocessing = 0; 508 | }; 509 | 6D24753D1CAAB1050044D223 /* Sources */ = { 510 | isa = PBXSourcesBuildPhase; 511 | buildActionMask = 2147483647; 512 | files = ( 513 | 6D2475471CAAB1050044D223 /* TextAttributesTests.swift in Sources */, 514 | ); 515 | runOnlyForDeploymentPostprocessing = 0; 516 | }; 517 | 6DB519731CCA7F30005C3E83 /* Sources */ = { 518 | isa = PBXSourcesBuildPhase; 519 | buildActionMask = 2147483647; 520 | files = ( 521 | 847427802308774B007A7922 /* NSMutableAttributedString+TextAttributes.swift in Sources */, 522 | 8474277723087737007A7922 /* NSRange+TextAttributes.swift in Sources */, 523 | 6DB519811CCA8195005C3E83 /* Utilities.swift in Sources */, 524 | 8474277A2308773E007A7922 /* NSMutableParagraphStyle+TextAttributes.swift in Sources */, 525 | 6DB519861CCA8AD9005C3E83 /* TextAttributes.swift in Sources */, 526 | 8474277D23087745007A7922 /* NSAttributedString+TextAttributes.swift in Sources */, 527 | ); 528 | runOnlyForDeploymentPostprocessing = 0; 529 | }; 530 | 6DB519871CCA8CEF005C3E83 /* Sources */ = { 531 | isa = PBXSourcesBuildPhase; 532 | buildActionMask = 2147483647; 533 | files = ( 534 | 8474277E23087748007A7922 /* NSMutableAttributedString+TextAttributes.swift in Sources */, 535 | 8474277523087735007A7922 /* NSRange+TextAttributes.swift in Sources */, 536 | 6DB519CA1CCA9101005C3E83 /* Utilities.swift in Sources */, 537 | 847427782308773B007A7922 /* NSMutableParagraphStyle+TextAttributes.swift in Sources */, 538 | 6DB519C91CCA90FB005C3E83 /* TextAttributes.swift in Sources */, 539 | 8474277B23087742007A7922 /* NSAttributedString+TextAttributes.swift in Sources */, 540 | ); 541 | runOnlyForDeploymentPostprocessing = 0; 542 | }; 543 | 6DB519911CCA8CEF005C3E83 /* Sources */ = { 544 | isa = PBXSourcesBuildPhase; 545 | buildActionMask = 2147483647; 546 | files = ( 547 | 6DB519CC1CCA9107005C3E83 /* TextAttributesTests.swift in Sources */, 548 | ); 549 | runOnlyForDeploymentPostprocessing = 0; 550 | }; 551 | 6DDF4E2B1CD1260A002AA459 /* Sources */ = { 552 | isa = PBXSourcesBuildPhase; 553 | buildActionMask = 2147483647; 554 | files = ( 555 | 8474277F23087749007A7922 /* NSMutableAttributedString+TextAttributes.swift in Sources */, 556 | 8474277623087736007A7922 /* NSRange+TextAttributes.swift in Sources */, 557 | 6DDF4E4A1CD2045A002AA459 /* Utilities.swift in Sources */, 558 | 847427792308773D007A7922 /* NSMutableParagraphStyle+TextAttributes.swift in Sources */, 559 | 6DDF4E481CD20452002AA459 /* TextAttributes.swift in Sources */, 560 | 8474277C23087743007A7922 /* NSAttributedString+TextAttributes.swift in Sources */, 561 | ); 562 | runOnlyForDeploymentPostprocessing = 0; 563 | }; 564 | 6DDF4E351CD1260B002AA459 /* Sources */ = { 565 | isa = PBXSourcesBuildPhase; 566 | buildActionMask = 2147483647; 567 | files = ( 568 | 6DDF4E4B1CD20817002AA459 /* TextAttributesTests.swift in Sources */, 569 | ); 570 | runOnlyForDeploymentPostprocessing = 0; 571 | }; 572 | /* End PBXSourcesBuildPhase section */ 573 | 574 | /* Begin PBXTargetDependency section */ 575 | 6D2475441CAAB1050044D223 /* PBXTargetDependency */ = { 576 | isa = PBXTargetDependency; 577 | target = 6D2475361CAAB1050044D223 /* TextAttributes iOS */; 578 | targetProxy = 6D2475431CAAB1050044D223 /* PBXContainerItemProxy */; 579 | }; 580 | 6DB519981CCA8CEF005C3E83 /* PBXTargetDependency */ = { 581 | isa = PBXTargetDependency; 582 | target = 6DB5198B1CCA8CEF005C3E83 /* TextAttributes tvOS */; 583 | targetProxy = 6DB519971CCA8CEF005C3E83 /* PBXContainerItemProxy */; 584 | }; 585 | 6DDF4E3C1CD1260B002AA459 /* PBXTargetDependency */ = { 586 | isa = PBXTargetDependency; 587 | target = 6DDF4E2F1CD1260A002AA459 /* TextAttributes OSX */; 588 | targetProxy = 6DDF4E3B1CD1260B002AA459 /* PBXContainerItemProxy */; 589 | }; 590 | /* End PBXTargetDependency section */ 591 | 592 | /* Begin XCBuildConfiguration section */ 593 | 6D2475491CAAB1050044D223 /* Debug */ = { 594 | isa = XCBuildConfiguration; 595 | buildSettings = { 596 | ALWAYS_SEARCH_USER_PATHS = NO; 597 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 598 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 599 | CLANG_CXX_LIBRARY = "libc++"; 600 | CLANG_ENABLE_MODULES = YES; 601 | CLANG_ENABLE_OBJC_ARC = YES; 602 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 603 | CLANG_WARN_BOOL_CONVERSION = YES; 604 | CLANG_WARN_COMMA = YES; 605 | CLANG_WARN_CONSTANT_CONVERSION = YES; 606 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 607 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 608 | CLANG_WARN_EMPTY_BODY = YES; 609 | CLANG_WARN_ENUM_CONVERSION = YES; 610 | CLANG_WARN_INFINITE_RECURSION = YES; 611 | CLANG_WARN_INT_CONVERSION = YES; 612 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 613 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 614 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 615 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 616 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 617 | CLANG_WARN_STRICT_PROTOTYPES = YES; 618 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 619 | CLANG_WARN_UNREACHABLE_CODE = YES; 620 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 621 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 622 | COPY_PHASE_STRIP = NO; 623 | CURRENT_PROJECT_VERSION = 1; 624 | DEBUG_INFORMATION_FORMAT = dwarf; 625 | ENABLE_STRICT_OBJC_MSGSEND = YES; 626 | ENABLE_TESTABILITY = YES; 627 | GCC_C_LANGUAGE_STANDARD = gnu99; 628 | GCC_DYNAMIC_NO_PIC = NO; 629 | GCC_NO_COMMON_BLOCKS = YES; 630 | GCC_OPTIMIZATION_LEVEL = 0; 631 | GCC_PREPROCESSOR_DEFINITIONS = ( 632 | "DEBUG=1", 633 | "$(inherited)", 634 | ); 635 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 636 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 637 | GCC_WARN_UNDECLARED_SELECTOR = YES; 638 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 639 | GCC_WARN_UNUSED_FUNCTION = YES; 640 | GCC_WARN_UNUSED_VARIABLE = YES; 641 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 642 | MTL_ENABLE_DEBUG_INFO = YES; 643 | ONLY_ACTIVE_ARCH = YES; 644 | SDKROOT = iphoneos; 645 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 646 | SWIFT_VERSION = 5.0; 647 | TARGETED_DEVICE_FAMILY = "1,2"; 648 | VERSIONING_SYSTEM = "apple-generic"; 649 | VERSION_INFO_PREFIX = ""; 650 | }; 651 | name = Debug; 652 | }; 653 | 6D24754A1CAAB1050044D223 /* Release */ = { 654 | isa = XCBuildConfiguration; 655 | buildSettings = { 656 | ALWAYS_SEARCH_USER_PATHS = NO; 657 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 658 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 659 | CLANG_CXX_LIBRARY = "libc++"; 660 | CLANG_ENABLE_MODULES = YES; 661 | CLANG_ENABLE_OBJC_ARC = YES; 662 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 663 | CLANG_WARN_BOOL_CONVERSION = YES; 664 | CLANG_WARN_COMMA = YES; 665 | CLANG_WARN_CONSTANT_CONVERSION = YES; 666 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 667 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 668 | CLANG_WARN_EMPTY_BODY = YES; 669 | CLANG_WARN_ENUM_CONVERSION = YES; 670 | CLANG_WARN_INFINITE_RECURSION = YES; 671 | CLANG_WARN_INT_CONVERSION = YES; 672 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 673 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 674 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 675 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 676 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 677 | CLANG_WARN_STRICT_PROTOTYPES = YES; 678 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 679 | CLANG_WARN_UNREACHABLE_CODE = YES; 680 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 681 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 682 | COPY_PHASE_STRIP = NO; 683 | CURRENT_PROJECT_VERSION = 1; 684 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 685 | ENABLE_NS_ASSERTIONS = NO; 686 | ENABLE_STRICT_OBJC_MSGSEND = YES; 687 | GCC_C_LANGUAGE_STANDARD = gnu99; 688 | GCC_NO_COMMON_BLOCKS = YES; 689 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 690 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 691 | GCC_WARN_UNDECLARED_SELECTOR = YES; 692 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 693 | GCC_WARN_UNUSED_FUNCTION = YES; 694 | GCC_WARN_UNUSED_VARIABLE = YES; 695 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 696 | MTL_ENABLE_DEBUG_INFO = NO; 697 | SDKROOT = iphoneos; 698 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 699 | SWIFT_VERSION = 5.0; 700 | TARGETED_DEVICE_FAMILY = "1,2"; 701 | VALIDATE_PRODUCT = YES; 702 | VERSIONING_SYSTEM = "apple-generic"; 703 | VERSION_INFO_PREFIX = ""; 704 | }; 705 | name = Release; 706 | }; 707 | 6D24754C1CAAB1050044D223 /* Debug */ = { 708 | isa = XCBuildConfiguration; 709 | buildSettings = { 710 | APPLICATION_EXTENSION_API_ONLY = YES; 711 | CLANG_ENABLE_MODULES = YES; 712 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 713 | DEFINES_MODULE = YES; 714 | DYLIB_COMPATIBILITY_VERSION = 1; 715 | DYLIB_CURRENT_VERSION = 1; 716 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 717 | INFOPLIST_FILE = "Source/Supporting Files/Info.plist"; 718 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 719 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 720 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 721 | PRODUCT_BUNDLE_IDENTIFIER = io.delba.TextAttributes; 722 | PRODUCT_NAME = TextAttributes; 723 | SKIP_INSTALL = YES; 724 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 725 | SWIFT_VERSION = 5.0; 726 | }; 727 | name = Debug; 728 | }; 729 | 6D24754D1CAAB1050044D223 /* Release */ = { 730 | isa = XCBuildConfiguration; 731 | buildSettings = { 732 | APPLICATION_EXTENSION_API_ONLY = YES; 733 | CLANG_ENABLE_MODULES = YES; 734 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 735 | DEFINES_MODULE = YES; 736 | DYLIB_COMPATIBILITY_VERSION = 1; 737 | DYLIB_CURRENT_VERSION = 1; 738 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 739 | INFOPLIST_FILE = "Source/Supporting Files/Info.plist"; 740 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 741 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 742 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 743 | PRODUCT_BUNDLE_IDENTIFIER = io.delba.TextAttributes; 744 | PRODUCT_NAME = TextAttributes; 745 | SKIP_INSTALL = YES; 746 | SWIFT_VERSION = 5.0; 747 | }; 748 | name = Release; 749 | }; 750 | 6D24754F1CAAB1050044D223 /* Debug */ = { 751 | isa = XCBuildConfiguration; 752 | buildSettings = { 753 | INFOPLIST_FILE = "Tests/Supporting Files/Info.plist"; 754 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 755 | PRODUCT_BUNDLE_IDENTIFIER = io.delba.TextAttributesTests; 756 | PRODUCT_NAME = "$(TARGET_NAME)"; 757 | SWIFT_VERSION = 5.0; 758 | }; 759 | name = Debug; 760 | }; 761 | 6D2475501CAAB1050044D223 /* Release */ = { 762 | isa = XCBuildConfiguration; 763 | buildSettings = { 764 | INFOPLIST_FILE = "Tests/Supporting Files/Info.plist"; 765 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 766 | PRODUCT_BUNDLE_IDENTIFIER = io.delba.TextAttributesTests; 767 | PRODUCT_NAME = "$(TARGET_NAME)"; 768 | SWIFT_VERSION = 5.0; 769 | }; 770 | name = Release; 771 | }; 772 | 6DB5197D1CCA7F30005C3E83 /* Debug */ = { 773 | isa = XCBuildConfiguration; 774 | buildSettings = { 775 | APPLICATION_EXTENSION_API_ONLY = YES; 776 | CLANG_ANALYZER_NONNULL = YES; 777 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 778 | DEFINES_MODULE = YES; 779 | DYLIB_COMPATIBILITY_VERSION = 1; 780 | DYLIB_CURRENT_VERSION = 1; 781 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 782 | INFOPLIST_FILE = "$(SRCROOT)/Source/Supporting Files/Info.plist"; 783 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 784 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 785 | PRODUCT_BUNDLE_IDENTIFIER = "io.delba.TextAttributes-watchOS"; 786 | PRODUCT_NAME = TextAttributes; 787 | SDKROOT = watchos; 788 | SKIP_INSTALL = YES; 789 | SWIFT_VERSION = 5.0; 790 | TARGETED_DEVICE_FAMILY = 4; 791 | WATCHOS_DEPLOYMENT_TARGET = 2.2; 792 | }; 793 | name = Debug; 794 | }; 795 | 6DB5197E1CCA7F30005C3E83 /* Release */ = { 796 | isa = XCBuildConfiguration; 797 | buildSettings = { 798 | APPLICATION_EXTENSION_API_ONLY = YES; 799 | CLANG_ANALYZER_NONNULL = YES; 800 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 801 | DEFINES_MODULE = YES; 802 | DYLIB_COMPATIBILITY_VERSION = 1; 803 | DYLIB_CURRENT_VERSION = 1; 804 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 805 | INFOPLIST_FILE = "$(SRCROOT)/Source/Supporting Files/Info.plist"; 806 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 807 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 808 | PRODUCT_BUNDLE_IDENTIFIER = "io.delba.TextAttributes-watchOS"; 809 | PRODUCT_NAME = TextAttributes; 810 | SDKROOT = watchos; 811 | SKIP_INSTALL = YES; 812 | SWIFT_VERSION = 5.0; 813 | TARGETED_DEVICE_FAMILY = 4; 814 | WATCHOS_DEPLOYMENT_TARGET = 2.2; 815 | }; 816 | name = Release; 817 | }; 818 | 6DB5199D1CCA8CEF005C3E83 /* Debug */ = { 819 | isa = XCBuildConfiguration; 820 | buildSettings = { 821 | APPLICATION_EXTENSION_API_ONLY = YES; 822 | CLANG_ANALYZER_NONNULL = YES; 823 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 824 | DEFINES_MODULE = YES; 825 | DYLIB_COMPATIBILITY_VERSION = 1; 826 | DYLIB_CURRENT_VERSION = 1; 827 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 828 | INFOPLIST_FILE = "$(SRCROOT)/Source/Supporting Files/Info.plist"; 829 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 830 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 831 | PRODUCT_BUNDLE_IDENTIFIER = "io.delba.TextAttributes-tvOS"; 832 | PRODUCT_NAME = TextAttributes; 833 | SDKROOT = appletvos; 834 | SKIP_INSTALL = YES; 835 | SWIFT_VERSION = 5.0; 836 | TARGETED_DEVICE_FAMILY = 3; 837 | TVOS_DEPLOYMENT_TARGET = 9.0; 838 | }; 839 | name = Debug; 840 | }; 841 | 6DB5199E1CCA8CEF005C3E83 /* Release */ = { 842 | isa = XCBuildConfiguration; 843 | buildSettings = { 844 | APPLICATION_EXTENSION_API_ONLY = YES; 845 | CLANG_ANALYZER_NONNULL = YES; 846 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 847 | DEFINES_MODULE = YES; 848 | DYLIB_COMPATIBILITY_VERSION = 1; 849 | DYLIB_CURRENT_VERSION = 1; 850 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 851 | INFOPLIST_FILE = "$(SRCROOT)/Source/Supporting Files/Info.plist"; 852 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 853 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 854 | PRODUCT_BUNDLE_IDENTIFIER = "io.delba.TextAttributes-tvOS"; 855 | PRODUCT_NAME = TextAttributes; 856 | SDKROOT = appletvos; 857 | SKIP_INSTALL = YES; 858 | SWIFT_VERSION = 5.0; 859 | TARGETED_DEVICE_FAMILY = 3; 860 | TVOS_DEPLOYMENT_TARGET = 9.0; 861 | }; 862 | name = Release; 863 | }; 864 | 6DB5199F1CCA8CEF005C3E83 /* Debug */ = { 865 | isa = XCBuildConfiguration; 866 | buildSettings = { 867 | CLANG_ANALYZER_NONNULL = YES; 868 | INFOPLIST_FILE = "$(SRCROOT)/Tests/Supporting Files/Info.plist"; 869 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 870 | PRODUCT_BUNDLE_IDENTIFIER = "io.delba.TextAttributes-tvOSTests"; 871 | PRODUCT_NAME = "$(TARGET_NAME)"; 872 | SDKROOT = appletvos; 873 | SWIFT_VERSION = 5.0; 874 | TVOS_DEPLOYMENT_TARGET = 9.2; 875 | }; 876 | name = Debug; 877 | }; 878 | 6DB519A01CCA8CEF005C3E83 /* Release */ = { 879 | isa = XCBuildConfiguration; 880 | buildSettings = { 881 | CLANG_ANALYZER_NONNULL = YES; 882 | INFOPLIST_FILE = "$(SRCROOT)/Tests/Supporting Files/Info.plist"; 883 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 884 | PRODUCT_BUNDLE_IDENTIFIER = "io.delba.TextAttributes-tvOSTests"; 885 | PRODUCT_NAME = "$(TARGET_NAME)"; 886 | SDKROOT = appletvos; 887 | SWIFT_VERSION = 5.0; 888 | TVOS_DEPLOYMENT_TARGET = 9.2; 889 | }; 890 | name = Release; 891 | }; 892 | 6DDF4E411CD1260B002AA459 /* Debug */ = { 893 | isa = XCBuildConfiguration; 894 | buildSettings = { 895 | APPLICATION_EXTENSION_API_ONLY = YES; 896 | CLANG_ANALYZER_NONNULL = YES; 897 | CODE_SIGN_IDENTITY = ""; 898 | COMBINE_HIDPI_IMAGES = YES; 899 | DEFINES_MODULE = YES; 900 | DYLIB_COMPATIBILITY_VERSION = 1; 901 | DYLIB_CURRENT_VERSION = 1; 902 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 903 | FRAMEWORK_VERSION = A; 904 | INFOPLIST_FILE = "$(SRCROOT)/Source/Supporting Files/Info.plist"; 905 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 906 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; 907 | MACOSX_DEPLOYMENT_TARGET = 10.10; 908 | PRODUCT_BUNDLE_IDENTIFIER = io.delba.TextAttributes; 909 | PRODUCT_NAME = TextAttributes; 910 | SDKROOT = macosx; 911 | SKIP_INSTALL = YES; 912 | SWIFT_VERSION = 5.0; 913 | }; 914 | name = Debug; 915 | }; 916 | 6DDF4E421CD1260B002AA459 /* Release */ = { 917 | isa = XCBuildConfiguration; 918 | buildSettings = { 919 | APPLICATION_EXTENSION_API_ONLY = YES; 920 | CLANG_ANALYZER_NONNULL = YES; 921 | CODE_SIGN_IDENTITY = ""; 922 | COMBINE_HIDPI_IMAGES = YES; 923 | DEFINES_MODULE = YES; 924 | DYLIB_COMPATIBILITY_VERSION = 1; 925 | DYLIB_CURRENT_VERSION = 1; 926 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 927 | FRAMEWORK_VERSION = A; 928 | INFOPLIST_FILE = "$(SRCROOT)/Source/Supporting Files/Info.plist"; 929 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 930 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; 931 | MACOSX_DEPLOYMENT_TARGET = 10.10; 932 | PRODUCT_BUNDLE_IDENTIFIER = io.delba.TextAttributes; 933 | PRODUCT_NAME = TextAttributes; 934 | SDKROOT = macosx; 935 | SKIP_INSTALL = YES; 936 | SWIFT_VERSION = 5.0; 937 | }; 938 | name = Release; 939 | }; 940 | 6DDF4E431CD1260B002AA459 /* Debug */ = { 941 | isa = XCBuildConfiguration; 942 | buildSettings = { 943 | CLANG_ANALYZER_NONNULL = YES; 944 | CODE_SIGN_IDENTITY = "-"; 945 | COMBINE_HIDPI_IMAGES = YES; 946 | INFOPLIST_FILE = "$(SRCROOT)/Tests/Supporting Files/Info.plist"; 947 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; 948 | MACOSX_DEPLOYMENT_TARGET = 10.11; 949 | PRODUCT_BUNDLE_IDENTIFIER = io.delba.TextAttributesTests; 950 | PRODUCT_NAME = "$(TARGET_NAME)"; 951 | SDKROOT = macosx; 952 | SWIFT_VERSION = 5.0; 953 | }; 954 | name = Debug; 955 | }; 956 | 6DDF4E441CD1260B002AA459 /* Release */ = { 957 | isa = XCBuildConfiguration; 958 | buildSettings = { 959 | CLANG_ANALYZER_NONNULL = YES; 960 | CODE_SIGN_IDENTITY = "-"; 961 | COMBINE_HIDPI_IMAGES = YES; 962 | INFOPLIST_FILE = "$(SRCROOT)/Tests/Supporting Files/Info.plist"; 963 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; 964 | MACOSX_DEPLOYMENT_TARGET = 10.11; 965 | PRODUCT_BUNDLE_IDENTIFIER = io.delba.TextAttributesTests; 966 | PRODUCT_NAME = "$(TARGET_NAME)"; 967 | SDKROOT = macosx; 968 | SWIFT_VERSION = 5.0; 969 | }; 970 | name = Release; 971 | }; 972 | /* End XCBuildConfiguration section */ 973 | 974 | /* Begin XCConfigurationList section */ 975 | 6D2475311CAAB1050044D223 /* Build configuration list for PBXProject "TextAttributes" */ = { 976 | isa = XCConfigurationList; 977 | buildConfigurations = ( 978 | 6D2475491CAAB1050044D223 /* Debug */, 979 | 6D24754A1CAAB1050044D223 /* Release */, 980 | ); 981 | defaultConfigurationIsVisible = 0; 982 | defaultConfigurationName = Release; 983 | }; 984 | 6D24754B1CAAB1050044D223 /* Build configuration list for PBXNativeTarget "TextAttributes iOS" */ = { 985 | isa = XCConfigurationList; 986 | buildConfigurations = ( 987 | 6D24754C1CAAB1050044D223 /* Debug */, 988 | 6D24754D1CAAB1050044D223 /* Release */, 989 | ); 990 | defaultConfigurationIsVisible = 0; 991 | defaultConfigurationName = Release; 992 | }; 993 | 6D24754E1CAAB1050044D223 /* Build configuration list for PBXNativeTarget "TextAttributes iOS Tests" */ = { 994 | isa = XCConfigurationList; 995 | buildConfigurations = ( 996 | 6D24754F1CAAB1050044D223 /* Debug */, 997 | 6D2475501CAAB1050044D223 /* Release */, 998 | ); 999 | defaultConfigurationIsVisible = 0; 1000 | defaultConfigurationName = Release; 1001 | }; 1002 | 6DB5197F1CCA7F31005C3E83 /* Build configuration list for PBXNativeTarget "TextAttributes watchOS" */ = { 1003 | isa = XCConfigurationList; 1004 | buildConfigurations = ( 1005 | 6DB5197D1CCA7F30005C3E83 /* Debug */, 1006 | 6DB5197E1CCA7F30005C3E83 /* Release */, 1007 | ); 1008 | defaultConfigurationIsVisible = 0; 1009 | defaultConfigurationName = Release; 1010 | }; 1011 | 6DB519A11CCA8CEF005C3E83 /* Build configuration list for PBXNativeTarget "TextAttributes tvOS" */ = { 1012 | isa = XCConfigurationList; 1013 | buildConfigurations = ( 1014 | 6DB5199D1CCA8CEF005C3E83 /* Debug */, 1015 | 6DB5199E1CCA8CEF005C3E83 /* Release */, 1016 | ); 1017 | defaultConfigurationIsVisible = 0; 1018 | defaultConfigurationName = Release; 1019 | }; 1020 | 6DB519A21CCA8CEF005C3E83 /* Build configuration list for PBXNativeTarget "TextAttributes tvOS Tests" */ = { 1021 | isa = XCConfigurationList; 1022 | buildConfigurations = ( 1023 | 6DB5199F1CCA8CEF005C3E83 /* Debug */, 1024 | 6DB519A01CCA8CEF005C3E83 /* Release */, 1025 | ); 1026 | defaultConfigurationIsVisible = 0; 1027 | defaultConfigurationName = Release; 1028 | }; 1029 | 6DDF4E451CD1260B002AA459 /* Build configuration list for PBXNativeTarget "TextAttributes OSX" */ = { 1030 | isa = XCConfigurationList; 1031 | buildConfigurations = ( 1032 | 6DDF4E411CD1260B002AA459 /* Debug */, 1033 | 6DDF4E421CD1260B002AA459 /* Release */, 1034 | ); 1035 | defaultConfigurationIsVisible = 0; 1036 | defaultConfigurationName = Release; 1037 | }; 1038 | 6DDF4E461CD1260B002AA459 /* Build configuration list for PBXNativeTarget "TextAttributes OSX Tests" */ = { 1039 | isa = XCConfigurationList; 1040 | buildConfigurations = ( 1041 | 6DDF4E431CD1260B002AA459 /* Debug */, 1042 | 6DDF4E441CD1260B002AA459 /* Release */, 1043 | ); 1044 | defaultConfigurationIsVisible = 0; 1045 | defaultConfigurationName = Release; 1046 | }; 1047 | /* End XCConfigurationList section */ 1048 | }; 1049 | rootObject = 6D24752E1CAAB1050044D223 /* Project object */; 1050 | } 1051 | --------------------------------------------------------------------------------