├── .gitignore
├── .swiftpm
└── xcode
│ └── package.xcworkspace
│ └── contents.xcworkspacedata
├── .travis.yml
├── AnyFormatKit.h
├── AnyFormatKit.podspec
├── AnyFormatKit.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ └── contents.xcworkspacedata
└── xcshareddata
│ └── xcschemes
│ └── AnyFormatKit.xcscheme
├── AnyFormatKit.xcworkspace
└── xcshareddata
│ └── IDEWorkspaceChecks.plist
├── Assets
├── anyformatkit.jpeg
├── example_card_number.gif
├── example_phone_number.gif
├── example_placeholder_phone_number.gif
└── example_sum.gif
├── BundleFiles
└── Info.plist
├── Documentation
├── AnyFormatKit 0.2.0 MigrationGuide.md
├── AnyFormatKit 1.0.0 MigrationGuide.md
└── AnyFormatKit 2.4.0 MigrationGuide.md
├── Example
├── CocoapodsExample
│ ├── Podfile
│ ├── Podfile.lock
│ ├── Pods
│ │ ├── Local Podspecs
│ │ │ └── AnyFormatKit.podspec.json
│ │ ├── Manifest.lock
│ │ ├── Pods.xcodeproj
│ │ │ └── project.pbxproj
│ │ ├── SnapKit
│ │ │ ├── LICENSE
│ │ │ ├── README.md
│ │ │ └── Source
│ │ │ │ ├── Constraint.swift
│ │ │ │ ├── ConstraintAttributes.swift
│ │ │ │ ├── ConstraintConfig.swift
│ │ │ │ ├── ConstraintConstantTarget.swift
│ │ │ │ ├── ConstraintDSL.swift
│ │ │ │ ├── ConstraintDescription.swift
│ │ │ │ ├── ConstraintInsetTarget.swift
│ │ │ │ ├── ConstraintInsets.swift
│ │ │ │ ├── ConstraintItem.swift
│ │ │ │ ├── ConstraintLayoutGuide+Extensions.swift
│ │ │ │ ├── ConstraintLayoutGuide.swift
│ │ │ │ ├── ConstraintLayoutGuideDSL.swift
│ │ │ │ ├── ConstraintLayoutSupport.swift
│ │ │ │ ├── ConstraintLayoutSupportDSL.swift
│ │ │ │ ├── ConstraintMaker.swift
│ │ │ │ ├── ConstraintMakerEditable.swift
│ │ │ │ ├── ConstraintMakerExtendable.swift
│ │ │ │ ├── ConstraintMakerFinalizable.swift
│ │ │ │ ├── ConstraintMakerPriortizable.swift
│ │ │ │ ├── ConstraintMakerRelatable.swift
│ │ │ │ ├── ConstraintMultiplierTarget.swift
│ │ │ │ ├── ConstraintOffsetTarget.swift
│ │ │ │ ├── ConstraintPriority.swift
│ │ │ │ ├── ConstraintPriorityTarget.swift
│ │ │ │ ├── ConstraintRelatableTarget.swift
│ │ │ │ ├── ConstraintRelation.swift
│ │ │ │ ├── ConstraintView+Extensions.swift
│ │ │ │ ├── ConstraintView.swift
│ │ │ │ ├── ConstraintViewDSL.swift
│ │ │ │ ├── Debugging.swift
│ │ │ │ ├── LayoutConstraint.swift
│ │ │ │ ├── LayoutConstraintItem.swift
│ │ │ │ ├── Typealiases.swift
│ │ │ │ └── UILayoutSupport+Extensions.swift
│ │ └── Target Support Files
│ │ │ ├── AnyFormatKit
│ │ │ ├── AnyFormatKit-Info.plist
│ │ │ ├── AnyFormatKit-dummy.m
│ │ │ ├── AnyFormatKit-prefix.pch
│ │ │ ├── AnyFormatKit-umbrella.h
│ │ │ ├── AnyFormatKit.debug.xcconfig
│ │ │ ├── AnyFormatKit.modulemap
│ │ │ └── AnyFormatKit.release.xcconfig
│ │ │ ├── Pods-iOS Example
│ │ │ ├── Pods-iOS Example-Info.plist
│ │ │ ├── Pods-iOS Example-acknowledgements.markdown
│ │ │ ├── Pods-iOS Example-acknowledgements.plist
│ │ │ ├── Pods-iOS Example-dummy.m
│ │ │ ├── Pods-iOS Example-frameworks.sh
│ │ │ ├── Pods-iOS Example-umbrella.h
│ │ │ ├── Pods-iOS Example.debug.xcconfig
│ │ │ ├── Pods-iOS Example.modulemap
│ │ │ └── Pods-iOS Example.release.xcconfig
│ │ │ └── SnapKit
│ │ │ ├── SnapKit-Info.plist
│ │ │ ├── SnapKit-dummy.m
│ │ │ ├── SnapKit-prefix.pch
│ │ │ ├── SnapKit-umbrella.h
│ │ │ ├── SnapKit.debug.xcconfig
│ │ │ ├── SnapKit.modulemap
│ │ │ └── SnapKit.release.xcconfig
│ ├── iOS Example.xcodeproj
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace
│ │ │ └── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ ├── UIKitExample.xcscheme
│ │ │ └── iOS Example.xcscheme
│ ├── iOS Example.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ └── iOS Example
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── ExampleView.swift
│ │ ├── ExampleViewController.swift
│ │ ├── Helpers
│ │ ├── CardInfoView.swift
│ │ ├── InitView.swift
│ │ ├── TitleTextFieldView.swift
│ │ └── UIFont+Extension.swift
│ │ └── Info.plist
└── SPMExample
│ ├── AnyFormatKitSPMExample.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── swiftpm
│ │ └── Package.resolved
│ └── AnyFormatKitSPMExample
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ ├── AccentColor.colorset
│ │ └── Contents.json
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ └── Contents.json
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── ExampleView.swift
│ ├── ExampleViewController.swift
│ ├── Helpers
│ ├── CardInfoView.swift
│ ├── InitView.swift
│ ├── TitleTextFieldView.swift
│ └── UIFont+Extension.swift
│ ├── Info.plist
│ └── SceneDelegate.swift
├── Info.plist
├── LICENSE
├── Package.swift
├── README.md
├── Source
├── Controllers
│ ├── TextFieldControllers
│ │ ├── TextFieldInputController.swift
│ │ └── TextFieldStartInputController.swift
│ └── TextViewControllers
│ │ ├── TextViewInputController.swift
│ │ └── TextViewStartInputController.swift
├── Extensions
│ ├── String+Extension.swift
│ ├── UITextField+Extension.swift
│ └── UITextView+Extension.swift
└── TextFormatter
│ ├── DefaultFormatters
│ ├── Formatters
│ │ ├── DefaultTextFormatter.swift
│ │ └── DefaultTextInputFormatter.swift
│ └── Helpers
│ │ ├── DefaultCaretPositionCorrector.swift
│ │ └── DefaultRangeCalculator.swift
│ ├── PlaceholderFormatters
│ ├── Formatters
│ │ ├── PlaceholderTextFormatter.swift
│ │ └── PlaceholderTextInputFormatter.swift
│ └── Helpers
│ │ ├── PlaceholderCaretPositionCalculator.swift
│ │ └── PlaceholderRangeCalculator.swift
│ ├── SumFormatters
│ ├── Formatters
│ │ ├── SumTextFormatter.swift
│ │ └── SumTextInputFormatter.swift
│ └── Helpers
│ │ ├── SumFormatParser.swift
│ │ └── SumTextInputFormatterCaretPositionCalculator.swift
│ └── TextFormatter
│ ├── CaretPositioner.swift
│ ├── FormattedTextValue.swift
│ ├── TextFormatter.swift
│ ├── TextInputFormatter.swift
│ ├── TextNumberFormatter.swift
│ ├── TextNumberUnformatter.swift
│ └── TextUnformatter.swift
├── Tests
├── DefaultTextFormatterTests
│ ├── DefaultTextFormatterTests.swift
│ └── DefaultTextFormatterUnformatTests.swift
├── DefaultTextInputFormatterTests
│ ├── Format
│ │ └── DefaultTextInputFormatterFormatTests.swift
│ ├── FormatInput
│ │ ├── Delete
│ │ │ └── DefaultTextInputFormatterDeleteTests.swift
│ │ ├── Insert
│ │ │ ├── AnyFormatKitTests.swift
│ │ │ ├── DefaultTextInputFormatterEmojisInputTests.swift
│ │ │ ├── DefaultTextInputFormatterInputTests.swift
│ │ │ └── DefaultTextInputFormatterPhoneEmojisInputTests.swift
│ │ └── Replace
│ │ │ ├── DefaultTextInputFormatter1SymbolReplaceTests.swift
│ │ │ ├── DefaultTextInputFormatter2SymbolsReplaceTests.swift
│ │ │ └── DefaultTextInputFormatter3SymbolsReplace.swift
│ └── Unformat
│ │ └── DefaultTextInputUnformattingTests.swift
├── Info.plist
├── PlaceholderFormatterTests
│ ├── PlaceholderFormatterFormattingTests.swift
│ └── PlaceholderFormatterUnformattingTests.swift
├── PlaceholderTextInputFormatterTests
│ ├── Format
│ │ └── PlaceholderTextInputFormatterFormatTests.swift
│ ├── FormatInput
│ │ ├── Delete
│ │ │ ├── PlaceholderTextInputFormatterDelete3SymbolsTests.swift
│ │ │ └── PlaceholderTextInputFormatterErasingBy1SymbolTests.swift
│ │ ├── Insert
│ │ │ ├── PlaceholderTextInputFormatterEmojisInputTests.swift
│ │ │ ├── PlaceholderTextInputFormatterInputTests.swift
│ │ │ └── PlaceholderTextInputFormatterInsert3SymbolsTests.swift
│ │ └── Replace
│ │ │ └── PlaceholderTextInputFormatterReplace3SymbolsTests.swift
│ └── Unformat
│ │ └── PlaceholderTextInputUnformattingTests.swift
├── SumFormatTests
│ ├── FormatParsingTests.swift
│ ├── SumFormatParserTests.swift
│ └── SumTextFormatterFormatParseTests.swift
├── SumTextFormatterTests
│ └── SumTextFormatterFormatTests.swift
└── SumTextInputFormatterTests
│ ├── FormatInput
│ ├── Simple
│ │ ├── Format
│ │ │ └── SumTextInputFormatterFormatTests.swift
│ │ ├── FormatInput
│ │ │ ├── Delete
│ │ │ │ ├── SumTextInputFormatterDelete3SymbolsTests.swift
│ │ │ │ ├── SumTextInputFormatterErasingBy1SymbolTests.swift
│ │ │ │ └── SumTextInputFormatterSpaceGroupSeparatorDelete1SymbolsTests.swift
│ │ │ ├── Insert
│ │ │ │ ├── SumTextInputFormatterInput0Tests.swift
│ │ │ │ ├── SumTextInputFormatterInputTests.swift
│ │ │ │ └── SumTextInputFormatterInsert3Symbols.swift
│ │ │ └── Replace
│ │ │ │ └── SumTextInputFormatterReplace3SymbolsTests.swift
│ │ └── Unformat
│ │ │ ├── SumTextInputFormatterNumberUnformatTests.swift
│ │ │ └── SumTextInputFormatterUnformatTests.swift
│ ├── WithPrefix
│ │ ├── 1SymbolPrefix
│ │ │ ├── Delete
│ │ │ │ ├── SumTextInputFormatterWithPrefixBy1SymbolErasingTests.swift
│ │ │ │ └── SumTextInputFormatterWithPrefixDelete3SymbolsTests.swift
│ │ │ ├── Insert
│ │ │ │ ├── SumTextInputFormatterWithPrefixInputTests.swift
│ │ │ │ └── SumTextInputtFormaterWithPrefix3SymbolnsertTests.swift
│ │ │ └── Replace
│ │ │ │ └── SumTextInputFormatterWithPrefix3SymbolsReplaceTests.swift
│ │ └── 2SymbolsPrefix
│ │ │ ├── Delete
│ │ │ ├── SumTextInputFormatterWith2SymbolsPrefixBy1SymbolErasingTests.swift
│ │ │ └── SumTextInputFormatterWith2SymbolsPrefixDelete3SymbolsTests.swift
│ │ │ └── Insert
│ │ │ └── SumTextInputFormatterWith2SymbolsPrefixInputTests.swift
│ └── WithSuffix
│ │ ├── 1SymbolSuffix
│ │ ├── Delete
│ │ │ ├── SumTextInputFormatterWithSimilarCharactersInSuffixAndGroupSeparatorDelete1SymbolTests.swift
│ │ │ ├── SumTextInputFormatterWithSuffixDelete1SymbolTests.swift
│ │ │ ├── SumTextInputFormatterWithSuffixDelete2SymbolsTests.swift
│ │ │ └── SumTextInputFormatterWithSuffixDelete3SymbolsTests.swift
│ │ ├── Insert
│ │ │ ├── SumTextInputFormatterWithSuffixInput0Tests.swift
│ │ │ ├── SumTextInputFormatterWithSuffixInputTests.swift
│ │ │ └── SumTextInputFormatterWithSuffixInsert2SymbolsTests.swift
│ │ └── Replace
│ │ │ ├── SumTextInputFormatterWithSuffixReplace1SymbolTests.swift
│ │ │ ├── SumTextInputFormatterWithSuffixReplace2SymbolsTests.swift
│ │ │ ├── SumTextInputFormatterWithSuffixReplace3SymbolsTests.swift
│ │ │ └── SumTextInputFormatterWithSuffixReplaceWith0Tests.swift
│ │ └── 2SymbolSuffix
│ │ ├── Delete
│ │ ├── SumTextInputFormatterWith2SymbolsSuffixBy1SymbolErasingTests.swift
│ │ └── SumTextInputFormatterWith2SymbolsSuffixDelete3SymbolsTests.swift
│ │ └── Insert
│ │ ├── SumTextInputFormatterWith2SymbolsSuffixBy1SymbolInputTests.swift
│ │ └── SumTextInputFormatterWith2SymbolsSuffixInsert2SymbolsTests.swift
│ └── FormatParse
│ └── SumTextInputFormatterFormatParseTests.swift
├── run-tests.sh
└── update_version.rb
/.gitignore:
--------------------------------------------------------------------------------
1 | # OS X
2 | .DS_Store
3 |
4 | # Xcode
5 | build/
6 | *.pbxuser
7 | !default.pbxuser
8 | *.mode1v3
9 | !default.mode1v3
10 | *.mode2v3
11 | !default.mode2v3
12 | *.perspectivev3
13 | !default.perspectivev3
14 | xcuserdata/
15 | *.xccheckout
16 | profile
17 | *.moved-aside
18 | DerivedData
19 | *.hmap
20 | *.ipa
21 |
22 | # Bundler
23 | .bundle
24 |
25 | Carthage
26 | # We recommend against adding the Pods directory to your .gitignore. However
27 | # you should judge for yourself, the pros and cons are mentioned at:
28 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
29 | #
30 | # Note: if you ignore the Pods directory, make sure to uncomment
31 | # `pod install` in .travis.yml
32 | #
33 | # Pods/
34 | AnyFormatKit.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
35 |
--------------------------------------------------------------------------------
/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 |
2 | osx_image: xcode11.3
3 | language: swift
4 | os: osx
5 |
6 | xcode_workspace: AnyFormatKit.xcworkspace
7 | xcode_scheme:
8 | - AnyFormatKit
9 | - AnyFormatKitTests
10 | - iOS Example
11 |
12 | branches:
13 | only:
14 | - master
15 | - develop
16 |
17 | script: ./run-tests.sh
18 |
19 | notifications:
20 | email:
21 | recipients:
22 | - luximetr.notification@gmail.com
23 | on_success: always
24 | on_failure: always
--------------------------------------------------------------------------------
/AnyFormatKit.h:
--------------------------------------------------------------------------------
1 | //
2 | // AnyFormatKit.h
3 | // AnyFormatKit
4 | //
5 | // Created by BRANDERSTUDIO on 01.11.2017.
6 | // Copyright © 2017 BRANDERSTUDIO. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for AnyFormatKit.
12 | FOUNDATION_EXPORT double AnyFormatKitVersionNumber;
13 |
14 | //! Project version string for AnyFormatKit.
15 | FOUNDATION_EXPORT const unsigned char AnyFormatKitVersionString[];
16 |
17 | // In this header, you should import all the public headers of your framework using statements like #import
18 |
19 |
20 |
--------------------------------------------------------------------------------
/AnyFormatKit.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = 'AnyFormatKit'
3 | s.version = '2.5.2'
4 | s.summary = 'Simple text formatting in Swift.'
5 |
6 | s.description = <<-DESC
7 | This framework provide to format text with format like "## ##-###", where # - replaceble symbol. Support format all string or character by character input.
8 | DESC
9 |
10 | s.homepage = 'https://github.com/luximetr/AnyFormatKit'
11 | s.license = { :type => 'MIT', :file => 'LICENSE' }
12 | s.author = { 'luximetr' => 'luximetr.notification@gmail.com' }
13 | s.source = { :git => 'https://github.com/luximetr/AnyFormatKit.git', :tag => s.version.to_s }
14 |
15 | s.ios.deployment_target = '9.0'
16 | s.swift_version = '5.0'
17 |
18 | s.source_files = 'Source/**/*'
19 | end
20 |
--------------------------------------------------------------------------------
/AnyFormatKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/AnyFormatKit.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Assets/anyformatkit.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luximetr/AnyFormatKit/ae3a965164005b07f81d6aa066520d7ad14ea54e/Assets/anyformatkit.jpeg
--------------------------------------------------------------------------------
/Assets/example_card_number.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luximetr/AnyFormatKit/ae3a965164005b07f81d6aa066520d7ad14ea54e/Assets/example_card_number.gif
--------------------------------------------------------------------------------
/Assets/example_phone_number.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luximetr/AnyFormatKit/ae3a965164005b07f81d6aa066520d7ad14ea54e/Assets/example_phone_number.gif
--------------------------------------------------------------------------------
/Assets/example_placeholder_phone_number.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luximetr/AnyFormatKit/ae3a965164005b07f81d6aa066520d7ad14ea54e/Assets/example_placeholder_phone_number.gif
--------------------------------------------------------------------------------
/Assets/example_sum.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/luximetr/AnyFormatKit/ae3a965164005b07f81d6aa066520d7ad14ea54e/Assets/example_sum.gif
--------------------------------------------------------------------------------
/BundleFiles/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
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 | $(MARKETING_VERSION)
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 | NSPrincipalClass
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Documentation/AnyFormatKit 0.2.0 MigrationGuide.md:
--------------------------------------------------------------------------------
1 | # AnyFormatKit 0.2.0 Migration Guide
2 |
3 | ## Breaking Changes
4 |
5 | ### SumTextFormatter
6 |
7 | #### Maximum Decimal Characters
8 |
9 | Variable, that allowed to input limited number of characters after decimal separator now get-only.
10 |
11 | ```swift
12 | // open var maximumDecimalCharacters: Int = 2
13 | open var maximumDecimalCharacters: Int {
14 | return numberFormatter.maximumFractionDigits
15 | }
16 | ```
17 | Now maximumFractionDigits parse from format (number of '#' after decimal separator).
18 |
19 | ```swift
20 | SumTextInputFormatter(textPattern: "#.###,#### $") // 4 '#' after ',' - maximumFractionDigits
21 | ```
22 |
23 | ## Updates
24 |
25 | #### Format input method
26 |
27 | func formatInput() - method, that format text and return it as result with new caret offset. Now TextInputFormatter use this method in shouldChangeTextIn() by default.
28 |
29 | ```swift
30 | func formatInput(currentText: String, range: NSRange, replacementString text: String) -> FormattedTextValue
31 | ```
32 |
33 | #### FormattedTextValue
34 |
35 | FormattedTextValue is a tuple, that use for return formatted text and caret offset from begin from input formatter.
36 |
37 | ```swift
38 | public typealias FormattedTextValue = (formattedText: String, caretBeginOffset: Int)
39 | ```
40 |
41 | #### SumTextFormatter
42 |
43 | Now sum text formatter use NumberFormatter under the hood.
44 |
45 | ```swift
46 | private let numberFormatter: NumberFormatter
47 | ```
48 | Was added init method with number formatter. Old init method still works.
49 |
50 | ```swift
51 | public init(numberFormatter: NumberFormatter) {
52 | self.numberFormatter = numberFormatter
53 | }
54 | ```
55 |
--------------------------------------------------------------------------------
/Documentation/AnyFormatKit 1.0.0 MigrationGuide.md:
--------------------------------------------------------------------------------
1 | # AnyFormatKit 1.0.0 Migration Guide
2 |
3 | ## Breaking Changes
4 |
5 | ### TextFormatterProtocol
6 |
7 | - `TextFormatterProtocol` was renamed to `TextFormatter`
8 | - `formattedText(from:)` method renamed to `format()`
9 | - `unformattedText(from:)` method renamed to `unformat()`
10 |
11 | ```swift
12 | public protocol TextFormatter {
13 | func format(_ unformattedText: String?) -> String?
14 | func unformat(_ formattedText: String?) -> String?
15 | }
16 | ```
17 |
18 | ### TextInputFormatterProtocol
19 |
20 | - `TextInputFormatterProtocol` was renamed to `TextInputFormatter`
21 | - now have only one method `formatInput(currentText:)`, how to use it look at [demo](https://github.com/luximetr/AnyFormatKit/tree/master/Example) project
22 |
23 | ```swift
24 | protocol TextInputFormatter: TextFormatter {
25 | func formatInput(currentText: String, range: NSRange, replacementString text: String) -> FormattedTextValue
26 | }
27 | ```
28 |
29 | ### TextFormatter
30 |
31 | `TextFormatter` was renamed to `DefaultTextFormatter`
32 |
33 | ### TextInputFormatter
34 |
35 | - `TextInputFormatter` was renamed to `DefaultTextInputFormatter`
36 | - `var allowedSymbolsRegex: String` was removed. Filter moved to separate pod (look at [Filter](https://github.com/Brander-ua/BTextInputFilter))
37 | - `shouldChangeTextIn(textInput:)` was removed (need to use `formatInput(currentText:)`)
38 |
39 | ### SumTextInputFormatter
40 |
41 | - `var formattedPrefix: String?` was removed
42 | - `var allowedSymbolsRegex: String?` was removed. Filter moved to separate pod (look at [Filter](https://github.com/Brander-ua/BTextInputFilter))
43 | - `func didBeginEditing()` was removed
44 | - `func shouldChangeTextIn(textInput:)` was removed
45 |
46 | ### Removed classes
47 |
48 | - `MulticastDelegate`
49 | - `TextInput`
50 | - `TextInputDelegate`
51 | - `AttributedTextInputField`
52 | - `AttributedTextInputView`
53 | - `TextInputField`
54 | - `TextInputFieldDelegate`
55 | - `TextInputView`
56 | - `TextInputViewDelegate`
57 | - `TextInputController`
58 |
--------------------------------------------------------------------------------
/Documentation/AnyFormatKit 2.4.0 MigrationGuide.md:
--------------------------------------------------------------------------------
1 | # AnyFormatKit 2.4.0 Migration Guide
2 |
3 | ## Breaking Changes
4 |
5 | - `TextFieldPlaceholderInputController` was renamed to `TextFieldStartInputController`
6 | - `TextViewPlaceholderInputController` was renamed to `TextViewStartInputController`
7 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment the next line to define a global platform for your project
2 | platform :ios, '9.0'
3 |
4 | target 'iOS Example' do
5 |
6 | use_frameworks!
7 |
8 | pod 'SnapKit', '~> 4.0.0'
9 | pod 'AnyFormatKit', :path => '../../'
10 |
11 | end
12 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - AnyFormatKit (2.5.1)
3 | - SnapKit (4.0.1)
4 |
5 | DEPENDENCIES:
6 | - AnyFormatKit (from `../../`)
7 | - SnapKit (~> 4.0.0)
8 |
9 | SPEC REPOS:
10 | trunk:
11 | - SnapKit
12 |
13 | EXTERNAL SOURCES:
14 | AnyFormatKit:
15 | :path: "../../"
16 |
17 | SPEC CHECKSUMS:
18 | AnyFormatKit: 4ef60ad3f48c69962d482bb2de0a6d3214e8527b
19 | SnapKit: 0de968a9fec17499afa29683b05d0c775b6d1c29
20 |
21 | PODFILE CHECKSUM: 64ea4beb092a0aaf133ee0f812f932e72d0f81b1
22 |
23 | COCOAPODS: 1.10.1
24 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/Local Podspecs/AnyFormatKit.podspec.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "AnyFormatKit",
3 | "version": "2.5.1",
4 | "summary": "Simple text formatting in Swift.",
5 | "description": "This framework provide to format text with format like \"## ##-###\", where # - replaceble symbol. Support format all string or character by character input.",
6 | "homepage": "https://github.com/luximetr/AnyFormatKit",
7 | "license": {
8 | "type": "MIT",
9 | "file": "LICENSE"
10 | },
11 | "authors": {
12 | "luximetr": "luximetr.notification@gmail.com"
13 | },
14 | "source": {
15 | "git": "https://github.com/luximetr/AnyFormatKit.git",
16 | "tag": "2.5.1"
17 | },
18 | "platforms": {
19 | "ios": "9.0"
20 | },
21 | "swift_versions": "5.0",
22 | "source_files": "Source/**/*",
23 | "swift_version": "5.0"
24 | }
25 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/Manifest.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - AnyFormatKit (2.5.1)
3 | - SnapKit (4.0.1)
4 |
5 | DEPENDENCIES:
6 | - AnyFormatKit (from `../../`)
7 | - SnapKit (~> 4.0.0)
8 |
9 | SPEC REPOS:
10 | trunk:
11 | - SnapKit
12 |
13 | EXTERNAL SOURCES:
14 | AnyFormatKit:
15 | :path: "../../"
16 |
17 | SPEC CHECKSUMS:
18 | AnyFormatKit: 4ef60ad3f48c69962d482bb2de0a6d3214e8527b
19 | SnapKit: 0de968a9fec17499afa29683b05d0c775b6d1c29
20 |
21 | PODFILE CHECKSUM: 64ea4beb092a0aaf133ee0f812f932e72d0f81b1
22 |
23 | COCOAPODS: 1.10.1
24 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/SnapKit/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
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
11 | all 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
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/SnapKit/Source/ConstraintConfig.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | public typealias ConstraintInterfaceLayoutDirection = UIUserInterfaceLayoutDirection
27 | #else
28 | import AppKit
29 | public typealias ConstraintInterfaceLayoutDirection = NSUserInterfaceLayoutDirection
30 | #endif
31 |
32 |
33 | public struct ConstraintConfig {
34 |
35 | public static var interfaceLayoutDirection: ConstraintInterfaceLayoutDirection = .leftToRight
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/SnapKit/Source/ConstraintDescription.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #else
27 | import AppKit
28 | #endif
29 |
30 |
31 | public class ConstraintDescription {
32 |
33 | internal let item: LayoutConstraintItem
34 | internal var attributes: ConstraintAttributes
35 | internal var relation: ConstraintRelation? = nil
36 | internal var sourceLocation: (String, UInt)? = nil
37 | internal var label: String? = nil
38 | internal var related: ConstraintItem? = nil
39 | internal var multiplier: ConstraintMultiplierTarget = 1.0
40 | internal var constant: ConstraintConstantTarget = 0.0
41 | internal var priority: ConstraintPriorityTarget = 1000.0
42 | internal lazy var constraint: Constraint? = {
43 | guard let relation = self.relation,
44 | let related = self.related,
45 | let sourceLocation = self.sourceLocation else {
46 | return nil
47 | }
48 | let from = ConstraintItem(target: self.item, attributes: self.attributes)
49 |
50 | return Constraint(
51 | from: from,
52 | to: related,
53 | relation: relation,
54 | sourceLocation: sourceLocation,
55 | label: self.label,
56 | multiplier: self.multiplier,
57 | constant: self.constant,
58 | priority: self.priority
59 | )
60 | }()
61 |
62 | // MARK: Initialization
63 |
64 | internal init(item: LayoutConstraintItem, attributes: ConstraintAttributes) {
65 | self.item = item
66 | self.attributes = attributes
67 | }
68 |
69 | }
70 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/SnapKit/Source/ConstraintInsetTarget.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #else
27 | import AppKit
28 | #endif
29 |
30 |
31 | public protocol ConstraintInsetTarget: ConstraintConstantTarget {
32 | }
33 |
34 | extension Int: ConstraintInsetTarget {
35 | }
36 |
37 | extension UInt: ConstraintInsetTarget {
38 | }
39 |
40 | extension Float: ConstraintInsetTarget {
41 | }
42 |
43 | extension Double: ConstraintInsetTarget {
44 | }
45 |
46 | extension CGFloat: ConstraintInsetTarget {
47 | }
48 |
49 | extension ConstraintInsets: ConstraintInsetTarget {
50 | }
51 |
52 | extension ConstraintInsetTarget {
53 |
54 | internal var constraintInsetTargetValue: ConstraintInsets {
55 | if let amount = self as? ConstraintInsets {
56 | return amount
57 | } else if let amount = self as? Float {
58 | return ConstraintInsets(top: CGFloat(amount), left: CGFloat(amount), bottom: CGFloat(amount), right: CGFloat(amount))
59 | } else if let amount = self as? Double {
60 | return ConstraintInsets(top: CGFloat(amount), left: CGFloat(amount), bottom: CGFloat(amount), right: CGFloat(amount))
61 | } else if let amount = self as? CGFloat {
62 | return ConstraintInsets(top: amount, left: amount, bottom: amount, right: amount)
63 | } else if let amount = self as? Int {
64 | return ConstraintInsets(top: CGFloat(amount), left: CGFloat(amount), bottom: CGFloat(amount), right: CGFloat(amount))
65 | } else if let amount = self as? UInt {
66 | return ConstraintInsets(top: CGFloat(amount), left: CGFloat(amount), bottom: CGFloat(amount), right: CGFloat(amount))
67 | } else {
68 | return ConstraintInsets(top: 0, left: 0, bottom: 0, right: 0)
69 | }
70 | }
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/SnapKit/Source/ConstraintInsets.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #else
27 | import AppKit
28 | #endif
29 |
30 |
31 | #if os(iOS) || os(tvOS)
32 | public typealias ConstraintInsets = UIEdgeInsets
33 | #else
34 | public typealias ConstraintInsets = NSEdgeInsets
35 | #endif
36 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/SnapKit/Source/ConstraintItem.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #else
27 | import AppKit
28 | #endif
29 |
30 |
31 | public final class ConstraintItem {
32 |
33 | internal weak var target: AnyObject?
34 | internal let attributes: ConstraintAttributes
35 |
36 | internal init(target: AnyObject?, attributes: ConstraintAttributes) {
37 | self.target = target
38 | self.attributes = attributes
39 | }
40 |
41 | internal var layoutConstraintItem: LayoutConstraintItem? {
42 | return self.target as? LayoutConstraintItem
43 | }
44 |
45 | }
46 |
47 | public func ==(lhs: ConstraintItem, rhs: ConstraintItem) -> Bool {
48 | // pointer equality
49 | guard lhs !== rhs else {
50 | return true
51 | }
52 |
53 | // must both have valid targets and identical attributes
54 | guard let target1 = lhs.target,
55 | let target2 = rhs.target,
56 | target1 === target2 && lhs.attributes == rhs.attributes else {
57 | return false
58 | }
59 |
60 | return true
61 | }
62 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/SnapKit/Source/ConstraintLayoutGuide+Extensions.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #endif
27 |
28 |
29 | @available(iOS 9.0, OSX 10.11, *)
30 | public extension ConstraintLayoutGuide {
31 |
32 | public var snp: ConstraintLayoutGuideDSL {
33 | return ConstraintLayoutGuideDSL(guide: self)
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/SnapKit/Source/ConstraintLayoutGuide.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #else
27 | import AppKit
28 | #endif
29 |
30 |
31 | #if os(iOS) || os(tvOS)
32 | @available(iOS 9.0, *)
33 | public typealias ConstraintLayoutGuide = UILayoutGuide
34 | #else
35 | @available(OSX 10.11, *)
36 | public typealias ConstraintLayoutGuide = NSLayoutGuide
37 | #endif
38 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/SnapKit/Source/ConstraintLayoutGuideDSL.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #else
27 | import AppKit
28 | #endif
29 |
30 |
31 | @available(iOS 9.0, OSX 10.11, *)
32 | public struct ConstraintLayoutGuideDSL: ConstraintAttributesDSL {
33 |
34 | @discardableResult
35 | public func prepareConstraints(_ closure: (_ make: ConstraintMaker) -> Void) -> [Constraint] {
36 | return ConstraintMaker.prepareConstraints(item: self.guide, closure: closure)
37 | }
38 |
39 | public func makeConstraints(_ closure: (_ make: ConstraintMaker) -> Void) {
40 | ConstraintMaker.makeConstraints(item: self.guide, closure: closure)
41 | }
42 |
43 | public func remakeConstraints(_ closure: (_ make: ConstraintMaker) -> Void) {
44 | ConstraintMaker.remakeConstraints(item: self.guide, closure: closure)
45 | }
46 |
47 | public func updateConstraints(_ closure: (_ make: ConstraintMaker) -> Void) {
48 | ConstraintMaker.updateConstraints(item: self.guide, closure: closure)
49 | }
50 |
51 | public func removeConstraints() {
52 | ConstraintMaker.removeConstraints(item: self.guide)
53 | }
54 |
55 | public var target: AnyObject? {
56 | return self.guide
57 | }
58 |
59 | internal let guide: ConstraintLayoutGuide
60 |
61 | internal init(guide: ConstraintLayoutGuide) {
62 | self.guide = guide
63 |
64 | }
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/SnapKit/Source/ConstraintLayoutSupport.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #else
27 | import AppKit
28 | #endif
29 |
30 |
31 | #if os(iOS) || os(tvOS)
32 | @available(iOS 8.0, *)
33 | public typealias ConstraintLayoutSupport = UILayoutSupport
34 | #else
35 | public class ConstraintLayoutSupport {}
36 | #endif
37 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/SnapKit/Source/ConstraintLayoutSupportDSL.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #else
27 | import AppKit
28 | #endif
29 |
30 |
31 | @available(iOS 8.0, *)
32 | public struct ConstraintLayoutSupportDSL: ConstraintDSL {
33 |
34 | public var target: AnyObject? {
35 | return self.support
36 | }
37 |
38 | internal let support: ConstraintLayoutSupport
39 |
40 | internal init(support: ConstraintLayoutSupport) {
41 | self.support = support
42 |
43 | }
44 |
45 | public var top: ConstraintItem {
46 | return ConstraintItem(target: self.target, attributes: ConstraintAttributes.top)
47 | }
48 |
49 | public var bottom: ConstraintItem {
50 | return ConstraintItem(target: self.target, attributes: ConstraintAttributes.bottom)
51 | }
52 |
53 | public var height: ConstraintItem {
54 | return ConstraintItem(target: self.target, attributes: ConstraintAttributes.height)
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/SnapKit/Source/ConstraintMakerEditable.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #else
27 | import AppKit
28 | #endif
29 |
30 |
31 | public class ConstraintMakerEditable: ConstraintMakerPriortizable {
32 |
33 | @discardableResult
34 | public func multipliedBy(_ amount: ConstraintMultiplierTarget) -> ConstraintMakerEditable {
35 | self.description.multiplier = amount
36 | return self
37 | }
38 |
39 | @discardableResult
40 | public func dividedBy(_ amount: ConstraintMultiplierTarget) -> ConstraintMakerEditable {
41 | return self.multipliedBy(1.0 / amount.constraintMultiplierTargetValue)
42 | }
43 |
44 | @discardableResult
45 | public func offset(_ amount: ConstraintOffsetTarget) -> ConstraintMakerEditable {
46 | self.description.constant = amount.constraintOffsetTargetValue
47 | return self
48 | }
49 |
50 | @discardableResult
51 | public func inset(_ amount: ConstraintInsetTarget) -> ConstraintMakerEditable {
52 | self.description.constant = amount.constraintInsetTargetValue
53 | return self
54 | }
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/SnapKit/Source/ConstraintMakerFinalizable.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #else
27 | import AppKit
28 | #endif
29 |
30 |
31 | public class ConstraintMakerFinalizable {
32 |
33 | internal let description: ConstraintDescription
34 |
35 | internal init(_ description: ConstraintDescription) {
36 | self.description = description
37 | }
38 |
39 | @discardableResult
40 | public func labeled(_ label: String) -> ConstraintMakerFinalizable {
41 | self.description.label = label
42 | return self
43 | }
44 |
45 | public var constraint: Constraint {
46 | return self.description.constraint!
47 | }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/SnapKit/Source/ConstraintMakerPriortizable.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #else
27 | import AppKit
28 | #endif
29 |
30 |
31 | public class ConstraintMakerPriortizable: ConstraintMakerFinalizable {
32 |
33 | @discardableResult
34 | public func priority(_ amount: ConstraintPriority) -> ConstraintMakerFinalizable {
35 | self.description.priority = amount.value
36 | return self
37 | }
38 |
39 | @discardableResult
40 | public func priority(_ amount: ConstraintPriorityTarget) -> ConstraintMakerFinalizable {
41 | self.description.priority = amount
42 | return self
43 | }
44 |
45 | @available(*, deprecated:3.0, message:"Use priority(.required) instead.")
46 | @discardableResult
47 | public func priorityRequired() -> ConstraintMakerFinalizable {
48 | return self.priority(.required)
49 | }
50 |
51 | @available(*, deprecated:3.0, message:"Use priority(.high) instead.")
52 | @discardableResult
53 | public func priorityHigh() -> ConstraintMakerFinalizable {
54 | return self.priority(.high)
55 | }
56 |
57 | @available(*, deprecated:3.0, message:"Use priority(.medium) instead.")
58 | @discardableResult
59 | public func priorityMedium() -> ConstraintMakerFinalizable {
60 | return self.priority(.medium)
61 | }
62 |
63 | @available(*, deprecated:3.0, message:"Use priority(.low) instead.")
64 | @discardableResult
65 | public func priorityLow() -> ConstraintMakerFinalizable {
66 | return self.priority(.low)
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/SnapKit/Source/ConstraintMultiplierTarget.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #else
27 | import AppKit
28 | #endif
29 |
30 |
31 | public protocol ConstraintMultiplierTarget {
32 |
33 | var constraintMultiplierTargetValue: CGFloat { get }
34 |
35 | }
36 |
37 | extension Int: ConstraintMultiplierTarget {
38 |
39 | public var constraintMultiplierTargetValue: CGFloat {
40 | return CGFloat(self)
41 | }
42 |
43 | }
44 |
45 | extension UInt: ConstraintMultiplierTarget {
46 |
47 | public var constraintMultiplierTargetValue: CGFloat {
48 | return CGFloat(self)
49 | }
50 |
51 | }
52 |
53 | extension Float: ConstraintMultiplierTarget {
54 |
55 | public var constraintMultiplierTargetValue: CGFloat {
56 | return CGFloat(self)
57 | }
58 |
59 | }
60 |
61 | extension Double: ConstraintMultiplierTarget {
62 |
63 | public var constraintMultiplierTargetValue: CGFloat {
64 | return CGFloat(self)
65 | }
66 |
67 | }
68 |
69 | extension CGFloat: ConstraintMultiplierTarget {
70 |
71 | public var constraintMultiplierTargetValue: CGFloat {
72 | return self
73 | }
74 |
75 | }
76 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/SnapKit/Source/ConstraintOffsetTarget.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #else
27 | import AppKit
28 | #endif
29 |
30 |
31 | public protocol ConstraintOffsetTarget: ConstraintConstantTarget {
32 | }
33 |
34 | extension Int: ConstraintOffsetTarget {
35 | }
36 |
37 | extension UInt: ConstraintOffsetTarget {
38 | }
39 |
40 | extension Float: ConstraintOffsetTarget {
41 | }
42 |
43 | extension Double: ConstraintOffsetTarget {
44 | }
45 |
46 | extension CGFloat: ConstraintOffsetTarget {
47 | }
48 |
49 | extension ConstraintOffsetTarget {
50 |
51 | internal var constraintOffsetTargetValue: CGFloat {
52 | let offset: CGFloat
53 | if let amount = self as? Float {
54 | offset = CGFloat(amount)
55 | } else if let amount = self as? Double {
56 | offset = CGFloat(amount)
57 | } else if let amount = self as? CGFloat {
58 | offset = CGFloat(amount)
59 | } else if let amount = self as? Int {
60 | offset = CGFloat(amount)
61 | } else if let amount = self as? UInt {
62 | offset = CGFloat(amount)
63 | } else {
64 | offset = 0.0
65 | }
66 | return offset
67 | }
68 |
69 | }
70 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/SnapKit/Source/ConstraintPriority.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #else
27 | import AppKit
28 | #endif
29 |
30 | public struct ConstraintPriority : ExpressibleByFloatLiteral, Equatable, Strideable {
31 | public typealias FloatLiteralType = Float
32 |
33 | public let value: Float
34 |
35 | public init(floatLiteral value: Float) {
36 | self.value = value
37 | }
38 |
39 | public init(_ value: Float) {
40 | self.value = value
41 | }
42 |
43 | public static var required: ConstraintPriority {
44 | return 1000.0
45 | }
46 |
47 | public static var high: ConstraintPriority {
48 | return 750.0
49 | }
50 |
51 | public static var medium: ConstraintPriority {
52 | #if os(OSX)
53 | return 501.0
54 | #else
55 | return 500.0
56 | #endif
57 |
58 | }
59 |
60 | public static var low: ConstraintPriority {
61 | return 250.0
62 | }
63 |
64 | public static func ==(lhs: ConstraintPriority, rhs: ConstraintPriority) -> Bool {
65 | return lhs.value == rhs.value
66 | }
67 |
68 | // MARK: Strideable
69 |
70 | public func advanced(by n: FloatLiteralType) -> ConstraintPriority {
71 | return ConstraintPriority(floatLiteral: value + n)
72 | }
73 |
74 | public func distance(to other: ConstraintPriority) -> FloatLiteralType {
75 | return other.value - value
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/SnapKit/Source/ConstraintPriorityTarget.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #else
27 | import AppKit
28 | #endif
29 |
30 |
31 | public protocol ConstraintPriorityTarget {
32 |
33 | var constraintPriorityTargetValue: Float { get }
34 |
35 | }
36 |
37 | extension Int: ConstraintPriorityTarget {
38 |
39 | public var constraintPriorityTargetValue: Float {
40 | return Float(self)
41 | }
42 |
43 | }
44 |
45 | extension UInt: ConstraintPriorityTarget {
46 |
47 | public var constraintPriorityTargetValue: Float {
48 | return Float(self)
49 | }
50 |
51 | }
52 |
53 | extension Float: ConstraintPriorityTarget {
54 |
55 | public var constraintPriorityTargetValue: Float {
56 | return self
57 | }
58 |
59 | }
60 |
61 | extension Double: ConstraintPriorityTarget {
62 |
63 | public var constraintPriorityTargetValue: Float {
64 | return Float(self)
65 | }
66 |
67 | }
68 |
69 | extension CGFloat: ConstraintPriorityTarget {
70 |
71 | public var constraintPriorityTargetValue: Float {
72 | return Float(self)
73 | }
74 |
75 | }
76 |
77 | #if os(iOS) || os(tvOS)
78 | extension UILayoutPriority: ConstraintPriorityTarget {
79 |
80 | public var constraintPriorityTargetValue: Float {
81 | return self.rawValue
82 | }
83 |
84 | }
85 | #endif
86 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/SnapKit/Source/ConstraintRelatableTarget.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #else
27 | import AppKit
28 | #endif
29 |
30 |
31 | public protocol ConstraintRelatableTarget {
32 | }
33 |
34 | extension Int: ConstraintRelatableTarget {
35 | }
36 |
37 | extension UInt: ConstraintRelatableTarget {
38 | }
39 |
40 | extension Float: ConstraintRelatableTarget {
41 | }
42 |
43 | extension Double: ConstraintRelatableTarget {
44 | }
45 |
46 | extension CGFloat: ConstraintRelatableTarget {
47 | }
48 |
49 | extension CGSize: ConstraintRelatableTarget {
50 | }
51 |
52 | extension CGPoint: ConstraintRelatableTarget {
53 | }
54 |
55 | extension ConstraintInsets: ConstraintRelatableTarget {
56 | }
57 |
58 | extension ConstraintItem: ConstraintRelatableTarget {
59 | }
60 |
61 | extension ConstraintView: ConstraintRelatableTarget {
62 | }
63 |
64 | @available(iOS 9.0, OSX 10.11, *)
65 | extension ConstraintLayoutGuide: ConstraintRelatableTarget {
66 | }
67 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/SnapKit/Source/ConstraintRelation.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #else
27 | import AppKit
28 | #endif
29 |
30 |
31 | internal enum ConstraintRelation : Int {
32 | case equal = 1
33 | case lessThanOrEqual
34 | case greaterThanOrEqual
35 |
36 | internal var layoutRelation: LayoutRelation {
37 | get {
38 | switch(self) {
39 | case .equal:
40 | return .equal
41 | case .lessThanOrEqual:
42 | return .lessThanOrEqual
43 | case .greaterThanOrEqual:
44 | return .greaterThanOrEqual
45 | }
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/SnapKit/Source/ConstraintView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #else
27 | import AppKit
28 | #endif
29 |
30 |
31 | #if os(iOS) || os(tvOS)
32 | public typealias ConstraintView = UIView
33 | #else
34 | public typealias ConstraintView = NSView
35 | #endif
36 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/SnapKit/Source/LayoutConstraint.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #else
27 | import AppKit
28 | #endif
29 |
30 |
31 | public class LayoutConstraint : NSLayoutConstraint {
32 |
33 | public var label: String? {
34 | get {
35 | return self.identifier
36 | }
37 | set {
38 | self.identifier = newValue
39 | }
40 | }
41 |
42 | internal weak var constraint: Constraint? = nil
43 |
44 | }
45 |
46 | internal func ==(lhs: LayoutConstraint, rhs: LayoutConstraint) -> Bool {
47 | guard lhs.firstItem === rhs.firstItem &&
48 | lhs.secondItem === rhs.secondItem &&
49 | lhs.firstAttribute == rhs.firstAttribute &&
50 | lhs.secondAttribute == rhs.secondAttribute &&
51 | lhs.relation == rhs.relation &&
52 | lhs.priority == rhs.priority &&
53 | lhs.multiplier == rhs.multiplier else {
54 | return false
55 | }
56 | return true
57 | }
58 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/SnapKit/Source/LayoutConstraintItem.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #else
27 | import AppKit
28 | #endif
29 |
30 |
31 | public protocol LayoutConstraintItem: class {
32 | }
33 |
34 | @available(iOS 9.0, OSX 10.11, *)
35 | extension ConstraintLayoutGuide : LayoutConstraintItem {
36 | }
37 |
38 | extension ConstraintView : LayoutConstraintItem {
39 | }
40 |
41 |
42 | extension LayoutConstraintItem {
43 |
44 | internal func prepare() {
45 | if let view = self as? ConstraintView {
46 | view.translatesAutoresizingMaskIntoConstraints = false
47 | }
48 | }
49 |
50 | internal var superview: ConstraintView? {
51 | if let view = self as? ConstraintView {
52 | return view.superview
53 | }
54 |
55 | if #available(iOS 9.0, OSX 10.11, *), let guide = self as? ConstraintLayoutGuide {
56 | return guide.owningView
57 | }
58 |
59 | return nil
60 | }
61 | internal var constraints: [Constraint] {
62 | return self.constraintsSet.allObjects as! [Constraint]
63 | }
64 |
65 | internal func add(constraints: [Constraint]) {
66 | let constraintsSet = self.constraintsSet
67 | for constraint in constraints {
68 | constraintsSet.add(constraint)
69 | }
70 | }
71 |
72 | internal func remove(constraints: [Constraint]) {
73 | let constraintsSet = self.constraintsSet
74 | for constraint in constraints {
75 | constraintsSet.remove(constraint)
76 | }
77 | }
78 |
79 | private var constraintsSet: NSMutableSet {
80 | let constraintsSet: NSMutableSet
81 |
82 | if let existing = objc_getAssociatedObject(self, &constraintsKey) as? NSMutableSet {
83 | constraintsSet = existing
84 | } else {
85 | constraintsSet = NSMutableSet()
86 | objc_setAssociatedObject(self, &constraintsKey, constraintsSet, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
87 | }
88 | return constraintsSet
89 |
90 | }
91 |
92 | }
93 | private var constraintsKey: UInt8 = 0
94 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/SnapKit/Source/Typealiases.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | import Foundation
25 |
26 | #if os(iOS) || os(tvOS)
27 | import UIKit
28 | #if swift(>=4.2)
29 | typealias LayoutRelation = NSLayoutConstraint.Relation
30 | typealias LayoutAttribute = NSLayoutConstraint.Attribute
31 | #else
32 | typealias LayoutRelation = NSLayoutRelation
33 | typealias LayoutAttribute = NSLayoutAttribute
34 | #endif
35 | typealias LayoutPriority = UILayoutPriority
36 | #else
37 | import AppKit
38 | typealias LayoutRelation = NSLayoutConstraint.Relation
39 | typealias LayoutAttribute = NSLayoutConstraint.Attribute
40 | typealias LayoutPriority = NSLayoutConstraint.Priority
41 | #endif
42 |
43 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/SnapKit/Source/UILayoutSupport+Extensions.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SnapKit
3 | //
4 | // Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
5 | //
6 | // Permission is hereby granted, free of charge, to any person obtaining a copy
7 | // of this software and associated documentation files (the "Software"), to deal
8 | // in the Software without restriction, including without limitation the rights
9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | // copies of the Software, and to permit persons to whom the Software is
11 | // furnished to do so, subject to the following conditions:
12 | //
13 | // The above copyright notice and this permission notice shall be included in
14 | // all copies or substantial portions of the Software.
15 | //
16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | // THE SOFTWARE.
23 |
24 | #if os(iOS) || os(tvOS)
25 | import UIKit
26 | #endif
27 |
28 |
29 | @available(iOS 8.0, *)
30 | public extension ConstraintLayoutSupport {
31 |
32 | public var snp: ConstraintLayoutSupportDSL {
33 | return ConstraintLayoutSupportDSL(support: self)
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/Target Support Files/AnyFormatKit/AnyFormatKit-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 | 2.5.1
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${CURRENT_PROJECT_VERSION}
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/Target Support Files/AnyFormatKit/AnyFormatKit-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_AnyFormatKit : NSObject
3 | @end
4 | @implementation PodsDummy_AnyFormatKit
5 | @end
6 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/Target Support Files/AnyFormatKit/AnyFormatKit-prefix.pch:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/Target Support Files/AnyFormatKit/AnyFormatKit-umbrella.h:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
14 | FOUNDATION_EXPORT double AnyFormatKitVersionNumber;
15 | FOUNDATION_EXPORT const unsigned char AnyFormatKitVersionString[];
16 |
17 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/Target Support Files/AnyFormatKit/AnyFormatKit.debug.xcconfig:
--------------------------------------------------------------------------------
1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/AnyFormatKit
3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
4 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
5 | PODS_BUILD_DIR = ${BUILD_DIR}
6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
7 | PODS_ROOT = ${SRCROOT}
8 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../../..
9 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
10 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
11 | SKIP_INSTALL = YES
12 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
13 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/Target Support Files/AnyFormatKit/AnyFormatKit.modulemap:
--------------------------------------------------------------------------------
1 | framework module AnyFormatKit {
2 | umbrella header "AnyFormatKit-umbrella.h"
3 |
4 | export *
5 | module * { export * }
6 | }
7 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/Target Support Files/AnyFormatKit/AnyFormatKit.release.xcconfig:
--------------------------------------------------------------------------------
1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/AnyFormatKit
3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
4 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
5 | PODS_BUILD_DIR = ${BUILD_DIR}
6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
7 | PODS_ROOT = ${SRCROOT}
8 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../../..
9 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
10 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
11 | SKIP_INSTALL = YES
12 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
13 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/Target Support Files/Pods-iOS Example/Pods-iOS Example-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | ${PRODUCT_BUNDLE_IDENTIFIER}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | ${PRODUCT_NAME}
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${CURRENT_PROJECT_VERSION}
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/Target Support Files/Pods-iOS Example/Pods-iOS Example-acknowledgements.markdown:
--------------------------------------------------------------------------------
1 | # Acknowledgements
2 | This application makes use of the following third party libraries:
3 |
4 | ## AnyFormatKit
5 |
6 | Copyright (c) 2021 luximetr
7 |
8 | Permission is hereby granted, free of charge, to any person obtaining a copy
9 | of this software and associated documentation files (the "Software"), to deal
10 | in the Software without restriction, including without limitation the rights
11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 | copies of the Software, and to permit persons to whom the Software is
13 | furnished to do so, subject to the following conditions:
14 |
15 | The above copyright notice and this permission notice shall be included in
16 | all copies or substantial portions of the Software.
17 |
18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 | THE SOFTWARE.
25 |
26 |
27 | ## SnapKit
28 |
29 | Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit
30 |
31 | Permission is hereby granted, free of charge, to any person obtaining a copy
32 | of this software and associated documentation files (the "Software"), to deal
33 | in the Software without restriction, including without limitation the rights
34 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
35 | copies of the Software, and to permit persons to whom the Software is
36 | furnished to do so, subject to the following conditions:
37 |
38 | The above copyright notice and this permission notice shall be included in
39 | all copies or substantial portions of the Software.
40 |
41 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
42 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
43 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
44 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
45 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
46 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
47 | THE SOFTWARE.
48 |
49 | Generated by CocoaPods - https://cocoapods.org
50 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/Target Support Files/Pods-iOS Example/Pods-iOS Example-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_Pods_iOS_Example : NSObject
3 | @end
4 | @implementation PodsDummy_Pods_iOS_Example
5 | @end
6 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/Target Support Files/Pods-iOS Example/Pods-iOS Example-umbrella.h:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
14 | FOUNDATION_EXPORT double Pods_iOS_ExampleVersionNumber;
15 | FOUNDATION_EXPORT const unsigned char Pods_iOS_ExampleVersionString[];
16 |
17 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/Target Support Files/Pods-iOS Example/Pods-iOS Example.debug.xcconfig:
--------------------------------------------------------------------------------
1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
2 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AnyFormatKit" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit"
4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
5 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AnyFormatKit/AnyFormatKit.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit/SnapKit.framework/Headers"
6 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
7 | OTHER_LDFLAGS = $(inherited) -framework "AnyFormatKit" -framework "SnapKit"
8 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
9 | PODS_BUILD_DIR = ${BUILD_DIR}
10 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
11 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
12 | PODS_ROOT = ${SRCROOT}/Pods
13 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
14 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
15 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/Target Support Files/Pods-iOS Example/Pods-iOS Example.modulemap:
--------------------------------------------------------------------------------
1 | framework module Pods_iOS_Example {
2 | umbrella header "Pods-iOS Example-umbrella.h"
3 |
4 | export *
5 | module * { export * }
6 | }
7 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/Target Support Files/Pods-iOS Example/Pods-iOS Example.release.xcconfig:
--------------------------------------------------------------------------------
1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
2 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AnyFormatKit" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit"
4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
5 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AnyFormatKit/AnyFormatKit.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit/SnapKit.framework/Headers"
6 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
7 | OTHER_LDFLAGS = $(inherited) -framework "AnyFormatKit" -framework "SnapKit"
8 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
9 | PODS_BUILD_DIR = ${BUILD_DIR}
10 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
11 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
12 | PODS_ROOT = ${SRCROOT}/Pods
13 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
14 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
15 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/Target Support Files/SnapKit/SnapKit-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 | 4.0.1
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${CURRENT_PROJECT_VERSION}
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/Target Support Files/SnapKit/SnapKit-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_SnapKit : NSObject
3 | @end
4 | @implementation PodsDummy_SnapKit
5 | @end
6 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/Target Support Files/SnapKit/SnapKit-prefix.pch:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/Target Support Files/SnapKit/SnapKit-umbrella.h:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #import
3 | #else
4 | #ifndef FOUNDATION_EXPORT
5 | #if defined(__cplusplus)
6 | #define FOUNDATION_EXPORT extern "C"
7 | #else
8 | #define FOUNDATION_EXPORT extern
9 | #endif
10 | #endif
11 | #endif
12 |
13 |
14 | FOUNDATION_EXPORT double SnapKitVersionNumber;
15 | FOUNDATION_EXPORT const unsigned char SnapKitVersionString[];
16 |
17 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/Target Support Files/SnapKit/SnapKit.debug.xcconfig:
--------------------------------------------------------------------------------
1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SnapKit
3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
4 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
5 | PODS_BUILD_DIR = ${BUILD_DIR}
6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
7 | PODS_ROOT = ${SRCROOT}
8 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/SnapKit
9 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
10 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
11 | SKIP_INSTALL = YES
12 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
13 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/Target Support Files/SnapKit/SnapKit.modulemap:
--------------------------------------------------------------------------------
1 | framework module SnapKit {
2 | umbrella header "SnapKit-umbrella.h"
3 |
4 | export *
5 | module * { export * }
6 | }
7 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/Pods/Target Support Files/SnapKit/SnapKit.release.xcconfig:
--------------------------------------------------------------------------------
1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO
2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SnapKit
3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
4 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
5 | PODS_BUILD_DIR = ${BUILD_DIR}
6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
7 | PODS_ROOT = ${SRCROOT}
8 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/SnapKit
9 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates
10 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
11 | SKIP_INSTALL = YES
12 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
13 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/iOS Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/iOS Example.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/iOS Example.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/iOS Example/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // iOS Example
4 | //
5 | // Created by Oleksandr Orlov on 01.11.2017.
6 | // Copyright © 2017 Oleksandr Orlov. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(_ application: UIApplication) {
23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(_ application: UIApplication) {
28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(_ application: UIApplication) {
33 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | func applicationDidBecomeActive(_ application: UIApplication) {
37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
38 | }
39 |
40 | func applicationWillTerminate(_ application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/iOS Example/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/Example/CocoapodsExample/iOS Example/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/iOS Example/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/iOS Example/ExampleViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ExampleViewController.swift
3 | // iOS Example
4 | //
5 | // Created by Oleksandr Orlov on 24.01.2021.
6 | // Copyright © 2021 Oleksandr Orlov. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import AnyFormatKit
11 |
12 | class ExampleViewController: UIViewController {
13 |
14 | // MARK: - View
15 |
16 | private let selfView = ExampleView()
17 |
18 | // MARK: - Controllers
19 |
20 | let phoneNumberInputController = TextFieldInputController()
21 | let cardNumberInputController = TextFieldStartInputController()
22 | let cardExpirationInputController = TextFieldStartInputController()
23 | let cardCVVInputController = TextFieldStartInputController()
24 | let moneyInputController = TextFieldStartInputController()
25 |
26 | // MARK: - Formatters
27 |
28 | let phoneNumberFormatter = DefaultTextInputFormatter(textPattern: "+5# (###) ###-##-##")
29 | let cardNumberFormatter = PlaceholderTextInputFormatter(textPattern: "#### #### #### ####")
30 | let cardExpirationFormatter = PlaceholderTextInputFormatter(textPattern: "__/__", patternSymbol: "_")
31 | let cardCVVFormatter = PlaceholderTextInputFormatter(textPattern: "***", patternSymbol: "*")
32 | let moneyFormatter = SumTextInputFormatter(textPattern: "# ###,## $")
33 |
34 | // MARK: - View life cycle
35 |
36 | override func loadView() {
37 | view = selfView
38 | }
39 |
40 | override func viewDidLoad() {
41 | super.viewDidLoad()
42 | setup()
43 | }
44 |
45 | // MARK: - Setup
46 |
47 | private func setup() {
48 | setupPhoneNumberController()
49 | setupCardNumberController()
50 | setupCardExpirationController()
51 | setupCardCVVController()
52 | setupMoneyController()
53 | }
54 |
55 | // MARK: - Setup phoneNumber
56 | private func setupPhoneNumberController() {
57 | phoneNumberInputController.formatter = phoneNumberFormatter
58 | selfView.phoneNumberInputView.textField.delegate = phoneNumberInputController
59 | }
60 |
61 | // MARK: - Setup cardNumber
62 | private func setupCardNumberController() {
63 | cardNumberInputController.formatter = cardNumberFormatter
64 | selfView.cardNumberInputView.cardNumberTextField.delegate = cardNumberInputController
65 | selfView.cardNumberInputView.cardNumberTextField.text = cardNumberFormatter.format("")
66 | }
67 |
68 | private func setupCardExpirationController() {
69 | cardExpirationInputController.formatter = cardExpirationFormatter
70 | selfView.cardNumberInputView.expirationTextField.delegate = cardExpirationInputController
71 | selfView.cardNumberInputView.expirationTextField.text = cardExpirationFormatter.format("")
72 | }
73 |
74 | private func setupCardCVVController() {
75 | cardCVVInputController.formatter = cardCVVFormatter
76 | selfView.cardNumberInputView.cvvTextField.delegate = cardCVVInputController
77 | selfView.cardNumberInputView.cvvTextField.text = cardCVVFormatter.format("")
78 | }
79 |
80 | // MARK: - Setup money
81 |
82 | private func setupMoneyController() {
83 | moneyInputController.formatter = moneyFormatter
84 | selfView.moneyInputView.textField.delegate = moneyInputController
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/iOS Example/Helpers/CardInfoView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CardInfoView.swift
3 | // iOS Example
4 | //
5 | // Created by Oleksandr Orlov on 24.01.2021.
6 | // Copyright © 2021 Oleksandr Orlov. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class CardInfoView: InitView {
12 |
13 | // MARK: - UI elements
14 |
15 | let titleLabel = UILabel()
16 | let cardNumberTextField = UITextField()
17 | let expirationTextField = UITextField()
18 | let cvvTextField = UITextField()
19 |
20 | // MARK: - Setup
21 |
22 | override func setup() {
23 | super.setup()
24 | setupTitleLabel()
25 | setupCardNumberTextField()
26 | setupExpirationTextField()
27 | setupCvvTextField()
28 | }
29 |
30 | // MARK: - Prepare layout
31 |
32 | override func prepareLayout() {
33 | super.prepareLayout()
34 | addSubview(titleLabel)
35 | addSubview(cardNumberTextField)
36 | addSubview(expirationTextField)
37 | addSubview(cvvTextField)
38 | prepareLayoutTitleLabel()
39 | prepareLayoutCardNumberTextField()
40 | prepareLayoutExpirationTextField()
41 | prepareLayoutCvvTextField()
42 | }
43 |
44 | // MARK: - Setup titleLabel
45 |
46 | private func setupTitleLabel() {
47 | titleLabel.textColor = .white
48 | }
49 |
50 | private func prepareLayoutTitleLabel() {
51 | titleLabel.snp.makeConstraints { make in
52 | make.leading.top.trailing.equalToSuperview()
53 | }
54 | }
55 |
56 | // MARK: - Setup cardNumberTextField
57 |
58 | private func setupCardNumberTextField() {
59 | cardNumberTextField.backgroundColor = .darkGray
60 | cardNumberTextField.textColor = .white
61 | cardNumberTextField.font = UIFont.monospaced(ofSize: 18)
62 | }
63 |
64 | private func prepareLayoutCardNumberTextField() {
65 | cardNumberTextField.snp.makeConstraints { make in
66 | make.leading.trailing.equalToSuperview()
67 | make.top.equalTo(titleLabel.snp.bottom).offset(1)
68 | make.height.equalTo(44)
69 | }
70 | }
71 |
72 | // MARK: - Setup expirationTextField
73 |
74 | private func setupExpirationTextField() {
75 | expirationTextField.backgroundColor = .darkGray
76 | expirationTextField.textColor = .white
77 | expirationTextField.font = UIFont.monospaced(ofSize: 18)
78 | }
79 |
80 | private func prepareLayoutExpirationTextField() {
81 | expirationTextField.snp.makeConstraints { make in
82 | make.leading.bottom.equalToSuperview()
83 | make.width.equalTo(120)
84 | make.height.equalTo(44)
85 | make.top.equalTo(cardNumberTextField.snp.bottom).offset(1)
86 | }
87 | }
88 |
89 | // MARK: - Setup cvvTextField
90 |
91 | private func setupCvvTextField() {
92 | cvvTextField.backgroundColor = .darkGray
93 | cvvTextField.textColor = .white
94 | cvvTextField.font = UIFont.monospaced(ofSize: 18)
95 | }
96 |
97 | private func prepareLayoutCvvTextField() {
98 | cvvTextField.snp.makeConstraints { make in
99 | make.bottom.height.equalTo(expirationTextField)
100 | make.leading.equalTo(expirationTextField.snp.trailing).offset(1)
101 | make.width.equalTo(70)
102 | }
103 | }
104 |
105 | }
106 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/iOS Example/Helpers/InitView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // InitView.swift
3 | // iOS Example
4 | //
5 | // Created by Oleksandr Orlov on 24.01.2021.
6 | // Copyright © 2021 Oleksandr Orlov. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import SnapKit
11 |
12 | class InitView: UIView {
13 |
14 | convenience init() {
15 | self.init(frame: .zero)
16 | }
17 |
18 | override init(frame: CGRect) {
19 | super.init(frame: frame)
20 | intialSetup()
21 | }
22 |
23 | required init?(coder: NSCoder) {
24 | super.init(coder: coder)
25 | intialSetup()
26 | }
27 |
28 | private func intialSetup() {
29 | setup()
30 | prepareLayout()
31 | }
32 |
33 | func prepareLayout() {
34 |
35 | }
36 |
37 | func setup() {
38 |
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/iOS Example/Helpers/TitleTextFieldView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TitleTextFieldView.swift
3 | // iOS Example
4 | //
5 | // Created by Oleksandr Orlov on 24.01.2021.
6 | // Copyright © 2021 Oleksandr Orlov. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class TitleTextFieldView: InitView {
12 |
13 | // MARK: - UI elements
14 |
15 | let titleLabel = UILabel()
16 | let textField = UITextField()
17 |
18 | // MARK: - Setup
19 |
20 | override func setup() {
21 | super.setup()
22 | setupTitleLabel()
23 | setupTextField()
24 | }
25 |
26 | // MARK: - Prepare layout
27 |
28 | override func prepareLayout() {
29 | super.prepareLayout()
30 | addSubview(titleLabel)
31 | addSubview(textField)
32 | prepareLayoutTitleLabel()
33 | prepareLayoutTextField()
34 | }
35 |
36 | // MARK: - Setup titleLabel
37 |
38 | private func setupTitleLabel() {
39 | titleLabel.textColor = .white
40 | }
41 |
42 | private func prepareLayoutTitleLabel() {
43 | titleLabel.snp.makeConstraints { make in
44 | make.leading.top.trailing.equalToSuperview()
45 | }
46 | }
47 |
48 | // MARK: - Setup textField
49 |
50 | private func setupTextField() {
51 | textField.textColor = .white
52 | textField.backgroundColor = .darkGray
53 | textField.font = .monospaced(ofSize: 18)
54 | }
55 |
56 | private func prepareLayoutTextField() {
57 | textField.snp.makeConstraints { make in
58 | make.leading.trailing.equalTo(titleLabel)
59 | make.top.equalTo(titleLabel.snp.bottom).offset(1)
60 | make.bottom.equalToSuperview()
61 | make.height.equalTo(44)
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/iOS Example/Helpers/UIFont+Extension.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIFont+Extension.swift
3 | // iOS Example
4 | //
5 | // Created by Oleksandr Orlov on 24.01.2021.
6 | // Copyright © 2021 Oleksandr Orlov. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension UIFont {
12 |
13 | static func monospaced(ofSize: CGFloat) -> UIFont {
14 | if #available(iOS 13.0, *) {
15 | return UIFont.monospacedSystemFont(ofSize: ofSize, weight: .regular)
16 | } else if #available(iOS 9.0, *) {
17 | return UIFont.monospacedDigitSystemFont(ofSize: ofSize, weight: .regular)
18 | } else {
19 | return UIFont.init(name: "Helvetica Neue", size: ofSize) ?? UIFont()
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Example/CocoapodsExample/iOS Example/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIMainStoryboardFile
26 | Main
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UIStatusBarStyle
32 | UIStatusBarStyleLightContent
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | UISupportedInterfaceOrientations~ipad
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 |
46 | UIViewControllerBasedStatusBarAppearance
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/Example/SPMExample/AnyFormatKitSPMExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Example/SPMExample/AnyFormatKitSPMExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Example/SPMExample/AnyFormatKitSPMExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved:
--------------------------------------------------------------------------------
1 | {
2 | "object": {
3 | "pins": [
4 | {
5 | "package": "AnyFormatKit",
6 | "repositoryURL": "https://github.com/luximetr/AnyFormatKit",
7 | "state": {
8 | "branch": null,
9 | "revision": "27b35c984c1c81e74c8be5273f7b2dc5250cb5cc",
10 | "version": "2.5.1"
11 | }
12 | },
13 | {
14 | "package": "SnapKit",
15 | "repositoryURL": "https://github.com/SnapKit/SnapKit",
16 | "state": {
17 | "branch": null,
18 | "revision": "d458564516e5676af9c70b4f4b2a9178294f1bc6",
19 | "version": "5.0.1"
20 | }
21 | }
22 | ]
23 | },
24 | "version": 1
25 | }
26 |
--------------------------------------------------------------------------------
/Example/SPMExample/AnyFormatKitSPMExample/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // AnyFormatKitSPMExample
4 | //
5 | // Created by Oleksandr Orlov on 25.01.2022.
6 | //
7 |
8 | import UIKit
9 |
10 | @main
11 | class AppDelegate: UIResponder, UIApplicationDelegate {
12 |
13 |
14 |
15 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
16 | // Override point for customization after application launch.
17 | return true
18 | }
19 |
20 | // MARK: UISceneSession Lifecycle
21 |
22 | @available(iOS 13.0, *)
23 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
24 | // Called when a new scene session is being created.
25 | // Use this method to select a configuration to create the new scene with.
26 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
27 | }
28 |
29 | @available(iOS 13.0, *)
30 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
31 | // Called when the user discards a scene session.
32 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
33 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
34 | }
35 |
36 |
37 | }
38 |
39 |
--------------------------------------------------------------------------------
/Example/SPMExample/AnyFormatKitSPMExample/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Example/SPMExample/AnyFormatKitSPMExample/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "scale" : "2x",
6 | "size" : "20x20"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "scale" : "3x",
11 | "size" : "20x20"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "scale" : "2x",
16 | "size" : "29x29"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "scale" : "3x",
21 | "size" : "29x29"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "scale" : "2x",
26 | "size" : "40x40"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "scale" : "3x",
31 | "size" : "40x40"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "scale" : "2x",
36 | "size" : "60x60"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "scale" : "3x",
41 | "size" : "60x60"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "scale" : "1x",
46 | "size" : "20x20"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "scale" : "2x",
51 | "size" : "20x20"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "scale" : "1x",
56 | "size" : "29x29"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "scale" : "2x",
61 | "size" : "29x29"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "scale" : "1x",
66 | "size" : "40x40"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "scale" : "2x",
71 | "size" : "40x40"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "scale" : "1x",
76 | "size" : "76x76"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "scale" : "2x",
81 | "size" : "76x76"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "scale" : "2x",
86 | "size" : "83.5x83.5"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "scale" : "1x",
91 | "size" : "1024x1024"
92 | }
93 | ],
94 | "info" : {
95 | "author" : "xcode",
96 | "version" : 1
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/Example/SPMExample/AnyFormatKitSPMExample/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Example/SPMExample/AnyFormatKitSPMExample/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Example/SPMExample/AnyFormatKitSPMExample/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/Example/SPMExample/AnyFormatKitSPMExample/ExampleViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ExampleViewController.swift
3 | // AnyFormatKitSPMExample
4 | //
5 | // Created by Oleksandr Orlov on 25.01.2022.
6 | //
7 |
8 | import UIKit
9 | import AnyFormatKit
10 |
11 | class ExampleViewController: UIViewController {
12 |
13 | // MARK: - View
14 |
15 | private let selfView = ExampleView()
16 |
17 | // MARK: - Controllers
18 |
19 | let phoneNumberInputController = TextFieldInputController()
20 | let cardNumberInputController = TextFieldStartInputController()
21 | let cardExpirationInputController = TextFieldStartInputController()
22 | let cardCVVInputController = TextFieldStartInputController()
23 | let moneyInputController = TextFieldStartInputController()
24 |
25 | // MARK: - Formatters
26 |
27 | let phoneNumberFormatter = DefaultTextInputFormatter(textPattern: "+5# (###) ###-##-##")
28 | let cardNumberFormatter = PlaceholderTextInputFormatter(textPattern: "#### #### #### ####")
29 | let cardExpirationFormatter = PlaceholderTextInputFormatter(textPattern: "__/__", patternSymbol: "_")
30 | let cardCVVFormatter = PlaceholderTextInputFormatter(textPattern: "***", patternSymbol: "*")
31 | let moneyFormatter = SumTextInputFormatter(textPattern: "# ###,## $")
32 |
33 | // MARK: - View life cycle
34 |
35 | override func loadView() {
36 | view = selfView
37 | }
38 |
39 | override func viewDidLoad() {
40 | super.viewDidLoad()
41 | setup()
42 | }
43 |
44 | // MARK: - Setup
45 |
46 | private func setup() {
47 | setupPhoneNumberController()
48 | setupCardNumberController()
49 | setupCardExpirationController()
50 | setupCardCVVController()
51 | setupMoneyController()
52 | }
53 |
54 | // MARK: - Setup phoneNumber
55 | private func setupPhoneNumberController() {
56 | phoneNumberInputController.formatter = phoneNumberFormatter
57 | selfView.phoneNumberInputView.textField.delegate = phoneNumberInputController
58 | }
59 |
60 | // MARK: - Setup cardNumber
61 | private func setupCardNumberController() {
62 | cardNumberInputController.formatter = cardNumberFormatter
63 | selfView.cardNumberInputView.cardNumberTextField.delegate = cardNumberInputController
64 | selfView.cardNumberInputView.cardNumberTextField.text = cardNumberFormatter.format("")
65 | }
66 |
67 | private func setupCardExpirationController() {
68 | cardExpirationInputController.formatter = cardExpirationFormatter
69 | selfView.cardNumberInputView.expirationTextField.delegate = cardExpirationInputController
70 | selfView.cardNumberInputView.expirationTextField.text = cardExpirationFormatter.format("")
71 | }
72 |
73 | private func setupCardCVVController() {
74 | cardCVVInputController.formatter = cardCVVFormatter
75 | selfView.cardNumberInputView.cvvTextField.delegate = cardCVVInputController
76 | selfView.cardNumberInputView.cvvTextField.text = cardCVVFormatter.format("")
77 | }
78 |
79 | // MARK: - Setup money
80 |
81 | private func setupMoneyController() {
82 | moneyInputController.formatter = moneyFormatter
83 | selfView.moneyInputView.textField.delegate = moneyInputController
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/Example/SPMExample/AnyFormatKitSPMExample/Helpers/CardInfoView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CardInfoView.swift
3 | // AnyFormatKitSPMExample
4 | //
5 | // Created by Oleksandr Orlov on 25.01.2022.
6 | //
7 |
8 | import UIKit
9 |
10 | class CardInfoView: InitView {
11 |
12 | // MARK: - UI elements
13 |
14 | let titleLabel = UILabel()
15 | let cardNumberTextField = UITextField()
16 | let expirationTextField = UITextField()
17 | let cvvTextField = UITextField()
18 |
19 | // MARK: - Setup
20 |
21 | override func setup() {
22 | super.setup()
23 | setupTitleLabel()
24 | setupCardNumberTextField()
25 | setupExpirationTextField()
26 | setupCvvTextField()
27 | }
28 |
29 | // MARK: - Prepare layout
30 |
31 | override func prepareLayout() {
32 | super.prepareLayout()
33 | addSubview(titleLabel)
34 | addSubview(cardNumberTextField)
35 | addSubview(expirationTextField)
36 | addSubview(cvvTextField)
37 | prepareLayoutTitleLabel()
38 | prepareLayoutCardNumberTextField()
39 | prepareLayoutExpirationTextField()
40 | prepareLayoutCvvTextField()
41 | }
42 |
43 | // MARK: - Setup titleLabel
44 |
45 | private func setupTitleLabel() {
46 | titleLabel.textColor = .white
47 | }
48 |
49 | private func prepareLayoutTitleLabel() {
50 | titleLabel.snp.makeConstraints { make in
51 | make.leading.top.trailing.equalToSuperview()
52 | }
53 | }
54 |
55 | // MARK: - Setup cardNumberTextField
56 |
57 | private func setupCardNumberTextField() {
58 | cardNumberTextField.backgroundColor = .darkGray
59 | cardNumberTextField.textColor = .white
60 | cardNumberTextField.font = UIFont.monospaced(ofSize: 18)
61 | }
62 |
63 | private func prepareLayoutCardNumberTextField() {
64 | cardNumberTextField.snp.makeConstraints { make in
65 | make.leading.trailing.equalToSuperview()
66 | make.top.equalTo(titleLabel.snp.bottom).offset(1)
67 | make.height.equalTo(44)
68 | }
69 | }
70 |
71 | // MARK: - Setup expirationTextField
72 |
73 | private func setupExpirationTextField() {
74 | expirationTextField.backgroundColor = .darkGray
75 | expirationTextField.textColor = .white
76 | expirationTextField.font = UIFont.monospaced(ofSize: 18)
77 | }
78 |
79 | private func prepareLayoutExpirationTextField() {
80 | expirationTextField.snp.makeConstraints { make in
81 | make.leading.bottom.equalToSuperview()
82 | make.width.equalTo(120)
83 | make.height.equalTo(44)
84 | make.top.equalTo(cardNumberTextField.snp.bottom).offset(1)
85 | }
86 | }
87 |
88 | // MARK: - Setup cvvTextField
89 |
90 | private func setupCvvTextField() {
91 | cvvTextField.backgroundColor = .darkGray
92 | cvvTextField.textColor = .white
93 | cvvTextField.font = UIFont.monospaced(ofSize: 18)
94 | }
95 |
96 | private func prepareLayoutCvvTextField() {
97 | cvvTextField.snp.makeConstraints { make in
98 | make.bottom.height.equalTo(expirationTextField)
99 | make.leading.equalTo(expirationTextField.snp.trailing).offset(1)
100 | make.width.equalTo(70)
101 | }
102 | }
103 |
104 | }
105 |
--------------------------------------------------------------------------------
/Example/SPMExample/AnyFormatKitSPMExample/Helpers/InitView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // InitView.swift
3 | // AnyFormatKitSPMExample
4 | //
5 | // Created by Oleksandr Orlov on 25.01.2022.
6 | //
7 |
8 | import UIKit
9 | import SnapKit
10 |
11 | class InitView: UIView {
12 |
13 | convenience init() {
14 | self.init(frame: .zero)
15 | }
16 |
17 | override init(frame: CGRect) {
18 | super.init(frame: frame)
19 | intialSetup()
20 | }
21 |
22 | required init?(coder: NSCoder) {
23 | super.init(coder: coder)
24 | intialSetup()
25 | }
26 |
27 | private func intialSetup() {
28 | setup()
29 | prepareLayout()
30 | }
31 |
32 | func prepareLayout() {
33 |
34 | }
35 |
36 | func setup() {
37 |
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/Example/SPMExample/AnyFormatKitSPMExample/Helpers/TitleTextFieldView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TitleTextFieldView.swift
3 | // AnyFormatKitSPMExample
4 | //
5 | // Created by Oleksandr Orlov on 25.01.2022.
6 | //
7 |
8 | import UIKit
9 |
10 | class TitleTextFieldView: InitView {
11 |
12 | // MARK: - UI elements
13 |
14 | let titleLabel = UILabel()
15 | let textField = UITextField()
16 |
17 | // MARK: - Setup
18 |
19 | override func setup() {
20 | super.setup()
21 | setupTitleLabel()
22 | setupTextField()
23 | }
24 |
25 | // MARK: - Prepare layout
26 |
27 | override func prepareLayout() {
28 | super.prepareLayout()
29 | addSubview(titleLabel)
30 | addSubview(textField)
31 | prepareLayoutTitleLabel()
32 | prepareLayoutTextField()
33 | }
34 |
35 | // MARK: - Setup titleLabel
36 |
37 | private func setupTitleLabel() {
38 | titleLabel.textColor = .white
39 | }
40 |
41 | private func prepareLayoutTitleLabel() {
42 | titleLabel.snp.makeConstraints { make in
43 | make.leading.top.trailing.equalToSuperview()
44 | }
45 | }
46 |
47 | // MARK: - Setup textField
48 |
49 | private func setupTextField() {
50 | textField.textColor = .white
51 | textField.backgroundColor = .darkGray
52 | textField.font = .monospaced(ofSize: 18)
53 | }
54 |
55 | private func prepareLayoutTextField() {
56 | textField.snp.makeConstraints { make in
57 | make.leading.trailing.equalTo(titleLabel)
58 | make.top.equalTo(titleLabel.snp.bottom).offset(1)
59 | make.bottom.equalToSuperview()
60 | make.height.equalTo(44)
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/Example/SPMExample/AnyFormatKitSPMExample/Helpers/UIFont+Extension.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIFont+Extension.swift
3 | // AnyFormatKitSPMExample
4 | //
5 | // Created by Oleksandr Orlov on 25.01.2022.
6 | //
7 |
8 | import UIKit
9 |
10 | extension UIFont {
11 |
12 | static func monospaced(ofSize: CGFloat) -> UIFont {
13 | if #available(iOS 13.0, *) {
14 | return UIFont.monospacedSystemFont(ofSize: ofSize, weight: .regular)
15 | } else {
16 | return UIFont.monospacedDigitSystemFont(ofSize: ofSize, weight: .regular)
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Example/SPMExample/AnyFormatKitSPMExample/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UIApplicationSceneManifest
6 |
7 | UIApplicationSupportsMultipleScenes
8 |
9 | UISceneConfigurations
10 |
11 | UIWindowSceneSessionRoleApplication
12 |
13 |
14 | UISceneConfigurationName
15 | Default Configuration
16 | UISceneDelegateClassName
17 | $(PRODUCT_MODULE_NAME).SceneDelegate
18 | UISceneStoryboardFile
19 | Main
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Example/SPMExample/AnyFormatKitSPMExample/SceneDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SceneDelegate.swift
3 | // AnyFormatKitSPMExample
4 | //
5 | // Created by Oleksandr Orlov on 25.01.2022.
6 | //
7 |
8 | import UIKit
9 |
10 | class SceneDelegate: UIResponder, UIWindowSceneDelegate {
11 |
12 | var window: UIWindow?
13 |
14 |
15 | @available(iOS 13.0, *)
16 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
17 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
18 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
19 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
20 | guard let _ = (scene as? UIWindowScene) else { return }
21 | }
22 |
23 | @available(iOS 13.0, *)
24 | func sceneDidDisconnect(_ scene: UIScene) {
25 | // Called as the scene is being released by the system.
26 | // This occurs shortly after the scene enters the background, or when its session is discarded.
27 | // Release any resources associated with this scene that can be re-created the next time the scene connects.
28 | // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).
29 | }
30 |
31 | @available(iOS 13.0, *)
32 | func sceneDidBecomeActive(_ scene: UIScene) {
33 | // Called when the scene has moved from an inactive state to an active state.
34 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
35 | }
36 |
37 | @available(iOS 13.0, *)
38 | func sceneWillResignActive(_ scene: UIScene) {
39 | // Called when the scene will move from an active state to an inactive state.
40 | // This may occur due to temporary interruptions (ex. an incoming phone call).
41 | }
42 |
43 | @available(iOS 13.0, *)
44 | func sceneWillEnterForeground(_ scene: UIScene) {
45 | // Called as the scene transitions from the background to the foreground.
46 | // Use this method to undo the changes made on entering the background.
47 | }
48 |
49 | @available(iOS 13.0, *)
50 | func sceneDidEnterBackground(_ scene: UIScene) {
51 | // Called as the scene transitions from the foreground to the background.
52 | // Use this method to save data, release shared resources, and store enough scene-specific state information
53 | // to restore the scene back to its current state.
54 | }
55 |
56 |
57 | }
58 |
59 |
--------------------------------------------------------------------------------
/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
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.0
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 | NSPrincipalClass
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2021 luximetr
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
11 | all 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
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:5.0
2 |
3 | import PackageDescription
4 |
5 | let package = Package(
6 | name: "AnyFormatKit",
7 | platforms: [.iOS(.v9)],
8 | products: [
9 | .library(
10 | name: "AnyFormatKit",
11 | targets: ["AnyFormatKit"]
12 | )
13 | ],
14 | targets: [
15 | .target(
16 | name: "AnyFormatKit",
17 | path: "Source"
18 | ),
19 | .testTarget(
20 | name: "AnyFormatKitTests",
21 | dependencies: ["AnyFormatKit"],
22 | path: "Tests"
23 | )
24 | ]
25 | )
26 |
--------------------------------------------------------------------------------
/Source/Controllers/TextFieldControllers/TextFieldInputController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TextFieldInputController.swift
3 | // AnyFormatKit
4 | //
5 | // Created by Oleksandr Orlov on 12.11.2020.
6 | // Copyright © 2020 Oleksandr Orlov. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | open class TextFieldInputController: NSObject, UITextFieldDelegate {
12 |
13 | open var formatter: TextInputFormatter?
14 |
15 | open func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
16 | guard let formatter = formatter else { return true }
17 | let result = formatter.formatInput(
18 | currentText: textField.text ?? "",
19 | range: range,
20 | replacementString: string
21 | )
22 | textField.text = result.formattedText
23 | textField.setCursorLocation(result.caretBeginOffset)
24 | notifyEditingChanged(at: textField)
25 | return false
26 | }
27 |
28 | private func notifyEditingChanged(at textField: UITextField) {
29 | textField.sendActions(for: .editingChanged)
30 | NotificationCenter.default.post(
31 | name: UITextField.textDidChangeNotification,
32 | object: textField
33 | )
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/Source/Controllers/TextFieldControllers/TextFieldStartInputController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TextFieldStartInputController.swift
3 | // AnyFormatKit
4 | //
5 | // Created by Oleksandr Orlov on 27.01.2021.
6 | // Copyright © 2021 Oleksandr Orlov. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | open class TextFieldStartInputController: NSObject, UITextFieldDelegate {
12 |
13 | open var formatter: (TextInputFormatter & CaretPositioner)?
14 |
15 | open func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
16 | guard let formatter = formatter else { return true }
17 | let result = formatter.formatInput(
18 | currentText: textField.text ?? "",
19 | range: range,
20 | replacementString: string
21 | )
22 | textField.text = result.formattedText
23 | textField.setCursorLocation(result.caretBeginOffset)
24 | notifyEditingChanged(at: textField)
25 | return false
26 | }
27 |
28 | open func textFieldDidBeginEditing(_ textField: UITextField) {
29 | guard let formatter = formatter else { return }
30 | let offset = formatter.getCaretOffset(for: textField.text ?? "")
31 | textField.setCursorLocation(offset)
32 | }
33 |
34 | private func notifyEditingChanged(at textField: UITextField) {
35 | textField.sendActions(for: .editingChanged)
36 | NotificationCenter.default.post(
37 | name: UITextField.textDidChangeNotification,
38 | object: textField
39 | )
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/Source/Controllers/TextViewControllers/TextViewInputController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TextViewInputController.swift
3 | // AnyFormatKit
4 | //
5 | // Created by Oleksandr Orlov on 12.11.2020.
6 | // Copyright © 2020 Oleksandr Orlov. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | open class TextViewInputController: NSObject, UITextViewDelegate {
12 |
13 | open var formatter: TextInputFormatter?
14 |
15 | open func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
16 | guard let formatter = formatter else { return true }
17 | let result = formatter.formatInput(
18 | currentText: textView.text,
19 | range: range,
20 | replacementString: text
21 | )
22 | textView.text = result.formattedText
23 | textView.setCursorLocation(result.caretBeginOffset)
24 | return false
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/Source/Controllers/TextViewControllers/TextViewStartInputController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TextViewStartInputController.swift
3 | // AnyFormatKit
4 | //
5 | // Created by Oleksandr Orlov on 27.01.2021.
6 | // Copyright © 2021 Oleksandr Orlov. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class TextViewStartInputController: NSObject, UITextViewDelegate {
12 |
13 | open var formatter: (TextInputFormatter & CaretPositioner)?
14 |
15 | open func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
16 | guard let formatter = formatter else { return true }
17 | let result = formatter.formatInput(
18 | currentText: textView.text,
19 | range: range,
20 | replacementString: text
21 | )
22 | textView.text = result.formattedText
23 | textView.setCursorLocation(result.caretBeginOffset)
24 | return false
25 | }
26 |
27 | open func textViewDidBeginEditing(_ textView: UITextView) {
28 | guard let formatter = formatter else { return }
29 | let offset = formatter.getCaretOffset(for: textView.text)
30 | textView.setCursorLocation(offset)
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Source/Extensions/UITextField+Extension.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UITextField+Extension.swift
3 | // AnyFormatKit
4 | //
5 | // Created by Oleksandr Orlov on 12.11.2020.
6 | // Copyright © 2020 Oleksandr Orlov. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension UITextField {
12 |
13 | func setCursorLocation(_ location: Int) {
14 | guard let cursorLocation = position(from: beginningOfDocument, offset: location) else { return }
15 | DispatchQueue.main.async { [weak self] in
16 | guard let strongSelf = self else { return }
17 | strongSelf.selectedTextRange = strongSelf.textRange(from: cursorLocation, to: cursorLocation)
18 | }
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/Source/Extensions/UITextView+Extension.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UITextView+Extension.swift
3 | // AnyFormatKit
4 | //
5 | // Created by Oleksandr Orlov on 12.11.2020.
6 | // Copyright © 2020 Oleksandr Orlov. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension UITextView {
12 |
13 | func setCursorLocation(_ location: Int) {
14 | guard let cursorLocation = position(from: beginningOfDocument, offset: location) else { return }
15 | DispatchQueue.main.async { [weak self] in
16 | guard let strongSelf = self else { return }
17 | strongSelf.selectedTextRange = strongSelf.textRange(from: cursorLocation, to: cursorLocation)
18 | }
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/Source/TextFormatter/DefaultFormatters/Formatters/DefaultTextFormatter.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DefaultTextFormatter.swift
3 | //
4 | // Created by Oleksandr Orlov on 11/14/18.
5 | // Copyright © 2018 Oleksandr Orlov. All rights reserved.
6 | //
7 |
8 | import Foundation
9 |
10 | open class DefaultTextFormatter: TextFormatter, TextUnformatter {
11 |
12 | // MARK: - Fields
13 |
14 | /// String, that will use for formatting of string replacing patter symbol, example: patternSymbol - "#", format - "### (###) ###-##-##"
15 | public let textPattern: String
16 |
17 | /// Symbol that will be replace by input symbols
18 | public let patternSymbol: Character
19 |
20 | // MARK: - Life cycle
21 | /**
22 | Initializes formatter with pattern
23 |
24 | - Parameters:
25 | - textPatterm: String, that will use for formatting of string replacing patter symbol
26 | - patternSymbol: Character, that will be replaced by input characters in textPattern
27 | */
28 | public init(textPattern: String,
29 | patternSymbol: Character = Constants.defaultPatternSymbol) {
30 | self.textPattern = textPattern
31 | self.patternSymbol = patternSymbol
32 | }
33 |
34 | // MARK: - TextFormatter
35 | /**
36 | Formatting text with current textPattern
37 |
38 | - Parameters:
39 | - unformatted: String, that need to be convert with current textPattern
40 |
41 | - Returns: Formatted text with current textPattern
42 | */
43 | open func format(_ unformattedText: String?) -> String? {
44 | guard let unformattedText = unformattedText else { return nil }
45 | var formatted = ""
46 | var unformattedIndex = 0
47 | var patternIndex = 0
48 |
49 | while patternIndex < textPattern.count && unformattedIndex < unformattedText.count {
50 | guard let patternCharacter = textPattern.characterAt(patternIndex) else { break }
51 | if patternCharacter == patternSymbol {
52 | if let unformattedCharacter = unformattedText.characterAt(unformattedIndex) {
53 | formatted.append(unformattedCharacter)
54 | }
55 | unformattedIndex += 1
56 | } else {
57 | formatted.append(patternCharacter)
58 | }
59 | patternIndex += 1
60 | }
61 | return formatted
62 | }
63 |
64 | /**
65 | Method for convert string, that sutisfy current textPattern, into unformatted string
66 |
67 | - Parameters:
68 | - formatted: String, that will convert
69 |
70 | - Returns: string converted into unformatted with current textPattern
71 | */
72 | open func unformat(_ formatted: String?) -> String? {
73 | guard let formatted = formatted else { return nil }
74 | var unformatted = String()
75 | var formattedIndex = 0
76 |
77 | while formattedIndex < formatted.count {
78 | if let formattedCharacter = formatted.characterAt(formattedIndex) {
79 | if formattedIndex >= textPattern.count {
80 | unformatted.append(formattedCharacter)
81 | } else if formattedCharacter != textPattern.characterAt(formattedIndex) || formattedCharacter == patternSymbol {
82 | unformatted.append(formattedCharacter)
83 | }
84 | formattedIndex += 1
85 | }
86 | }
87 | return unformatted
88 | }
89 |
90 | public struct Constants {
91 | public static let defaultPatternSymbol: Character = "#"
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/Source/TextFormatter/DefaultFormatters/Helpers/DefaultCaretPositionCorrector.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DefaultCaretPositionCorrector.swift
3 | // AnyFormatKit
4 | //
5 | // Created by Oleksandr Orlov on 02.04.2018.
6 | // Copyright © 2018 Oleksandr Orlov. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | class DefaultCaretPositionCorrector {
12 |
13 | let textPattern: String
14 | let patternSymbol: Character
15 |
16 | // MARK: - Life Cycle
17 | init(textPattern: String, patternSymbol: Character) {
18 | self.textPattern = textPattern
19 | self.patternSymbol = patternSymbol
20 | }
21 |
22 | func calculateCaretPositionOffset(newText: String, originalRange range: Range, replacementText: String) -> Int {
23 | var offset = 0
24 | if replacementText.isEmpty {
25 | offset = offsetForRemove(newText: newText, lowerBound: range.lowerBound)
26 | } else {
27 | offset = offsetForInsert(newText: newText, lowerBound: range.lowerBound, replacementLength: replacementText.count)
28 | }
29 | return offset
30 | }
31 |
32 | private func offsetForRemove(newText: String, lowerBound: String.Index) -> Int {
33 | let textPatternLowerBound = textPattern.getSameIndex(asIn: newText, sourceIndex: lowerBound)
34 | let textPatternIndex = textPattern.findIndexBefore(of: patternSymbol, startFrom: textPatternLowerBound)
35 | let index = newText.getSameIndex(asIn: textPattern, sourceIndex: textPatternIndex)
36 | let leftSlice = newText.leftSlice(end: index)
37 | return leftSlice.utf16.count
38 | }
39 |
40 | private func offsetForInsert(newText: String, lowerBound: String.Index, replacementLength: Int) -> Int {
41 | let textPatternLowerBound = textPattern.getSameIndex(asIn: newText, sourceIndex: lowerBound)
42 | let textPatternIndex = textPattern.findIndex(of: patternSymbol, skipFirst: replacementLength, startFrom: textPatternLowerBound)
43 | let index = newText.getSameIndex(asIn: textPattern, sourceIndex: textPatternIndex)
44 | let leftSlice = newText.leftSlice(end: index)
45 | return leftSlice.utf16.count
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/Source/TextFormatter/DefaultFormatters/Helpers/DefaultRangeCalculator.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DefaultRangeCalculator.swift
3 | // AnyFormatKit
4 | //
5 | // Created by Oleksandr Orlov on 27.01.2022.
6 | //
7 |
8 | import Foundation
9 |
10 | class DefaultRangeCalculator {
11 |
12 | func unformattedRange(
13 | currentText: String,
14 | textPattern: String,
15 | from range: Range,
16 | patternSymbol: Character
17 | ) -> Range {
18 | let numberOfFormatCharsBeforeRange = getNumberOfFormatChars(
19 | textPattern: textPattern,
20 | text: currentText,
21 | before: range.lowerBound,
22 | patternSymbol: patternSymbol
23 | )
24 | let numberOfFormatCharsInRange = getNumberOfFormatChars(
25 | textPattern: textPattern,
26 | text: currentText,
27 | in: range,
28 | patternSymbol: patternSymbol
29 | )
30 |
31 | return currentText.getRangeWithOffsets(
32 | sourceRange: range,
33 | lowerBoundOffset: -numberOfFormatCharsBeforeRange,
34 | upperBoundOffset: -numberOfFormatCharsInRange
35 | )
36 | }
37 |
38 | private func getNumberOfFormatChars(
39 | textPattern: String,
40 | text: String,
41 | before beforeIndex: String.Index,
42 | patternSymbol: Character
43 | ) -> Int {
44 | let textLeftSlice = text.leftSlice(end: beforeIndex)
45 | let patternLeftSlice = textPattern.leftSlice(limit: textLeftSlice.count)
46 | var result = 0
47 | for (textSliceChar, patternSliceChar) in zip(textLeftSlice, patternLeftSlice) {
48 | if textSliceChar == patternSliceChar && textSliceChar != patternSymbol { result += 1 }
49 | }
50 | return result
51 | }
52 |
53 | private func getNumberOfFormatChars(
54 | textPattern: String,
55 | text: String,
56 | in range: Range,
57 | patternSymbol: Character
58 | ) -> Int {
59 | let textSlice = text.slice(in: range)
60 | let textPatternRange = textPattern.getSameRange(asIn: text, sourceRange: range)
61 | let patternSlice = textPattern.slice(in: textPatternRange)
62 |
63 | var result = 0
64 | for (textSliceCharIndex, textSliceChar) in textSlice.enumerated() {
65 | let isSameCharacter = patternSlice.isSameCharacter(at: textSliceCharIndex, character: textSliceChar)
66 | if isSameCharacter && textSliceChar != patternSymbol {
67 | result += 1
68 | }
69 | }
70 | return result
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/Source/TextFormatter/PlaceholderFormatters/Formatters/PlaceholderTextFormatter.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PlaceholderTextFormatter.swift
3 | // AnyFormatKit
4 | //
5 | // Created by Oleksandr Orlov on 12.11.2020.
6 | // Copyright © 2020 Oleksandr Orlov. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | open class PlaceholderTextFormatter: TextFormatter, TextUnformatter {
12 |
13 | // MARK: - Properties
14 |
15 | /// String, that will use for formatting of string replacing patter symbol, example: patternSymbol - "#", format - "### (###) ###-##-##"
16 | public let textPattern: String
17 |
18 | /// Symbol that will be replace by input symbols
19 | public let patternSymbol: Character
20 |
21 | // MARK: - Life cycle
22 |
23 | /**
24 | Initializes formatter with pattern
25 |
26 | - Parameters:
27 | - textPatterm: String, that will use for formatting of string replacing patter symbol
28 | - patternSymbol: Character, that will be replaced by input characters in textPattern
29 | */
30 | public init(
31 | textPattern: String,
32 | patternSymbol: Character = "#"
33 | ) {
34 | self.textPattern = textPattern
35 | self.patternSymbol = patternSymbol
36 | }
37 |
38 | // MARK: - TextFormatter
39 |
40 | open func format(_ unformattedText: String?) -> String? {
41 | guard let unformattedText = unformattedText, !unformattedText.isEmpty else { return textPattern }
42 | var formatted = ""
43 | var unformattedIndex = 0
44 | var patternIndex = 0
45 |
46 | while patternIndex < textPattern.count && unformattedIndex < unformattedText.count {
47 | guard let patternCharacter = textPattern.characterAt(patternIndex) else { break }
48 | if patternCharacter == patternSymbol {
49 | if let unformattedCharacter = unformattedText.characterAt(unformattedIndex) {
50 | formatted.append(unformattedCharacter)
51 | }
52 | unformattedIndex += 1
53 | } else {
54 | formatted.append(patternCharacter)
55 | }
56 | patternIndex += 1
57 | }
58 | if formatted.count < textPattern.count {
59 | let start = textPattern.index(textPattern.startIndex, offsetBy: formatted.count)
60 | let end = textPattern.endIndex
61 | formatted = formatted + textPattern[start.. String? {
69 | guard let formatted = formattedText else { return nil }
70 | var unformatted = String()
71 | var formattedIndex = 0
72 |
73 | while formattedIndex < formatted.count {
74 | if let formattedCharacter = formatted.characterAt(formattedIndex) {
75 | if formattedIndex >= textPattern.count {
76 | unformatted.append(formattedCharacter)
77 | } else if formattedCharacter != textPattern.characterAt(formattedIndex) {
78 | unformatted.append(formattedCharacter)
79 | }
80 | formattedIndex += 1
81 | }
82 | }
83 | return unformatted
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/Source/TextFormatter/PlaceholderFormatters/Formatters/PlaceholderTextInputFormatter.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PlaceholderTextInputFormatter.swift
3 | // AnyFormatKit
4 | //
5 | // Created by Oleksandr Orlov on 12.11.2020.
6 | // Copyright © 2020 Oleksandr Orlov. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | open class PlaceholderTextInputFormatter: TextInputFormatter, TextFormatter, TextUnformatter, CaretPositioner {
12 |
13 | // MARK: - Dependencies
14 |
15 | private let caretPositionCorrector: PlaceholderCaretPositionCalculator
16 | private let textFormatter: PlaceholderTextFormatter
17 | private let rangeCalculator: PlaceholderRangeCalculator
18 |
19 | // MARK: - Properties
20 |
21 | var textPattern: String { textFormatter.textPattern }
22 | var patternSymbol: Character { textFormatter.patternSymbol }
23 |
24 | // MARK: - Life cycle
25 |
26 | public init(
27 | textPattern: String,
28 | patternSymbol: Character = "#"
29 | ) {
30 | self.caretPositionCorrector = PlaceholderCaretPositionCalculator(
31 | textPattern: textPattern,
32 | patternSymbol: patternSymbol
33 | )
34 | self.textFormatter = PlaceholderTextFormatter(
35 | textPattern: textPattern,
36 | patternSymbol: patternSymbol
37 | )
38 | self.rangeCalculator = PlaceholderRangeCalculator()
39 | }
40 |
41 | // MARK: - TextInputFormatter
42 |
43 | open func formatInput(currentText: String, range: NSRange, replacementString text: String) -> FormattedTextValue {
44 | guard let swiftRange = Range(range, in: currentText) else { return .zero }
45 | let oldUnformattedText = textFormatter.unformat(currentText) ?? ""
46 |
47 | let unformattedCurrentTextRange = rangeCalculator.unformattedRange(currentText: currentText, textPattern: textPattern, from: swiftRange)
48 | let unformattedRange = oldUnformattedText.getSameRange(asIn: currentText, sourceRange: unformattedCurrentTextRange)
49 |
50 | let newText = oldUnformattedText.replacingCharacters(in: unformattedRange, with: text)
51 |
52 | let formattedText = textFormatter.format(newText) ?? ""
53 | let formattedTextRange = formattedText.getSameRange(asIn: currentText, sourceRange: swiftRange)
54 |
55 | let caretOffset = getCorrectedCaretPosition(newText: formattedText, range: formattedTextRange, replacementString: text)
56 |
57 | return FormattedTextValue(formattedText: formattedText, caretBeginOffset: caretOffset)
58 | }
59 |
60 | open func getCaretOffset(for text: String) -> Int {
61 | return caretPositionCorrector.calculateCaretPositionOffset(currentText: text)
62 | }
63 |
64 | // MARK: - TextFormatter
65 |
66 | open func format(_ unformattedText: String?) -> String? {
67 | return textFormatter.format(unformattedText)
68 | }
69 |
70 | // MARK: - TextUnformatter
71 |
72 | open func unformat(_ formattedText: String?) -> String? {
73 | return textFormatter.unformat(formattedText)
74 | }
75 |
76 | // MARK: - Caret position calculation
77 |
78 | private func getCorrectedCaretPosition(newText: String, range: Range, replacementString: String) -> Int {
79 | return caretPositionCorrector.calculateCaretPositionOffset(
80 | newText: newText,
81 | originalRange: range,
82 | replacementText: replacementString
83 | )
84 | }
85 |
86 | }
87 |
--------------------------------------------------------------------------------
/Source/TextFormatter/PlaceholderFormatters/Helpers/PlaceholderCaretPositionCalculator.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PlaceholderCaretPositionCalculator.swift
3 | // AnyFormatKit
4 | //
5 | // Created by Oleksandr Orlov on 25.01.2021.
6 | // Copyright © 2021 Oleksandr Orlov. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | class PlaceholderCaretPositionCalculator {
12 |
13 | // MARK: - Properties
14 | let textPattern: String
15 | let patternSymbol: Character
16 | private let defaultFormatter: DefaultTextFormatter
17 |
18 | // MARK: - Life Cycle
19 | init(textPattern: String, patternSymbol: Character) {
20 | self.textPattern = textPattern
21 | self.patternSymbol = patternSymbol
22 | self.defaultFormatter = DefaultTextFormatter(textPattern: textPattern, patternSymbol: patternSymbol)
23 | }
24 |
25 | func calculateCaretPositionOffset(currentText: String) -> Int {
26 | let diff = currentText.getRemovingMatches(toMatch: textPattern)
27 | return diff.utf16Length
28 | }
29 |
30 | func calculateCaretPositionOffset(newText: String, originalRange range: Range, replacementText: String) -> Int {
31 | var offset = 0
32 | if replacementText.isEmpty {
33 | offset = offsetForRemove(newText: newText, lowerBound: range.lowerBound)
34 | } else {
35 | offset = offsetForInsert(newText: newText, lowerBound: range.lowerBound, replacementLength: replacementText.count)
36 | }
37 | return offset
38 | }
39 |
40 | private func offsetForRemove(newText: String, lowerBound: String.Index) -> Int {
41 | let textPatternLowerBound = textPattern.getSameIndex(asIn: newText, sourceIndex: lowerBound)
42 | let textPatternIndex = textPattern.findIndexBefore(of: patternSymbol, startFrom: textPatternLowerBound)
43 | let index = newText.getSameIndex(asIn: textPattern, sourceIndex: textPatternIndex)
44 | let leftSlice = newText.leftSlice(end: index)
45 | return leftSlice.utf16Length
46 | }
47 |
48 | private func offsetForInsert(newText: String, lowerBound: String.Index, replacementLength: Int) -> Int {
49 | let textPatternLowerBound = textPattern.getSameIndex(asIn: newText, sourceIndex: lowerBound)
50 | let textPatternIndex = textPattern.findIndex(of: patternSymbol, skipFirst: replacementLength, startFrom: textPatternLowerBound)
51 | let index = newText.getSameIndex(asIn: textPattern, sourceIndex: textPatternIndex)
52 | let leftSlice = newText.leftSlice(end: index)
53 | let textPatternLeftSlice = textPattern.leftSlice(end: textPatternIndex)
54 | let diff = leftSlice.getRemovingMatches(toMatch: textPatternLeftSlice)
55 | return diff.utf16Length
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/Source/TextFormatter/PlaceholderFormatters/Helpers/PlaceholderRangeCalculator.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PlaceholderRangeCalculator.swift
3 | // AnyFormatKit
4 | //
5 | // Created by Oleksandr Orlov on 16.01.2021.
6 | // Copyright © 2021 Oleksandr Orlov. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | class PlaceholderRangeCalculator {
12 |
13 | func unformattedRange(
14 | currentText: String,
15 | textPattern: String,
16 | from range: Range
17 | ) -> Range {
18 | let numberOfFormatCharsBeforeRange = getNumberOfFormatChars(
19 | textPattern: textPattern,
20 | text: currentText,
21 | before: range.lowerBound
22 | )
23 | let numberOfFormatCharsInRange = getNumberOfFormatChars(
24 | textPattern: textPattern,
25 | text: currentText,
26 | in: range
27 | )
28 |
29 | return currentText.getRangeWithOffsets(
30 | sourceRange: range,
31 | lowerBoundOffset: -numberOfFormatCharsBeforeRange,
32 | upperBoundOffset: -numberOfFormatCharsInRange
33 | )
34 | }
35 |
36 | private func getNumberOfFormatChars(
37 | textPattern: String,
38 | text: String,
39 | before: String.Index
40 | ) -> Int {
41 | let textLeftSlice = text.leftSlice(end: before)
42 | let patternLeftSlice = textPattern.leftSlice(limit: textLeftSlice.count)
43 | var result = 0
44 | for (textSliceChar, patternSliceChar) in zip(textLeftSlice, patternLeftSlice) {
45 | if textSliceChar == patternSliceChar { result += 1 }
46 | }
47 | return result
48 | }
49 |
50 | private func getNumberOfFormatChars(
51 | textPattern: String,
52 | text: String,
53 | in range: Range
54 | ) -> Int {
55 | let textSlice = text.slice(in: range)
56 | let textPatternRange = textPattern.getSameRange(asIn: text, sourceRange: range)
57 | let patternSlice = textPattern.slice(in: textPatternRange)
58 |
59 | var result = 0
60 | for (textSliceCharIndex, textSliceChar) in textSlice.enumerated() {
61 | let isSameCharacter = patternSlice.isSameCharacter(at: textSliceCharIndex, character: textSliceChar)
62 | if isSameCharacter {
63 | result += 1
64 | }
65 | }
66 | return result
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/Source/TextFormatter/SumFormatters/Helpers/SumFormatParser.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SumFormatParser.swift
3 | // AnyFormatKit
4 | //
5 | // Created by Oleksandr Orlov on 5/27/19.
6 | // Copyright © 2019 Oleksandr Orlov. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | class SumFormatParser {
12 |
13 | struct Result {
14 | let prefix: String
15 | let suffix: String
16 | let groupingSeparator: String
17 | let decimalSeparator: String
18 | let groupingSize: Int
19 | let maximumFractionDigits: Int
20 | }
21 |
22 | func parse(format: String, patternSymbol: Character) -> Result {
23 | let prefix = parsePrefix(format: format, patternSymbol: patternSymbol)
24 | let suffix = parseSuffix(format: format, patternSymbol: patternSymbol)
25 | let groupingSeparator = parseGroupingSeparator(format: format, prefix: prefix, patternSymbol: patternSymbol)
26 | let decimalSeparator = parseDecimalSeparator(format: format, suffix: suffix, patternSymbol: patternSymbol)
27 | let groupingSize = parseGroupingSize(format: format, prefix: prefix, groupingSeparator: groupingSeparator, decimalSeparator: decimalSeparator, patternSymbol: patternSymbol)
28 | let maximumFractionDigits = parseMaximumFractionDigits(format: format, decimalSeparator: decimalSeparator, suffix: suffix, patternSymbol: patternSymbol)
29 | return Result(prefix: prefix,
30 | suffix: suffix,
31 | groupingSeparator: groupingSeparator,
32 | decimalSeparator: decimalSeparator,
33 | groupingSize: groupingSize,
34 | maximumFractionDigits: maximumFractionDigits)
35 | }
36 |
37 | private func parsePrefix(format: String, patternSymbol: Character) -> String {
38 | guard format.first != patternSymbol else { return "" }
39 | guard let prefixPart = format.split(separator: patternSymbol).first else { return "" }
40 | return String(prefixPart)
41 | }
42 |
43 | private func parseSuffix(format: String, patternSymbol: Character) -> String {
44 | guard format.last != patternSymbol else { return "" }
45 | guard let suffixPart = format.split(separator: patternSymbol).last else { return "" }
46 | return String(suffixPart)
47 | }
48 |
49 | private func parseGroupingSeparator(format: String, prefix: String, patternSymbol: Character) -> String {
50 | let formatWithoutPrefix = format.removePrefix(prefix)
51 | guard let groupingSeparatorPart = formatWithoutPrefix.split(separator: patternSymbol).first else { return "" }
52 | return String(groupingSeparatorPart)
53 | }
54 |
55 | private func parseDecimalSeparator(format: String, suffix: String, patternSymbol: Character) -> String {
56 | let formatWithoutSuffix = format.removeSuffix(suffix)
57 | guard let decimalSeparatorPart = formatWithoutSuffix.split(separator: patternSymbol).last else { return "" }
58 | return String(decimalSeparatorPart)
59 | }
60 |
61 | private func parseGroupingSize(format: String, prefix: String, groupingSeparator: String, decimalSeparator: String, patternSymbol: Character) -> Int {
62 | let formatWithoutPrefix = format.removePrefix(prefix)
63 | let groupPart = formatWithoutPrefix.slice(from: groupingSeparator, to: decimalSeparator)
64 | return groupPart.count
65 | }
66 |
67 | private func parseMaximumFractionDigits(format: String, decimalSeparator: String, suffix: String, patternSymbol: Character) -> Int {
68 | let fractionDigitsPart = format.slice(from: decimalSeparator, to: suffix)
69 | return fractionDigitsPart.count
70 | }
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/Source/TextFormatter/TextFormatter/CaretPositioner.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CaretPositioner.swift
3 | // AnyFormatKit
4 | //
5 | // Created by Oleksandr Orlov on 27.01.2021.
6 | // Copyright © 2021 Oleksandr Orlov. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public protocol CaretPositioner {
12 | func getCaretOffset(for text: String) -> Int
13 | }
14 |
--------------------------------------------------------------------------------
/Source/TextFormatter/TextFormatter/FormattedTextValue.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FormattedTextValue.swift
3 | // AnyFormatKitTests
4 | //
5 | // Created by Oleksandr Orlov on 12.11.2020.
6 | // Copyright © 2020 Oleksandr Orlov. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public struct FormattedTextValue: Equatable {
12 | public let formattedText: String
13 | public let caretBeginOffset: Int
14 |
15 | public init(formattedText: String, caretBeginOffset: Int) {
16 | self.formattedText = formattedText
17 | self.caretBeginOffset = caretBeginOffset
18 | }
19 |
20 | public static var zero: FormattedTextValue {
21 | return FormattedTextValue(formattedText: "", caretBeginOffset: 0)
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Source/TextFormatter/TextFormatter/TextFormatter.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TextFormatter.swift
3 | // TextInput
4 | //
5 | // Created by Oleksandr Orlov on 18.10.2017.
6 | // Copyright © 2017 Oleksandr Orlov. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | /// Interface of text formatter
12 | public protocol TextFormatter {
13 | /**
14 | Formatting text with current textPattern
15 |
16 | - Parameters:
17 | - unformatted: String to convert
18 |
19 | - Returns: Formatted text
20 | */
21 | func format(_ unformattedText: String?) -> String?
22 | }
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Source/TextFormatter/TextFormatter/TextInputFormatter.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TextInputFormatter.swift
3 | //
4 | // Created by Oleksandr Orlov on 18.10.2017.
5 | // Copyright © 2017 Oleksandr Orlov. All rights reserved.
6 | //
7 |
8 | import Foundation
9 |
10 | /// Interface for formatter of TextInput, that allow change format of text during input
11 | public protocol TextInputFormatter {
12 |
13 | func formatInput(
14 | currentText: String, range: NSRange, replacementString text: String) -> FormattedTextValue
15 | }
16 |
--------------------------------------------------------------------------------
/Source/TextFormatter/TextFormatter/TextNumberFormatter.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TextNumberFormatter.swift
3 | // AnyFormatKit
4 | //
5 | // Created by Oleksandr Orlov on 01.02.2021.
6 | // Copyright © 2021 Oleksandr Orlov. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public protocol TextNumberFormatter {
12 | func format(_ number: NSNumber) -> String?
13 | }
14 |
--------------------------------------------------------------------------------
/Source/TextFormatter/TextFormatter/TextNumberUnformatter.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TextNumberUnformatter.swift
3 | // AnyFormatKit
4 | //
5 | // Created by Oleksandr Orlov on 18.01.2021.
6 | // Copyright © 2021 Oleksandr Orlov. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public protocol TextNumberUnformatter {
12 | func unformatNumber(_ formattedText: String?) -> NSNumber?
13 | }
14 |
--------------------------------------------------------------------------------
/Source/TextFormatter/TextFormatter/TextUnformatter.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TextUnformatter.swift
3 | // AnyFormatKit
4 | //
5 | // Created by Oleksandr Orlov on 18.01.2021.
6 | // Copyright © 2021 Oleksandr Orlov. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public protocol TextUnformatter {
12 | /**
13 | Method for convert string, that sutisfy current textPattern, into unformatted string
14 |
15 | - Parameters:
16 | - formatted: String to convert
17 |
18 | - Returns: String converted into unformatted
19 | */
20 | func unformat(_ formattedText: String?) -> String?
21 | }
22 |
--------------------------------------------------------------------------------
/Tests/DefaultTextFormatterTests/DefaultTextFormatterTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DefaultTextFormatterTests.swift
3 | // AnyFormatKitTests
4 | //
5 | // Created by Oleksandr Orlov on 18.01.2021.
6 | // Copyright © 2021 Oleksandr Orlov. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | import AnyFormatKit
11 |
12 | class DefaultTextFormatterTests: XCTestCase {
13 |
14 | // "" -> ""
15 | func test1() {
16 | let formatter = DefaultTextFormatter(textPattern: "## ## ##")
17 | let result = formatter.format("")
18 | let expectedResult = ""
19 | XCTAssertEqual(result, expectedResult)
20 | }
21 |
22 | // 123 -> 12 3
23 | func test2() {
24 | let formatter = DefaultTextFormatter(textPattern: "## ## ##")
25 | let result = formatter.format("123")
26 | let expectedResult = "12 3"
27 | XCTAssertEqual(result, expectedResult)
28 | }
29 |
30 | // 123 -> +5 12 3
31 | func test3() {
32 | let formatter = DefaultTextFormatter(textPattern: "+5 ## ## ##")
33 | let result = formatter.format("123")
34 | let expectedResult = "+5 12 3"
35 | XCTAssertEqual(result, expectedResult)
36 | }
37 |
38 | // 123 -> 😊 12 3
39 | func test4() {
40 | let formatter = DefaultTextFormatter(textPattern: "😊 ## ## ##")
41 | let result = formatter.format("123")
42 | let expectedResult = "😊 12 3"
43 | XCTAssertEqual(result, expectedResult)
44 | }
45 |
46 | // nil -> nil
47 | func test5() {
48 | let formatter = DefaultTextFormatter(textPattern: "## ## ##")
49 | let result = formatter.format(nil)
50 | let expectedResult: String? = nil
51 | XCTAssertEqual(result, expectedResult)
52 | }
53 |
54 | // 1234 -> 12 34
55 | func test6() {
56 | let formatter = DefaultTextFormatter(textPattern: "XX XX", patternSymbol: "X")
57 | let result = formatter.format("1234")
58 | let expectedResult = "12 34"
59 | XCTAssertEqual(result, expectedResult)
60 | }
61 |
62 | // #123 -> #1-23
63 | func test7() {
64 | let formatter = DefaultTextFormatter(textPattern: "##-##-##")
65 | let result = formatter.format("#123")
66 | let expectedResult = "#1-23"
67 | XCTAssertEqual(result, expectedResult)
68 | }
69 |
70 | // #### -> ##-##
71 | func test8() {
72 | let formatter = DefaultTextFormatter(textPattern: "##-##-##")
73 | let result = formatter.format("####")
74 | let expectedResult = "##-##"
75 | XCTAssertEqual(result, expectedResult)
76 | }
77 |
78 | // abcd -> ab-cd
79 | func test9() {
80 | let formatter = DefaultTextFormatter(textPattern: "##-##-##")
81 | let result = formatter.format("abcd")
82 | let expectedResult = "ab-cd"
83 | XCTAssertEqual(result, expectedResult)
84 | }
85 |
86 | // a1b2 -> a1-b2
87 | func test10() {
88 | let formatter = DefaultTextFormatter(textPattern: "##-##-##")
89 | let result = formatter.format("a1b2")
90 | let expectedResult = "a1-b2"
91 | XCTAssertEqual(result, expectedResult)
92 | }
93 |
94 | func test11() {
95 | let formatter = DefaultTextFormatter(textPattern: "##-##-##")
96 | let result = formatter.format("a1#b#2")
97 | let expectedResult = "a1-#b-#2"
98 | XCTAssertEqual(result, expectedResult)
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/Tests/DefaultTextFormatterTests/DefaultTextFormatterUnformatTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DefaultTextFormatterUnformatTests.swift
3 | // AnyFormatKitTests
4 | //
5 | // Created by Oleksandr Orlov on 18.01.2021.
6 | // Copyright © 2021 Oleksandr Orlov. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | import AnyFormatKit
11 |
12 | class DefaultTextFormatterUnformatTests: XCTestCase {
13 |
14 | // 12-34-45 -> 123445
15 | func test1() {
16 | let formatter = DefaultTextFormatter(textPattern: "##-##-##")
17 | let result = formatter.unformat("12-34-45")
18 | let expectedResult = "123445"
19 | XCTAssertEqual(result, expectedResult)
20 | }
21 |
22 | // 12 34 -> 1234
23 | func test2() {
24 | let formatter = DefaultTextFormatter(textPattern: "## ## ##")
25 | let result = formatter.unformat("12 34")
26 | let expectedResult = "1234"
27 | XCTAssertEqual(result, expectedResult)
28 | }
29 |
30 | // +5 11 22
31 | func test3() {
32 | let formatter = DefaultTextFormatter(textPattern: "+5 ## ##")
33 | let result = formatter.unformat("+5 11 22")
34 | let expectedResult = "1122"
35 | XCTAssertEqual(result, expectedResult)
36 | }
37 |
38 | // "" -> ""
39 | func test4() {
40 | let formatter = DefaultTextFormatter(textPattern: "##-## ##")
41 | let result = formatter.unformat("")
42 | let expectedResult = ""
43 | XCTAssertEqual(result, expectedResult)
44 | }
45 |
46 | // nil -> nil
47 | func test5() {
48 | let formatter = DefaultTextFormatter(textPattern: "##-## ##")
49 | let result = formatter.unformat(nil)
50 | let expectedResult: String? = nil
51 | XCTAssertEqual(result, expectedResult)
52 | }
53 |
54 | func test6() {
55 | let formatter = DefaultTextFormatter(textPattern: "##-##-##")
56 | let result = formatter.unformat("12-##")
57 | let expectedResult = "12##"
58 | XCTAssertEqual(result, expectedResult)
59 | }
60 |
61 | func test7() {
62 | let formatter = DefaultTextFormatter(textPattern: "##-##-##")
63 | let result = formatter.unformat("12-ab")
64 | let expectedResult = "12ab"
65 | XCTAssertEqual(result, expectedResult)
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/Tests/DefaultTextInputFormatterTests/Format/DefaultTextInputFormatterFormatTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DefaultTextInputFormatterFormatTests.swift
3 | // AnyFormatKitTests
4 | //
5 | // Created by Oleksandr Orlov on 18.01.2021.
6 | // Copyright © 2021 BRANDERSTUDIO. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | import AnyFormatKit
11 |
12 | class DefaultTextInputFormatterFormatTests: XCTestCase {
13 |
14 | // "" -> ""
15 | func test1() {
16 | let formatter = DefaultTextInputFormatter(textPattern: "## ## ##")
17 | let result = formatter.format("")
18 | let expectedResult = ""
19 | XCTAssertEqual(result, expectedResult)
20 | }
21 |
22 | // 123 -> 12 3
23 | func test2() {
24 | let formatter = DefaultTextInputFormatter(textPattern: "## ## ##")
25 | let result = formatter.format("123")
26 | let expectedResult = "12 3"
27 | XCTAssertEqual(result, expectedResult)
28 | }
29 |
30 | // 123 -> +5 12 3
31 | func test3() {
32 | let formatter = DefaultTextInputFormatter(textPattern: "+5 ## ## ##")
33 | let result = formatter.format("123")
34 | let expectedResult = "+5 12 3"
35 | XCTAssertEqual(result, expectedResult)
36 | }
37 |
38 | // 123 -> 😊 12 3
39 | func test4() {
40 | let formatter = DefaultTextInputFormatter(textPattern: "😊 ## ## ##")
41 | let result = formatter.format("123")
42 | let expectedResult = "😊 12 3"
43 | XCTAssertEqual(result, expectedResult)
44 | }
45 |
46 | // nil -> nil
47 | func test5() {
48 | let formatter = DefaultTextInputFormatter(textPattern: "## ## ##")
49 | let result = formatter.format(nil)
50 | let expectedResult: String? = nil
51 | XCTAssertEqual(result, expectedResult)
52 | }
53 |
54 | // 1234 -> 12 34
55 | func test6() {
56 | let formatter = DefaultTextInputFormatter(textPattern: "XX XX", patternSymbol: "X")
57 | let result = formatter.format("1234")
58 | let expectedResult = "12 34"
59 | XCTAssertEqual(result, expectedResult)
60 | }
61 |
62 | // #123 -> #1-23
63 | func test7() {
64 | let formatter = DefaultTextInputFormatter(textPattern: "##-##-##")
65 | let result = formatter.format("#123")
66 | let expectedResult = "#1-23"
67 | XCTAssertEqual(result, expectedResult)
68 | }
69 |
70 | // #### -> ##-##
71 | func test8() {
72 | let formatter = DefaultTextInputFormatter(textPattern: "##-##-##")
73 | let result = formatter.format("####")
74 | let expectedResult = "##-##"
75 | XCTAssertEqual(result, expectedResult)
76 | }
77 |
78 | // abcd -> ab-cd
79 | func test9() {
80 | let formatter = DefaultTextInputFormatter(textPattern: "##-##-##")
81 | let result = formatter.format("abcd")
82 | let expectedResult = "ab-cd"
83 | XCTAssertEqual(result, expectedResult)
84 | }
85 |
86 | // a1b2 -> a1-b2
87 | func test10() {
88 | let formatter = DefaultTextInputFormatter(textPattern: "##-##-##")
89 | let result = formatter.format("a1b2")
90 | let expectedResult = "a1-b2"
91 | XCTAssertEqual(result, expectedResult)
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/Tests/DefaultTextInputFormatterTests/FormatInput/Insert/AnyFormatKitTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AnyFormatKitTests.swift
3 | // AnyFormatKitTests
4 | //
5 | // Created by Oleksandr Orlov on 01.11.2017.
6 | // Copyright © 2017 Oleksandr Orlov. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import AnyFormatKit
11 |
12 | class AnyFormatKitTests: XCTestCase {
13 | let phoneNumberFormatter = DefaultTextFormatter(textPattern: "### (###) ##-##-###")
14 |
15 | func testOneSymbolFormatting() {
16 | let expectedString = "3"
17 | let formattedString = phoneNumberFormatter.format("3")
18 | XCTAssert(expectedString == formattedString, "\(expectedString) must be equal to \(String(describing: formattedString))")
19 | }
20 |
21 | func testFullStringFormatting() {
22 | let expectedString = "123 (456) 78-78-789"
23 | let formattedString = phoneNumberFormatter.format("1234567878789")
24 | XCTAssert(expectedString == formattedString, "\(expectedString) must be equal to \(String(describing: formattedString))")
25 | }
26 |
27 | func testOverLengthStringFormatting() {
28 | let expectedString = "123 (456) 78-78-789"
29 | let formattedString = phoneNumberFormatter.format("123456787878900000")
30 | XCTAssert(expectedString == formattedString, "\(expectedString) must be equal to \(String(describing: formattedString))")
31 | }
32 |
33 | func testEmptyStringFormatting() {
34 | let expectedString = ""
35 | let formattedString = phoneNumberFormatter.format("")
36 | XCTAssert(expectedString == formattedString, "\(expectedString) must be equal to \(String(describing: formattedString))")
37 | }
38 |
39 | func testNilStringFormatting() {
40 | let expectedString: String? = nil
41 | let formattedString = phoneNumberFormatter.format(nil)
42 | XCTAssert(expectedString == formattedString, "\(String(describing: expectedString)) must be equal to \(String(describing: formattedString))")
43 | }
44 |
45 | func testHalfStringFormatting() {
46 | let expectedString = "123 (45"
47 | let formattedString = phoneNumberFormatter.format("12345")
48 | XCTAssert(expectedString == formattedString, "\(expectedString) must be equal to \(String(describing: formattedString))")
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/Tests/DefaultTextInputFormatterTests/FormatInput/Insert/DefaultTextInputFormatterPhoneEmojisInputTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DefaultTextInputFormatterPhoneEmojisInputTests.swift
3 | // AnyFormatKitTests
4 | //
5 | // Created by Oleksandr Orlov on 16.01.2021.
6 | // Copyright © 2021 Orlov Oleksandr. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | import AnyFormatKit
11 |
12 | class DefaultTextInputFormatterPhoneEmojisInputTests: XCTestCase {
13 |
14 | private let formatter = DefaultTextInputFormatter(textPattern: "### (###) ###-##-##")
15 |
16 | // | -> 😊|
17 | func test1() {
18 | let actualResult = formatter.formatInput(
19 | currentText: "",
20 | range: NSRange(location: 0, length: 0),
21 | replacementString: "😊")
22 | let expectedResult = FormattedTextValue(formattedText: "😊", caretBeginOffset: 2)
23 | XCTAssert(actualResult == expectedResult, "\n\(actualResult) must be equal to\n\(expectedResult)")
24 | }
25 |
26 | // 😊| -> 😊👍|
27 | func test2() {
28 | let actualResult = formatter.formatInput(
29 | currentText: "😊",
30 | range: NSRange(location: 2, length: 0),
31 | replacementString: "👍")
32 | let expectedResult = FormattedTextValue(formattedText: "😊👍", caretBeginOffset: 4)
33 | XCTAssert(actualResult == expectedResult, "\n\(actualResult) must be equal to\n\(expectedResult)")
34 | }
35 |
36 | // 😊👍| -> 😊👍🙈|
37 | func test3() {
38 | let actualResult = formatter.formatInput(
39 | currentText: "😊👍",
40 | range: NSRange(location: 4, length: 0),
41 | replacementString: "🙈")
42 | let expectedResult = FormattedTextValue(formattedText: "😊👍🙈", caretBeginOffset: 6)
43 | XCTAssert(actualResult == expectedResult, "\n\(actualResult) must be equal to\n\(expectedResult)")
44 | }
45 |
46 | // 😊👍🙈| -> 😊👍🙈 (😱|
47 | func test4() {
48 | let actualResult = formatter.formatInput(
49 | currentText: "😊👍🙈",
50 | range: NSRange(location: 6, length: 0),
51 | replacementString: "😱")
52 | let expectedResult = FormattedTextValue(formattedText: "😊👍🙈 (😱", caretBeginOffset: 10)
53 | XCTAssert(actualResult == expectedResult, "\n\(actualResult) must be equal to\n\(expectedResult)")
54 | }
55 |
56 | // 😊👍🙈 (😱| -> 😊👍🙈 (😱😭|
57 | func test5() {
58 | let actualResult = formatter.formatInput(
59 | currentText: "😊👍🙈 (😱",
60 | range: NSRange(location: 10, length: 0),
61 | replacementString: "😭")
62 | let expectedResult = FormattedTextValue(formattedText: "😊👍🙈 (😱😭", caretBeginOffset: 12)
63 | XCTAssert(actualResult == expectedResult, "\n\(actualResult) must be equal to\n\(expectedResult)")
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/Tests/DefaultTextInputFormatterTests/FormatInput/Replace/DefaultTextInputFormatter1SymbolReplaceTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DefaultTextInputFormatter1SymbolReplaceTests.swift
3 | // AnyFormatKitTests
4 | //
5 | // Created by Oleksandr Orlov on 09.06.2019.
6 | // Copyright © 2019 Oleksandr Orlov. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import AnyFormatKit
11 |
12 | class DefaultTextInputFormatter1SymbolReplaceTests: XCTestCase {
13 |
14 | private let formatter = DefaultTextInputFormatter(textPattern: "## ## ##")
15 |
16 | // 12 3|4| -> 12 30|
17 | func test1() {
18 | let actualResult = formatter.formatInput(
19 | currentText: "12 34",
20 | range: NSRange(location: 4, length: 1),
21 | replacementString: "0")
22 | let expectedResult = FormattedTextValue(formattedText: "12 30", caretBeginOffset: 5)
23 | XCTAssert(actualResult == expectedResult, "\n\(actualResult) must be equal to\n\(expectedResult)")
24 | }
25 |
26 | func test2() {
27 | let actualResult = formatter.formatInput(
28 | currentText: "12 34",
29 | range: NSRange(location: 3, length: 1),
30 | replacementString: "0")
31 | let expectedResult = FormattedTextValue(formattedText: "12 04", caretBeginOffset: 4)
32 | XCTAssert(actualResult == expectedResult, "\n\(actualResult) must be equal to\n\(expectedResult)")
33 | }
34 |
35 | func test12_34to10_34() {
36 | let actualResult = formatter.formatInput(
37 | currentText: "12 34",
38 | range: NSRange(location: 1, length: 1),
39 | replacementString: "0")
40 | let expectedResult = FormattedTextValue(formattedText: "10 34", caretBeginOffset: 2)
41 | XCTAssert(actualResult == expectedResult, "\n\(actualResult) must be equal to\n\(expectedResult)")
42 | }
43 |
44 | func test12_34to02_34() {
45 | let actualResult = formatter.formatInput(
46 | currentText: "12 34",
47 | range: NSRange(location: 0, length: 1),
48 | replacementString: "0")
49 | let expectedResult = FormattedTextValue(formattedText: "02 34", caretBeginOffset: 1)
50 | XCTAssert(actualResult == expectedResult, "\n\(actualResult) must be equal to\n\(expectedResult)")
51 | }
52 |
53 | func test12I_I34to12_03_4() {
54 | let actualResult = formatter.formatInput(
55 | currentText: "12 34",
56 | range: NSRange(location: 2, length: 1),
57 | replacementString: "0")
58 | let expectedResult = FormattedTextValue(formattedText: "12 03 4", caretBeginOffset: 4)
59 | XCTAssert(actualResult == expectedResult, "\n\(actualResult) must be equal to\n\(expectedResult)")
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/Tests/DefaultTextInputFormatterTests/Unformat/DefaultTextInputUnformattingTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // DefaultTextInputUnformattingTests.swift
3 | // AnyFormatKitTests
4 | //
5 | // Created by Oleksandr Orlov on 18.01.2021.
6 | // Copyright © 2021 Oleksandr Orlov. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | import AnyFormatKit
11 |
12 | class DefaultTextInputUnformattingTests: XCTestCase {
13 |
14 | // +5 123 456 -> 123456
15 | func test1() {
16 | let formatter = DefaultTextInputFormatter(textPattern: "+5 ### ###")
17 | let result = formatter.unformat("+5 123 456")
18 | let expectedResult = "123456"
19 | XCTAssertEqual(result, expectedResult)
20 | }
21 |
22 | // 123 4 -> 1234
23 | func test2() {
24 | let formatter = DefaultTextInputFormatter(textPattern: "### ###")
25 | let result = formatter.unformat("123 4")
26 | let expectedResult = "1234"
27 | XCTAssertEqual(result, expectedResult)
28 | }
29 |
30 | // "" -> ""
31 | func test3() {
32 | let formatter = DefaultTextInputFormatter(textPattern: "### ###")
33 | let result = formatter.unformat("")
34 | let expectedResult = ""
35 | XCTAssertEqual(result, expectedResult)
36 | }
37 |
38 | // nil -> nil
39 | func test4() {
40 | let formatter = DefaultTextInputFormatter(textPattern: "### ###")
41 | let result = formatter.unformat(nil)
42 | let expectedResult: String? = nil
43 | XCTAssertEqual(result, expectedResult)
44 | }
45 |
46 | func test5() {
47 | let formatter = DefaultTextInputFormatter(textPattern: "+5 ### ###")
48 | let result = formatter.unformat("+5 ")
49 | let expectedResult = ""
50 | XCTAssertEqual(result, expectedResult)
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/Tests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
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 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Tests/PlaceholderFormatterTests/PlaceholderFormatterFormattingTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PlaceholderFormatterFormattingTests.swift
3 | // AnyFormatKitTests
4 | //
5 | // Created by Oleksandr Orlov on 12.11.2020.
6 | // Copyright © 2020 Oleksandr Orlov. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | import AnyFormatKit
11 |
12 | class PlaceholderFormatterFormattingTests: XCTestCase {
13 |
14 | func test1() {
15 | let formatter = PlaceholderTextFormatter(textPattern: "#### ####")
16 | let result = formatter.format("12345678")
17 | let expectedResult = "1234 5678"
18 | XCTAssertEqual(result, expectedResult)
19 | }
20 |
21 | func test2() {
22 | let formatter = PlaceholderTextFormatter(textPattern: "#### ####")
23 | let result = formatter.format("12")
24 | let expectedResult = "12## ####"
25 | XCTAssertEqual(result, expectedResult)
26 | }
27 |
28 | func test3() {
29 | let formatter = PlaceholderTextFormatter(textPattern: "#### ####")
30 | let result = formatter.format("")
31 | let expectedResult = "#### ####"
32 | XCTAssertEqual(result, expectedResult)
33 | }
34 |
35 | func test4() {
36 | let formatter = PlaceholderTextFormatter(textPattern: "#### ####")
37 | let result = formatter.format(nil)
38 | let expectedResult = "#### ####"
39 | XCTAssertEqual(result, expectedResult)
40 | }
41 |
42 | func test5() {
43 | let formatter = PlaceholderTextFormatter(textPattern: "#### ####")
44 | let result = formatter.format("1")
45 | let expectedResult = "1### ####"
46 | XCTAssertEqual(result, expectedResult)
47 | }
48 |
49 | func test6() {
50 | let formatter = PlaceholderTextFormatter(textPattern: "#### ####")
51 | let result = formatter.format("123456789")
52 | let expectedResult = "1234 5678"
53 | XCTAssertEqual(result, expectedResult)
54 | }
55 |
56 | func test7() {
57 | let formatter = PlaceholderTextFormatter(textPattern: "#### ####")
58 | let result = formatter.format("1234567")
59 | let expectedResult = "1234 567#"
60 | XCTAssertEqual(result, expectedResult)
61 | }
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/Tests/PlaceholderFormatterTests/PlaceholderFormatterUnformattingTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PlaceholderFormatterUnformattingTests.swift
3 | // AnyFormatKit
4 | //
5 | // Created by Oleksandr Orlov on 12.11.2020.
6 | // Copyright © 2020 Oleksandr Orlov. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import AnyFormatKit
11 |
12 | class PlaceholderFormatterUnformattingTests: XCTestCase {
13 |
14 | func test1() {
15 | let formatter = PlaceholderTextFormatter(textPattern: "#### ####")
16 | let result = formatter.unformat("12## ####")
17 | let expectedResult = "12"
18 | XCTAssertEqual(result, expectedResult)
19 | }
20 |
21 | func test2() {
22 | let formatter = PlaceholderTextFormatter(textPattern: "#### ####")
23 | let result = formatter.unformat("#### ####")
24 | let expectedResult = ""
25 | XCTAssertEqual(result, expectedResult)
26 | }
27 |
28 | func test3() {
29 | let formatter = PlaceholderTextFormatter(textPattern: "#### ####")
30 | let result = formatter.unformat("1234 ####")
31 | let expectedResult = "1234"
32 | XCTAssertEqual(result, expectedResult)
33 | }
34 |
35 | func test4() {
36 | let formatter = PlaceholderTextFormatter(textPattern: "#### ####")
37 | let result = formatter.unformat("1234 5###")
38 | let expectedResult = "12345"
39 | XCTAssertEqual(result, expectedResult)
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Tests/PlaceholderTextInputFormatterTests/Format/PlaceholderTextInputFormatterFormatTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PlaceholderTextInputFormatterFormatTests.swift
3 | // AnyFormatKitTests
4 | //
5 | // Created by Oleksandr Orlov on 18.01.2021.
6 | // Copyright © 2021 BRANDERSTUDIO. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | import AnyFormatKit
11 |
12 | class PlaceholderTextInputFormatterFormatTests: XCTestCase {
13 |
14 | func test1() {
15 | let formatter = PlaceholderTextInputFormatter(textPattern: "#### ####")
16 | let result = formatter.format("12345678")
17 | let expectedResult = "1234 5678"
18 | XCTAssertEqual(result, expectedResult)
19 | }
20 |
21 | func test2() {
22 | let formatter = PlaceholderTextInputFormatter(textPattern: "#### ####")
23 | let result = formatter.format("12")
24 | let expectedResult = "12## ####"
25 | XCTAssertEqual(result, expectedResult)
26 | }
27 |
28 | func test3() {
29 | let formatter = PlaceholderTextInputFormatter(textPattern: "#### ####")
30 | let result = formatter.format("")
31 | let expectedResult = "#### ####"
32 | XCTAssertEqual(result, expectedResult)
33 | }
34 |
35 | func test4() {
36 | let formatter = PlaceholderTextInputFormatter(textPattern: "#### ####")
37 | let result = formatter.format(nil)
38 | let expectedResult = "#### ####"
39 | XCTAssertEqual(result, expectedResult)
40 | }
41 |
42 | func test5() {
43 | let formatter = PlaceholderTextInputFormatter(textPattern: "#### ####")
44 | let result = formatter.format("1")
45 | let expectedResult = "1### ####"
46 | XCTAssertEqual(result, expectedResult)
47 | }
48 |
49 | func test6() {
50 | let formatter = PlaceholderTextInputFormatter(textPattern: "#### ####")
51 | let result = formatter.format("123456789")
52 | let expectedResult = "1234 5678"
53 | XCTAssertEqual(result, expectedResult)
54 | }
55 |
56 | func test7() {
57 | let formatter = PlaceholderTextInputFormatter(textPattern: "#### ####")
58 | let result = formatter.format("1234567")
59 | let expectedResult = "1234 567#"
60 | XCTAssertEqual(result, expectedResult)
61 | }
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/Tests/PlaceholderTextInputFormatterTests/FormatInput/Replace/PlaceholderTextInputFormatterReplace3SymbolsTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PlaceholderTextInputFormatterReplace3SymbolsTests.swift
3 | // AnyFormatKitTests
4 | //
5 | // Created by Oleksandr Orlov on 13.11.2020.
6 | // Copyright © 2020 Oleksandr Orlov. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import AnyFormatKit
11 |
12 | class PlaceholderTextInputFormatterReplace3SymbolsTests: XCTestCase {
13 |
14 | // |123| ### -> 789| ###
15 | func test1() {
16 | let formatter = PlaceholderTextInputFormatter(textPattern: "### ###")
17 | let result = formatter.formatInput(
18 | currentText: "123 ###",
19 | range: NSRange(location: 0, length: 3),
20 | replacementString: "789"
21 | )
22 | let expectedResult = FormattedTextValue(formattedText: "789 ###", caretBeginOffset: 3)
23 | XCTAssertEqual(result, expectedResult)
24 | }
25 |
26 | // |123| 456 -> 789| 456
27 | func test2() {
28 | let formatter = PlaceholderTextInputFormatter(textPattern: "### ###")
29 | let result = formatter.formatInput(
30 | currentText: "123 456",
31 | range: NSRange(location: 0, length: 3),
32 | replacementString: "789"
33 | )
34 | let expectedResult = FormattedTextValue(formattedText: "789 456", caretBeginOffset: 3)
35 | XCTAssertEqual(result, expectedResult)
36 | }
37 |
38 | // 1|23 |### -> 178 9|##
39 | func test3() {
40 | let formatter = PlaceholderTextInputFormatter(textPattern: "### ###")
41 | let result = formatter.formatInput(
42 | currentText: "123 ###",
43 | range: NSRange(location: 1, length: 3),
44 | replacementString: "789"
45 | )
46 | let expectedResult = FormattedTextValue(formattedText: "178 9##", caretBeginOffset: 5)
47 | XCTAssertEqual(result, expectedResult)
48 | }
49 |
50 | // 12|3 #|## -> 127 89|#
51 | func test4() {
52 | let formatter = PlaceholderTextInputFormatter(textPattern: "### ###")
53 | let result = formatter.formatInput(
54 | currentText: "123 ###",
55 | range: NSRange(location: 2, length: 3),
56 | replacementString: "789"
57 | )
58 | let expectedResult = FormattedTextValue(formattedText: "127 89#", caretBeginOffset: 6)
59 | XCTAssertEqual(result, expectedResult)
60 | }
61 |
62 | // 12|3 4|56 -> 127 89|5
63 | func test5() {
64 | let formatter = PlaceholderTextInputFormatter(textPattern: "### ###")
65 | let result = formatter.formatInput(
66 | currentText: "123 456",
67 | range: NSRange(location: 2, length: 3),
68 | replacementString: "789"
69 | )
70 | let expectedResult = FormattedTextValue(formattedText: "127 895", caretBeginOffset: 6)
71 | XCTAssertEqual(result, expectedResult)
72 | }
73 |
74 | // 123| ##|# -> 123 789|
75 | func test6() {
76 | let formatter = PlaceholderTextInputFormatter(textPattern: "### ###")
77 | let result = formatter.formatInput(
78 | currentText: "123 ###",
79 | range: NSRange(location: 3, length: 3),
80 | replacementString: "789"
81 | )
82 | let expectedResult = FormattedTextValue(formattedText: "123 789", caretBeginOffset: 7)
83 | XCTAssertEqual(result, expectedResult)
84 | }
85 |
86 | // 123 |###| -> 123 789|
87 | func test7() {
88 | let formatter = PlaceholderTextInputFormatter(textPattern: "### ###")
89 | let result = formatter.formatInput(
90 | currentText: "123 ###",
91 | range: NSRange(location: 4, length: 3),
92 | replacementString: "789"
93 | )
94 | let expectedResult = FormattedTextValue(formattedText: "123 789", caretBeginOffset: 7)
95 | XCTAssertEqual(result, expectedResult)
96 | }
97 |
98 | }
99 |
--------------------------------------------------------------------------------
/Tests/PlaceholderTextInputFormatterTests/Unformat/PlaceholderTextInputUnformattingTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PlaceholderTextInputUnformattingTests.swift
3 | // AnyFormatKitTests
4 | //
5 | // Created by Oleksandr Orlov on 18.01.2021.
6 | // Copyright © 2021 Oleksandr Orlov. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | import AnyFormatKit
11 |
12 | class PlaceholderTextInputUnformattingTests: XCTestCase {
13 |
14 | func test1() {
15 | let formatter = PlaceholderTextInputFormatter(textPattern: "#### ####")
16 | let result = formatter.unformat("12## ####")
17 | let expectedResult = "12"
18 | XCTAssertEqual(result, expectedResult)
19 | }
20 |
21 | func test2() {
22 | let formatter = PlaceholderTextInputFormatter(textPattern: "#### ####")
23 | let result = formatter.unformat("#### ####")
24 | let expectedResult = ""
25 | XCTAssertEqual(result, expectedResult)
26 | }
27 |
28 | func test3() {
29 | let formatter = PlaceholderTextInputFormatter(textPattern: "#### ####")
30 | let result = formatter.unformat("1234 ####")
31 | let expectedResult = "1234"
32 | XCTAssertEqual(result, expectedResult)
33 | }
34 |
35 | func test4() {
36 | let formatter = PlaceholderTextInputFormatter(textPattern: "#### ####")
37 | let result = formatter.unformat("1234 5###")
38 | let expectedResult = "12345"
39 | XCTAssertEqual(result, expectedResult)
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Tests/SumFormatTests/FormatParsingTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FormatParsingTests.swift
3 | // AnyFormatKitTests
4 | //
5 | // Created by Oleksandr Orlov on 11/21/17.
6 | // Copyright © 2017 Oleksandr Orlov. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | import AnyFormatKit
11 |
12 | class FormatParsingTests: XCTestCase {
13 | func test5InGroupFormat() {
14 | let formatter = SumTextFormatter(textPattern: "X.XXXXX,XX", patternSymbol: "X")
15 | let initialString = "1234567890123"
16 | let expectedString = "123.45678.90123"
17 | let formattedString = formatter.format(initialString)
18 | XCTAssert(expectedString == formattedString,
19 | "\(String(describing: formattedString)) must be equal to \(expectedString)")
20 | }
21 |
22 | func test3InGroupFormat() {
23 | let formatter = SumTextFormatter(textPattern: "X.XXX,XX", patternSymbol: "X")
24 | let initialString = "1234567890123"
25 | let expectedString = "1.234.567.890.123"
26 | let formattedString = formatter.format(initialString)
27 | XCTAssert(expectedString == formattedString,
28 | "\(String(describing: formattedString)) must be equal to \(expectedString)")
29 | }
30 |
31 | func test1InGroupFormat() {
32 | let formatter = SumTextFormatter(textPattern: "X.X,XX", patternSymbol: "X")
33 | let initialString = "1234567"
34 | let expectedString = "1.2.3.4.5.6.7"
35 | let formattedString = formatter.format(initialString)
36 | XCTAssert(expectedString == formattedString,
37 | "\(String(describing: formattedString)) must be equal to \(expectedString)")
38 | }
39 |
40 | func testGroupingSeparatorParsing() {
41 | let formatter = SumTextFormatter(textPattern: "X.XXX,XX", patternSymbol: "X")
42 | let initialString = "1234567890"
43 | let expectedString = "1.234.567.890"
44 | let formattedString = formatter.format(initialString)
45 | XCTAssert(expectedString == formattedString,
46 | "\(String(describing: formattedString)) must be equal to \(expectedString)")
47 | }
48 |
49 | func testDecimalSeparatorParsing() {
50 | let formatter = SumTextFormatter(textPattern: "X.XXX,XX", patternSymbol: "X")
51 | let initialString = "12345.12"
52 | let expectedString = "12.345,12"
53 | let formattedString = formatter.format(initialString)
54 | XCTAssert(expectedString == formattedString,
55 | "\(String(describing: formattedString)) must be equal to \(expectedString)")
56 | }
57 |
58 | func testPrefixParsing() {
59 | let formatter = SumTextFormatter(textPattern: "Prefix: X.XXX,XX", patternSymbol: "X")
60 | let initialString = "123456789,01"
61 | let expectedString = "Prefix: 123.456.789,01"
62 | let formattedString = formatter.format(initialString)
63 | XCTAssert(expectedString == formattedString,
64 | "\(String(describing: formattedString)) must be equal to \(expectedString)")
65 | }
66 |
67 | func testSufixParsing() {
68 | let formatter = SumTextFormatter(textPattern: "X.XXX,XX <-Sufix", patternSymbol: "X")
69 | let initialString = "1234567"
70 | let expectedString = "1.234.567 <-Sufix"
71 | let formattedString = formatter.format(initialString)
72 | XCTAssert(expectedString == formattedString,
73 | "\(String(describing: formattedString)) must be equal to \(expectedString)")
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/Tests/SumTextInputFormatterTests/FormatInput/Simple/FormatInput/Delete/SumTextInputFormatterDelete3SymbolsTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SumTextInputFormatterDelete3SymbolsTests.swift
3 | // AnyFormatKitTests
4 | //
5 | // Created by Oleksandr Orlov on 15.06.2019.
6 | // Copyright © 2019 Oleksandr Orlov. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import AnyFormatKit
11 |
12 | class SumTextInputFormatterDelete3SymbolsTests: XCTestCase {
13 |
14 | private let formatter = SumTextInputFormatter(textPattern: "#,###.##")
15 |
16 | // |12,|345.67 -> |345.67
17 | func test1() {
18 | let actualResult = formatter.formatInput(
19 | currentText: "12,345.67",
20 | range: NSRange(location: 0, length: 3),
21 | replacementString: "")
22 | let expectedResult = FormattedTextValue(formattedText: "345.67", caretBeginOffset: 0)
23 | XCTAssert(actualResult == expectedResult, "\n\(actualResult) must be equal to\n\(expectedResult)")
24 | }
25 |
26 | // 1|2,3|45.67 -> 1|45.67
27 | func test2() {
28 | let actualResult = formatter.formatInput(
29 | currentText: "12,345.67",
30 | range: NSRange(location: 1, length: 3),
31 | replacementString: "")
32 | let expectedResult = FormattedTextValue(formattedText: "145.67", caretBeginOffset: 1)
33 | XCTAssert(actualResult == expectedResult, "\n\(actualResult) must be equal to\n\(expectedResult)")
34 | }
35 |
36 | // 12|,34|5.67 -> 12|5.67
37 | func test3() {
38 | let actualResult = formatter.formatInput(
39 | currentText: "12,345.67",
40 | range: NSRange(location: 2, length: 3),
41 | replacementString: "")
42 | let expectedResult = FormattedTextValue(formattedText: "125.67", caretBeginOffset: 2)
43 | XCTAssert(actualResult == expectedResult, "\n\(actualResult) must be equal to\n\(expectedResult)")
44 | }
45 |
46 | // 12,|345|.67 -> 12|.67
47 | func test4() {
48 | let actualResult = formatter.formatInput(
49 | currentText: "12,345.67",
50 | range: NSRange(location: 3, length: 3),
51 | replacementString: "")
52 | let expectedResult = FormattedTextValue(formattedText: "12.67", caretBeginOffset: 2)
53 | XCTAssert(actualResult == expectedResult, "\n\(actualResult) must be equal to\n\(expectedResult)")
54 | }
55 |
56 | // 12,3|45.|67 -> 12,3|67
57 | func test5() {
58 | let actualResult = formatter.formatInput(
59 | currentText: "12,345.67",
60 | range: NSRange(location: 4, length: 3),
61 | replacementString: "")
62 | let expectedResult = FormattedTextValue(formattedText: "12,367", caretBeginOffset: 4)
63 | XCTAssert(actualResult == expectedResult, "\n\(actualResult) must be equal to\n\(expectedResult)")
64 | }
65 |
66 | // 12,34|5.6|7 -> 12,34|7
67 | func test6() {
68 | let actualResult = formatter.formatInput(
69 | currentText: "12,345.67",
70 | range: NSRange(location: 5, length: 3),
71 | replacementString: "")
72 | let expectedResult = FormattedTextValue(formattedText: "12,347", caretBeginOffset: 5)
73 | XCTAssert(actualResult == expectedResult, "\n\(actualResult) must be equal to\n\(expectedResult)")
74 | }
75 |
76 | // 12,345|.67| -> 12,345|
77 | func test7() {
78 | let actualResult = formatter.formatInput(
79 | currentText: "12,345.67",
80 | range: NSRange(location: 6, length: 3),
81 | replacementString: "")
82 | let expectedResult = FormattedTextValue(formattedText: "12,345", caretBeginOffset: 6)
83 | XCTAssert(actualResult == expectedResult, "\n\(actualResult) must be equal to\n\(expectedResult)")
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/Tests/SumTextInputFormatterTests/FormatInput/Simple/FormatInput/Insert/SumTextInputFormatterInput0Tests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SumTextInputFormatterInput0Tests.swift
3 | // AnyFormatKitTests
4 | //
5 | // Created by Oleksandr Orlov on 19.06.2019.
6 | // Copyright © 2019 Oleksandr Orlov. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import AnyFormatKit
11 |
12 | class SumTextInputFormatterInput0Tests: XCTestCase {
13 |
14 | private let formatter = SumTextInputFormatter(textPattern: "#,###.##")
15 |
16 | // 20.| -> 20.0|
17 | func test1() {
18 | let actualResult = formatter.formatInput(
19 | currentText: "20.",
20 | range: NSRange(location: 3, length: 0),
21 | replacementString: "0")
22 | let expectedResult = FormattedTextValue(formattedText: "20.0", caretBeginOffset: 4)
23 | XCTAssert(actualResult == expectedResult, "\n\(actualResult) must be equal to\n\(expectedResult)")
24 | }
25 |
26 | // 20.0| -> 20.00|
27 | func test2() {
28 | let actualResult = formatter.formatInput(
29 | currentText: "20.0",
30 | range: NSRange(location: 4, length: 0),
31 | replacementString: "0")
32 | let expectedResult = FormattedTextValue(formattedText: "20.00", caretBeginOffset: 5)
33 | XCTAssert(actualResult == expectedResult, "\n\(actualResult) must be equal to\n\(expectedResult)")
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Tests/SumTextInputFormatterTests/FormatInput/Simple/FormatInput/Replace/SumTextInputFormatterReplace3SymbolsTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SumTextInputFormatterReplace3SymbolsTests.swift
3 | // AnyFormatKitTests
4 | //
5 | // Created by Oleksandr Orlov on 15.06.2019.
6 | // Copyright © 2019 Oleksandr Orlov. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import AnyFormatKit
11 |
12 | class SumTextInputFormatterReplace3SymbolsTests: XCTestCase {
13 |
14 | let formatter = SumTextInputFormatter(textPattern: "#,###.##")
15 |
16 | // |12,|345.67 -> 809,|345.67
17 | func test1() {
18 | let actualResult = formatter.formatInput(
19 | currentText: "12,345.67",
20 | range: NSRange(location: 0, length: 3),
21 | replacementString: "809")
22 | let expectedResult = FormattedTextValue(formattedText: "809,345.67", caretBeginOffset: 4)
23 | XCTAssert(actualResult == expectedResult, "\n\(actualResult) must be equal to\n\(expectedResult)")
24 | }
25 |
26 | // 1|2,3|45.67 -> 180,9|45.67
27 | func test2() {
28 | let actualResult = formatter.formatInput(
29 | currentText: "12,345.67",
30 | range: NSRange(location: 1, length: 3),
31 | replacementString: "809")
32 | let expectedResult = FormattedTextValue(formattedText: "180,945.67", caretBeginOffset: 5)
33 | XCTAssert(actualResult == expectedResult, "\n\(actualResult) must be equal to\n\(expectedResult)")
34 | }
35 |
36 | // 12|,34|5.67 -> 128,09|5.67
37 | func test3() {
38 | let actualResult = formatter.formatInput(
39 | currentText: "12,345.67",
40 | range: NSRange(location: 2, length: 3),
41 | replacementString: "809")
42 | let expectedResult = FormattedTextValue(formattedText: "128,095.67", caretBeginOffset: 6)
43 | XCTAssert(actualResult == expectedResult, "\n\(actualResult) must be equal to\n\(expectedResult)")
44 | }
45 |
46 | // 12,|345|.67 -> 12,809|.67
47 | func test4() {
48 | let actualResult = formatter.formatInput(
49 | currentText: "12,345.67",
50 | range: NSRange(location: 3, length: 3),
51 | replacementString: "809")
52 | let expectedResult = FormattedTextValue(formattedText: "12,809.67", caretBeginOffset: 6)
53 | XCTAssert(actualResult == expectedResult, "\n\(actualResult) must be equal to\n\(expectedResult)")
54 | }
55 |
56 | // 12,3|45.|67 -> 12,380,9|67
57 | func test5() {
58 | let actualResult = formatter.formatInput(
59 | currentText: "12,345.67",
60 | range: NSRange(location: 4, length: 3),
61 | replacementString: "809")
62 | let expectedResult = FormattedTextValue(formattedText: "12,380,967", caretBeginOffset: 8)
63 | XCTAssert(actualResult == expectedResult, "\n\(actualResult) must be equal to\n\(expectedResult)")
64 | }
65 |
66 | // 12,34|5.6|7 -> 12,348,09|7
67 | func test6() {
68 | let actualResult = formatter.formatInput(
69 | currentText: "12,345.67",
70 | range: NSRange(location: 5, length: 3),
71 | replacementString: "809")
72 | let expectedResult = FormattedTextValue(formattedText: "12,348,097", caretBeginOffset: 9)
73 | XCTAssert(actualResult == expectedResult, "\n\(actualResult) must be equal to\n\(expectedResult)")
74 | }
75 |
76 | // 12,345|.67| -> 12,345,809|
77 | func test7() {
78 | let actualResult = formatter.formatInput(
79 | currentText: "12,345.67",
80 | range: NSRange(location: 6, length: 3),
81 | replacementString: "809")
82 | let expectedResult = FormattedTextValue(formattedText: "12,345,809", caretBeginOffset: 10)
83 | XCTAssert(actualResult == expectedResult, "\n\(actualResult) must be equal to\n\(expectedResult)")
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/Tests/SumTextInputFormatterTests/FormatInput/WithPrefix/2SymbolsPrefix/Delete/SumTextInputFormatterWith2SymbolsPrefixBy1SymbolErasingTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SumTextInputFormatterWith2SymbolsPrefixBy1SymbolErasingTests.swift
3 | // AnyFormatKitTests
4 | //
5 | // Created by Oleksandr Orlov on 20.06.2019.
6 | // Copyright © 2019 Oleksandr Orlov. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import AnyFormatKit
11 |
12 | class SumTextInputFormatterWith2SymbolsPrefixBy1SymbolErasingTests: XCTestCase {
13 |
14 | private let formatter = SumTextInputFormatter(textPattern: "$ #,###.##")
15 |
16 | // $ 12.3|4| -> $ 12.3|
17 | func test1() {
18 | let actualResult = formatter.formatInput(
19 | currentText: "$ 12.34",
20 | range: NSRange(location: 6, length: 1),
21 | replacementString: "")
22 | let expectedResult = FormattedTextValue(formattedText: "$ 12.3", caretBeginOffset: 6)
23 | XCTAssert(actualResult == expectedResult, "\n\(actualResult) must be equal to\n\(expectedResult)")
24 | }
25 |
26 | // $ 12.|3| -> $ 12.|
27 | func test2() {
28 | let actualResult = formatter.formatInput(
29 | currentText: "$ 12.3",
30 | range: NSRange(location: 5, length: 1),
31 | replacementString: "")
32 | let expectedResult = FormattedTextValue(formattedText: "$ 12.", caretBeginOffset: 5)
33 | XCTAssert(actualResult == expectedResult, "\n\(actualResult) must be equal to\n\(expectedResult)")
34 | }
35 |
36 | // $ 12|.| -> $ 12|
37 | func test3() {
38 | let actualResult = formatter.formatInput(
39 | currentText: "$ 12.",
40 | range: NSRange(location: 4, length: 1),
41 | replacementString: "")
42 | let expectedResult = FormattedTextValue(formattedText: "$ 12", caretBeginOffset: 4)
43 | XCTAssert(actualResult == expectedResult, "\n\(actualResult) must be equal to\n\(expectedResult)")
44 | }
45 |
46 | // $ 1|2| -> $ 1|
47 | func test4() {
48 | let actualResult = formatter.formatInput(
49 | currentText: "$ 12",
50 | range: NSRange(location: 3, length: 1),
51 | replacementString: "")
52 | let expectedResult = FormattedTextValue(formattedText: "$ 1", caretBeginOffset: 3)
53 | XCTAssert(actualResult == expectedResult, "\n\(actualResult) must be equal to\n\(expectedResult)")
54 | }
55 |
56 | // $ |1| -> "|"
57 | func test5() {
58 | let actualResult = formatter.formatInput(
59 | currentText: "$ 1",
60 | range: NSRange(location: 2, length: 1),
61 | replacementString: "")
62 | let expectedResult = FormattedTextValue(formattedText: "", caretBeginOffset: 0)
63 | XCTAssert(actualResult == expectedResult, "\n\(actualResult) must be equal to\n\(expectedResult)")
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/Tests/SumTextInputFormatterTests/FormatInput/WithPrefix/2SymbolsPrefix/Insert/SumTextInputFormatterWith2SymbolsPrefixInputTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SumTextInputFormatterWith2SymbolsPrefixInputTests.swift
3 | // AnyFormatKitTests
4 | //
5 | // Created by Oleksandr Orlov on 20.06.2019.
6 | // Copyright © 2019 Oleksandr Orlov. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import AnyFormatKit
11 |
12 | class SumTextInputFormatterWith2SymbolsPrefixInputTests: XCTestCase {
13 |
14 | private let formatter = SumTextInputFormatter(textPattern: "$ #,###.##")
15 |
16 | // "|" -> $ 1|
17 | func test1() {
18 | let actualResult = formatter.formatInput(
19 | currentText: "",
20 | range: NSRange(location: 0, length: 0),
21 | replacementString: "1")
22 | let expectedResult = FormattedTextValue(formattedText: "$ 1", caretBeginOffset: 3)
23 | XCTAssert(actualResult == expectedResult, "\n\(actualResult) must be equal to\n\(expectedResult)")
24 | }
25 |
26 | // $ 1| -> $ 1.
27 | func test2() {
28 | let actualResult = formatter.formatInput(
29 | currentText: "$ 1",
30 | range: NSRange(location: 3, length: 0),
31 | replacementString: ".")
32 | let expectedResult = FormattedTextValue(formattedText: "$ 1.", caretBeginOffset: 4)
33 | XCTAssert(actualResult == expectedResult, "\n\(actualResult) must be equal to\n\(expectedResult)")
34 | }
35 |
36 | // $ 1.| -> $ 1.2
37 | func test3() {
38 | let actualResult = formatter.formatInput(
39 | currentText: "$ 1.",
40 | range: NSRange(location: 4, length: 0),
41 | replacementString: "2")
42 | let expectedResult = FormattedTextValue(formattedText: "$ 1.2", caretBeginOffset: 5)
43 | XCTAssert(actualResult == expectedResult, "\n\(actualResult) must be equal to\n\(expectedResult)")
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/Tests/SumTextInputFormatterTests/FormatInput/WithSuffix/1SymbolSuffix/Insert/SumTextInputFormatterWithSuffixInput0Tests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SumTextInputFormatterWithSuffixInput0Tests.swift
3 | // AnyFormatKitTests
4 | //
5 | // Created by Oleksandr Orlov on 19.06.2019.
6 | // Copyright © 2019 Oleksandr Orlov. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import AnyFormatKit
11 |
12 | class SumTextInputFormatterWithSuffixInput0Tests: XCTestCase {
13 |
14 | private let formatter = SumTextInputFormatter(textPattern: "#,###.## $")
15 |
16 | // 20.| $ -> 20.0| $
17 | func test1() {
18 | let actualResult = formatter.formatInput(
19 | currentText: "20. $",
20 | range: NSRange(location: 3, length: 0),
21 | replacementString: "0")
22 | let expectedResult = FormattedTextValue(formattedText: "20.0 $", caretBeginOffset: 4)
23 | XCTAssert(actualResult == expectedResult, "\n\(actualResult) must be equal to\n\(expectedResult)")
24 | }
25 |
26 | // 20.0| $ -> 20.00| $
27 | func test2() {
28 | let actualResult = formatter.formatInput(
29 | currentText: "20.0 $",
30 | range: NSRange(location: 4, length: 0),
31 | replacementString: "0")
32 | let expectedResult = FormattedTextValue(formattedText: "20.00 $", caretBeginOffset: 5)
33 | XCTAssert(actualResult == expectedResult, "\n\(actualResult) must be equal to\n\(expectedResult)")
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Tests/SumTextInputFormatterTests/FormatInput/WithSuffix/2SymbolSuffix/Insert/SumTextInputFormatterWith2SymbolsSuffixBy1SymbolInputTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SumTextInputFormatterWith2SymbolsSuffixBy1SymbolInputTests.swift
3 | // AnyFormatKitTests
4 | //
5 | // Created by Oleksandr Orlov on 20.06.2019.
6 | // Copyright © 2019 Oleksandr Orlov. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import AnyFormatKit
11 |
12 | class SumTextInputFormatterWith2SymbolsSuffixBy1SymbolInputTests: XCTestCase {
13 |
14 | private let formatter = SumTextInputFormatter(textPattern: "#,###.## $")
15 |
16 | // "|" -> 1| $
17 | func test1() {
18 | let actualResult = formatter.formatInput(
19 | currentText: "",
20 | range: NSRange(location: 0, length: 0),
21 | replacementString: "1")
22 | let expectedResult = FormattedTextValue(formattedText: "1 $", caretBeginOffset: 1)
23 | XCTAssert(actualResult == expectedResult, "\n\(actualResult) must be equal to\n\(expectedResult)")
24 | }
25 |
26 | // 1| $ -> 12| $
27 | func test2() {
28 | let actualResult = formatter.formatInput(
29 | currentText: "1 $",
30 | range: NSRange(location: 1, length: 0),
31 | replacementString: "2")
32 | let expectedResult = FormattedTextValue(formattedText: "12 $", caretBeginOffset: 2)
33 | XCTAssert(actualResult == expectedResult, "\n\(actualResult) must be equal to\n\(expectedResult)")
34 | }
35 |
36 | // 12| $ -> 12.| $
37 | func test3() {
38 | let actualResult = formatter.formatInput(
39 | currentText: "12 $",
40 | range: NSRange(location: 2, length: 0),
41 | replacementString: ".")
42 | let expectedResult = FormattedTextValue(formattedText: "12. $", caretBeginOffset: 3)
43 | XCTAssert(actualResult == expectedResult, "\n\(actualResult) must be equal to\n\(expectedResult)")
44 | }
45 |
46 | // 12.| $ -> 12.3 $
47 | func test4() {
48 | let actualResult = formatter.formatInput(
49 | currentText: "12. $",
50 | range: NSRange(location: 3, length: 0),
51 | replacementString: "3")
52 | let expectedResult = FormattedTextValue(formattedText: "12.3 $", caretBeginOffset: 4)
53 | XCTAssert(actualResult == expectedResult, "\n\(actualResult) must be equal to\n\(expectedResult)")
54 | }
55 |
56 | // 12.3| $ -> 12.34| $
57 | func test5() {
58 | let actualResult = formatter.formatInput(
59 | currentText: "12.3 $",
60 | range: NSRange(location: 4, length: 0),
61 | replacementString: "4")
62 | let expectedResult = FormattedTextValue(formattedText: "12.34 $", caretBeginOffset: 5)
63 | XCTAssert(actualResult == expectedResult, "\n\(actualResult) must be equal to\n\(expectedResult)")
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/run-tests.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | xcodebuild -project AnyFormatKit.xcodeproj -scheme "AnyFormatKit" -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 11 Pro Max,OS=13.3' test
3 |
--------------------------------------------------------------------------------
/update_version.rb:
--------------------------------------------------------------------------------
1 | if ARGV.empty?
2 | print("❌ syntax had to be 'ruby update_version.rb version\n'")
3 | exit
4 | end
5 |
6 | $new_version = ARGV[0]
7 |
8 | def update_version(filePath, line_start, line_end)
9 | file_data = File.open(filePath).readlines.map(&:chomp)
10 |
11 | File.open(filePath, "w") { |file|
12 | file_data.each { |line|
13 | edited_line = line
14 |
15 | if line.include? line_start
16 | edited_line = "#{line_start}#{$new_version}#{line_end}"
17 | end
18 |
19 | file.write "#{edited_line}\n"
20 | }
21 | }
22 | end
23 |
24 |
25 |
26 | print("• updating podspec file\n")
27 |
28 | podspec_version_line_start = " s.version = '"
29 | podspec_version_line_end = "'"
30 |
31 | update_version('AnyFormatKit.podspec', podspec_version_line_start, podspec_version_line_end)
32 |
33 |
34 | print("• updating README file\n")
35 |
36 | spm_package_line_start = ' .package(url: "https://github.com/luximetr/AnyFormatKit.git", .upToNextMajor(from: "'
37 | spm_package_line_end = '"))'
38 |
39 | pod_line_start = "pod 'AnyFormatKit', '~> "
40 | pod_line_end = "'"
41 |
42 | update_version('README.md', spm_package_line_start, spm_package_line_end)
43 | update_version('README.md', pod_line_start, pod_line_end)
44 |
45 |
46 | print("• updating xcodeproj file\n")
47 |
48 | xproj_version_line_start = " MARKETING_VERSION = "
49 | xproj_version_line_end = ";"
50 |
51 | update_version('AnyFormatKit.xcodeproj/project.pbxproj', xproj_version_line_start, xproj_version_line_end)
52 |
53 | print "✅ done\n"
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------