├── .gitignore
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING
├── LICENSE
├── README.md
├── SSFloatingLabelTextField.podspec
├── SSFloatingLabelTextField
├── Assests
│ └── Images.xcassets
│ │ ├── Contents.json
│ │ ├── eyeClose.imageset
│ │ ├── Contents.json
│ │ └── visibility.png
│ │ └── eyeOpen.imageset
│ │ ├── Contents.json
│ │ └── view.png
└── Classes
│ ├── Constants + Enums.swift
│ ├── SSFloatingLabelTextField.swift
│ └── StringExtension.swift
├── SSFloatingTextFieldDemo
├── Podfile
├── SSFloatingTextFieldDemo.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── SSFloatingTextFieldDemo.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
└── SSFloatingTextFieldDemo
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ ├── AccentColor.colorset
│ │ └── Contents.json
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ └── Contents.json
│ ├── Info.plist
│ ├── LaunchScreen.storyboard
│ ├── Main.storyboard
│ └── ViewController.swift
└── screenshots
├── Installation.png
├── SSFloatingTextField.gif
└── simformBanner.png
/.gitignore:
--------------------------------------------------------------------------------
1 | # Add any directories, files, or patterns you don't want to be tracked by version control
2 | # Xcode
3 | #
4 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
5 |
6 |
7 |
8 | ## Build generated
9 | build/
10 | DerivedData/
11 |
12 |
13 |
14 | ## Various settings
15 | *.pbxuser
16 | !default.pbxuser
17 | *.mode1v3
18 | !default.mode1v3
19 | *.mode2v3
20 | !default.mode2v3
21 | *.perspectivev3
22 | !default.perspectivev3
23 | xcuserdata/
24 | *.generated.swift
25 |
26 |
27 | ## Other
28 | *.moved-aside
29 | *.xccheckout
30 | *.xcscmblueprint
31 |
32 |
33 |
34 | ## Obj-C/Swift specific
35 | *.hmap
36 | *.ipa
37 | *.dSYM.zip
38 | *.dSYM
39 |
40 |
41 |
42 | ## Playgrounds
43 | timeline.xctimeline
44 | playground.xcworkspace
45 |
46 |
47 |
48 | # Swift Package Manager
49 | #
50 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
51 | # Packages/
52 | # Package.pins
53 | # Package.resolved
54 | .build/
55 |
56 |
57 |
58 | # CocoaPods
59 | #
60 | # We recommend against adding the Pods directory to your .gitignore. However
61 | # you should judge for yourself, the pros and cons are mentioned at:
62 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
63 | #
64 | Pods/
65 |
66 |
67 |
68 | # Carthage
69 | #
70 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
71 | # Carthage/Checkouts
72 |
73 |
74 |
75 | Carthage/Build
76 |
77 |
78 |
79 | # fastlane
80 | #
81 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
82 | # screenshots whenever they are needed.
83 | # For more information about the recommended setup visit:
84 | # https://docs.fastlane.tools/best-practices/source-control/#source-control
85 |
86 |
87 |
88 | fastlane/report.xml
89 | fastlane/Preview.html
90 | fastlane/screenshots
91 | fastlane/test_output
92 | .DS_Store
93 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at mohammed.h@simformsolutions.com. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72 |
73 | [homepage]: https://www.contributor-covenant.org
74 |
75 | For answers to common questions about this code of conduct, see
76 | https://www.contributor-covenant.org/faq
77 |
--------------------------------------------------------------------------------
/CONTRIBUTING:
--------------------------------------------------------------------------------
1 | # Way to contribute
2 |
3 | 1. Fork the repo and create your branch from `master`.
4 | 2. Clone the project to your own machine. (Please have a look at [**Readme.md**](https://github.com/SimformSolutionsPvtLtd/Kotlin-multiplatform-sample/blob/master/README.md) to understand how to run this project on your machine)
5 | 3. Commit changes to your own branch
6 | 4. Make sure your code lints.
7 | 5. Push your work back up to your fork.
8 | 6. Issue that pull request!
9 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 mobile-simformsolutions
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | [![Platform][platform-image]][platform-url]
4 | [![Swift Version][swift-image]][swift-url]
5 | [![License][license-image]][license-url]
6 | [![PRs Welcome][PR-image]][PR-url]
7 |
8 | # SSFloatingLabelTextField
9 |
10 | SSFloatingLabelTextField is a small library for iOS which supports Floating labels and errors with different kind of validations. Also user can add/customise own validation and error messages.
11 |
12 | 
13 |
14 | # Features!
15 |
16 | Main Features include :-
17 | - Floating Placeholder label
18 | - Set different validations type
19 | - Set Custom regex for validation or for phone number formatter
20 | - Check if text is valid or not and display error message
21 |
22 | All Attributes :-
23 | | Attribute | Description |
24 | | --- | --- |
25 | | `floatingLabelText` | Floating Placeholder label
26 | | `selectedLabelColor` | Color of Floating label when textfield is active
27 | | `unSelectedLabelColor` | Color of Floating label when textfield is active
28 | | `errorText` | Error message when text is not valid
29 | | `errorTextColor` | Color in which error message is shown
30 | | `type` | Set Validation type
31 | | `customValidationRegex` | Set Custom Regex for Validation
32 | | `isPasswordToggleEnable` | Toggle show hide password
33 | | `showPasswordImage` | Toggle image when password is visible
34 | | `hidePasswordImage` | Toggle image when password is visible
35 |
36 | # Requirements
37 | - iOS 11.0+
38 | - Xcode 11+
39 |
40 | # Installation
41 | #### CocoaPods
42 |
43 | - You can use CocoaPods to install `SSFloatingLabelTextField` by adding it to your Podfile:
44 |
45 | use_frameworks!
46 | pod 'SSFloatingLabelTextField'
47 |
48 | - Import SSFloatingLabelTextField in your file:
49 |
50 | import SSFloatingLabelTextField
51 |
52 | **Manually**
53 | - Download and drop **SSFloatingLabelTextField/Sources** folder in your project.
54 | - Congratulations!
55 |
56 |
57 | # Usage example
58 |
59 | In the storyboard add a UITextField and change its class to SSFloatingLabelTextField
60 |
61 |
62 |
63 | Import SSFloatingLabelTextField
64 |
65 | import SSFloatingLabelTextField
66 |
67 | Set text type in your View Controller file :-
68 |
69 | @IBOutlet weak var txtUsername: SSFloatingLabelTextField! // Add IBOutlet
70 | txtEmail.type = .email // Assign type as email
71 | txtPassword.type = .password(passwordRule: .medium) // Assign type as password
72 | txtPhoneNumber.type = .phoneNumber(formatterString: nil) // Assign type as phone number (Params :- Phone number formatter default :- XXX-XXX-XXXX )
73 |
74 | Check if given text field is valid or not :-
75 |
76 | txtUsername.isValid()
77 |
78 |
79 | ## Find this library useful? :heart:
80 | Support it by joining __[stargazers](https://github.com/mobile-simformsolutions/SSFloatingLabelTextField/stargazers)__ for this repository. :star:
81 |
82 | ## 🤝 How to Contribute
83 |
84 | Whether you're helping us fix bugs, improve the docs, or a feature request, we'd love to have you! :muscle:
85 |
86 | Check out our [**Contributing Guide**](https://github.com/mobile-simformsolutions/SSFloatingLabelTextField/blob/master/CONTRIBUTING.md) for ideas on contributing.
87 |
88 | ## Bugs and Feedback
89 |
90 | For bugs, feature requests, and discussion please use [GitHub Issues](https://github.com/mobile-simformsolutions/SSFloatingLabelTextField/issues).
91 |
92 |
93 | # Meta
94 | - This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details
95 |
96 |
97 | [swift-image]:https://img.shields.io/badge/swift-5.0-orange.svg
98 | [swift-url]: https://swift.org/
99 | [license-image]: https://img.shields.io/badge/License-MIT-blue.svg
100 | [license-url]: LICENSE
101 | [platform-image]:https://img.shields.io/cocoapods/p/LFAlertController.svg?style=flat
102 | [platform-url]:https://github.com/mobile-simformsolutions/SSSwiftUISpinnerButton
103 | [PR-image]:https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square
104 | [PR-url]:http://makeapullrequest.com
105 |
--------------------------------------------------------------------------------
/SSFloatingLabelTextField.podspec:
--------------------------------------------------------------------------------
1 | #
2 | # Be sure to run `pod spec lint SSFloatingLabelTextField.podspec' to ensure this is a
3 | # valid spec and to remove all comments including this before submitting the spec.
4 | #
5 | # To learn more about Podspec attributes see https://guides.cocoapods.org/syntax/podspec.html
6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/
7 | #
8 |
9 | Pod::Spec.new do |spec|
10 |
11 | spec.name = "SSFloatingLabelTextField"
12 | spec.version = "1.0.0"
13 | spec.summary = "A small framework to use Floating label and show errors of SSFloatingLabelTextField."
14 | spec.description = "A small framework to use Floating label and show errors of SSFloatingLabelTextField."
15 |
16 | spec.homepage = "https://github.com/mobile-simformsolutions/SSFloatingLabelTextField"
17 | spec.license = { :type => "MIT", :file => "LICENSE" }
18 | spec.author = { 'Simform Solutions' => 'developer@simform.com' }
19 | spec.platform = :ios
20 | spec.ios.deployment_target = "11.0"
21 | spec.swift_versions = '5.0'
22 |
23 | spec.source = { :git => "https://github.com/mobile-simformsolutions/SSFloatingLabelTextField", :tag => "#{spec.version}" }
24 |
25 | spec.source_files = "SSFloatingLabelTextField/Classes/**"
26 | spec.framework = 'UIKit'
27 |
28 | end
29 |
--------------------------------------------------------------------------------
/SSFloatingLabelTextField/Assests/Images.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/SSFloatingLabelTextField/Assests/Images.xcassets/eyeClose.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "visibility.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/SSFloatingLabelTextField/Assests/Images.xcassets/eyeClose.imageset/visibility.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimformSolutionsPvtLtd/SSFloatingLabelTextField/3b425b141df546d19bf726525e10caa04c699172/SSFloatingLabelTextField/Assests/Images.xcassets/eyeClose.imageset/visibility.png
--------------------------------------------------------------------------------
/SSFloatingLabelTextField/Assests/Images.xcassets/eyeOpen.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "view.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "author" : "xcode",
19 | "version" : 1
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/SSFloatingLabelTextField/Assests/Images.xcassets/eyeOpen.imageset/view.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimformSolutionsPvtLtd/SSFloatingLabelTextField/3b425b141df546d19bf726525e10caa04c699172/SSFloatingLabelTextField/Assests/Images.xcassets/eyeOpen.imageset/view.png
--------------------------------------------------------------------------------
/SSFloatingLabelTextField/Classes/Constants + Enums.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Constants + Enums.swift
3 | // SSFloatingLabelTextField
4 | //
5 | // Created by Mohammed Hanif on 30/06/21.
6 | //
7 |
8 | import Foundation
9 |
10 | public class Constants {
11 | static let emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"
12 | // Minimum eight characters, at least one letter, one number and one special character:
13 | static let weakPasswordRegex = "^(?=.*[A-Za-z])(?=.*\\d)(?=.*[@$!%*#?&])[A-Za-z\\d@$!%*#?&]{8,}$"
14 | // Minimum eight characters, at least one uppercase letter, one lowercase letter, one number and one special character:
15 | static let mediumPasswordRegex = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]{8,}$"
16 | // Minimum eight and maximum 10 characters, at least one uppercase letter, one lowercase letter, one number and one special character:
17 | static let strongPasswordRegex = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]{8,10}$"
18 | // Phone number formatter mask
19 | static var phoneNumberMask = "XXX-XXX-XXXX"
20 | }
21 |
22 | public enum Type {
23 | case email
24 | case password(passwordRule: PasswordRule)
25 | case phoneNumber(formatterString: String?)
26 | }
27 |
28 | public enum PasswordRule {
29 | case weak
30 | case medium
31 | case strong
32 | }
33 |
--------------------------------------------------------------------------------
/SSFloatingLabelTextField/Classes/SSFloatingLabelTextField.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SSFloatingLabelTextField.swift
3 | // SSFloatingLabelTextField
4 | //
5 | // Created by Mohammed Hanif on 21/06/21.
6 | //
7 |
8 | import Foundation
9 | import UIKit
10 | import Combine
11 |
12 | open class SSFloatingLabelTextField: UITextField {
13 |
14 | // MARK:- Variables
15 | /// placeholder label
16 | var placeholderLabel: UILabel = UILabel(frame: CGRect.zero)
17 | /// Error Label
18 | var errorLabel: UILabel = UILabel(frame: CGRect.zero)
19 | // Default height
20 | var placeholderLabelHeight: CGFloat = 14
21 | // Set any predefine validation type
22 | open var type: Type? {
23 | didSet {
24 | switch type {
25 | case .email:
26 | self.keyboardType = .emailAddress
27 | case .phoneNumber:
28 | self.keyboardType = .numberPad
29 | default:
30 | break
31 | }
32 | }
33 | }
34 | // Button for toggle password
35 | let button = UIButton(type: .custom)
36 |
37 | // Defines Placeholder label text
38 | @IBInspectable
39 | open var floatingLabelText: String?
40 |
41 | // Defines error text which will be displayed when text is not valid
42 | @IBInspectable
43 | open var errorText: String? {
44 | didSet {
45 | errorLabel.text = errorText
46 | setNeedsDisplay()
47 | }
48 | }
49 |
50 | // Color of error text
51 | @IBInspectable
52 | open var errorTextColor: UIColor = UIColor.black {
53 | didSet {
54 | errorLabel.textColor = errorTextColor
55 | setNeedsDisplay()
56 | }
57 | }
58 |
59 | // Color for floating label By defaul :- Blue
60 | @IBInspectable
61 | open var selectedLabelColor: UIColor = UIColor.blue
62 |
63 | // Color for floating label By defaul :- Grey
64 | @IBInspectable
65 | open var unSelectedLabelColor: UIColor = UIColor.gray
66 |
67 | // Set Custom regex for Text Validation
68 | @IBInspectable
69 | var customValidationRegex: String?
70 |
71 | @available(iOS 13.0, *)
72 | private(set) lazy var cancellables = [AnyCancellable]()
73 |
74 | // Set if you want to show hide password with icon
75 | @IBInspectable
76 | open var isPasswordToggleEnable: Bool = false {
77 | didSet {
78 | if isPasswordToggleEnable {
79 | enablePasswordToggle()
80 | }
81 | }
82 | }
83 |
84 | // Toggle image when password is shown (Only required if password toggle is enable)
85 | @IBInspectable
86 | open var showPasswordImage: UIImage? = UIImage(named: "eyeOpen") {
87 | didSet {
88 | setPasswordToggleImage(button)
89 | }
90 | }
91 |
92 | // Toggle image when password is hidden (Only required if password toggle is enable)
93 | @IBInspectable
94 | open var hidePasswordImage: UIImage? = UIImage(named: "eyeClose") {
95 | didSet {
96 | setPasswordToggleImage(button)
97 | }
98 | }
99 |
100 | required public init?(coder aDecoder: NSCoder) {
101 | super.init(coder: aDecoder)
102 | baseSetup()
103 | }
104 |
105 | override init(frame: CGRect) {
106 | super.init(frame: frame)
107 | baseSetup()
108 | }
109 |
110 | @objc func onEditingChanged() {
111 | updateValidation()
112 | }
113 |
114 | /// On Textfield editing end
115 | @objc func onEditingEnd() {
116 | placeholderLabel.textColor = unSelectedLabelColor
117 | setNeedsDisplay()
118 | }
119 |
120 | /// /// On Textfield editing begin
121 | @objc func onEditingBegin() {
122 | placeholderLabel.textColor = selectedLabelColor
123 | setNeedsDisplay()
124 | }
125 |
126 | /// When toggle password is clicked
127 | /// - Parameter sender: UIButton used for toggle
128 | @IBAction func togglePasswordView(_ sender: UIButton) {
129 | self.isSecureTextEntry = !self.isSecureTextEntry
130 | setPasswordToggleImage(sender)
131 | }
132 |
133 | /// Initial Setup
134 | fileprivate func baseSetup() {
135 | placeholderLabel = UILabel(frame: CGRect.zero)
136 | addTarget(self, action: #selector(self.onEditingBegin), for: .editingDidBegin)
137 | addTarget(self, action: #selector(self.onEditingEnd), for: .editingDidEnd)
138 | addError()
139 | if #available(iOS 13.0, *) {
140 | setUpValidations()
141 | } else {
142 | addTarget(self, action: #selector(self.onEditingChanged), for: .editingChanged)
143 | }
144 | }
145 |
146 | /// Add Validations
147 | @available(iOS 13.0, *)
148 | func setUpValidations() {
149 | NotificationCenter.default.publisher(for: SSFloatingLabelTextField.textDidChangeNotification, object: self)
150 | .sink { (text) in
151 | self.updateValidation()
152 | }.store(in: &cancellables)
153 | }
154 |
155 | /// Set password toggle images
156 | /// - Parameter button: UI Button which is used for toggle
157 | func setPasswordToggleImage(_ button: UIButton) {
158 | if(isSecureTextEntry) {
159 | button.setImage(hidePasswordImage, for: .normal)
160 | } else {
161 | button.setImage(showPasswordImage, for: .normal)
162 | }
163 | }
164 |
165 | /// Enable password toggle
166 | func enablePasswordToggle(){
167 | button.imageEdgeInsets = UIEdgeInsets(top: 0, left: -16, bottom: 0, right: 0)
168 | button.frame = CGRect(x: CGFloat(self.frame.size.width - 25), y: CGFloat(5), width: CGFloat(25), height: CGFloat(25))
169 | button.addTarget(self, action: #selector(self.togglePasswordView), for: .touchUpInside)
170 | self.rightView = button
171 | self.rightViewMode = .always
172 | setPasswordToggleImage(button)
173 | }
174 |
175 | /// Validate text according to the validation types
176 | func updateValidation() {
177 | self.addFloatingLabel()
178 | guard let _validationType = self.type else {
179 | self.validate(regex: nil)
180 | return
181 | }
182 | switch _validationType {
183 | case .phoneNumber(let formatterString):
184 | text = text?.format(with: formatterString ?? Constants.phoneNumberMask)
185 | self.addFloatingLabel()
186 | default:
187 | break
188 | }
189 | if self.customValidationRegex != nil {
190 | self.validate(regex: self.customValidationRegex)
191 | } else {
192 | switch _validationType {
193 | case .email:
194 | self.validate(regex: Constants.emailRegex)
195 | case .password(let rule):
196 | switch rule {
197 | case .weak:
198 | self.validate(regex: Constants.weakPasswordRegex)
199 | case .medium:
200 | self.validate(regex: Constants.mediumPasswordRegex)
201 | case .strong:
202 | self.validate(regex: Constants.strongPasswordRegex)
203 | }
204 | case .phoneNumber(let mask):
205 | if self.text?.count == (mask?.count ?? Constants.phoneNumberMask.count) {
206 | remmoveError()
207 | } else {
208 | addError()
209 | }
210 | }
211 | }
212 | }
213 |
214 | /// Validate any regex ans show hide error
215 | /// - Parameter regex: regex which needs to be validated
216 | func validate(regex: String?) {
217 | if text?.isValidRegex(regex: regex) ?? false {
218 | remmoveError()
219 | } else {
220 | addError()
221 | }
222 | }
223 |
224 | /// Add label if not already added
225 | func addFloatingLabel() {
226 | if text != "" {
227 | if (self.subviews.contains(placeholderLabel)) {
228 | return
229 | }
230 | placeholderLabel.textColor = selectedLabelColor
231 | placeholderLabel.font = UIFont.systemFont(ofSize: 15.0)
232 | placeholderLabel.text = floatingLabelText
233 | placeholderLabel.layer.backgroundColor = UIColor.white.cgColor
234 | placeholderLabel.translatesAutoresizingMaskIntoConstraints = false
235 | placeholderLabel.clipsToBounds = true
236 | placeholderLabel.frame = CGRect(x: 0, y: 0, width: self.frame.size.width, height: placeholderLabelHeight)
237 | self.addSubview(self.placeholderLabel)
238 | UIView.animate(withDuration: 0.5) {
239 | self.placeholderLabel.bottomAnchor.constraint(equalTo: self.topAnchor, constant: -10).isActive = true // Place our label 10pts above the text field
240 | }
241 | } else {
242 | self.placeholderLabel.removeFromSuperview()
243 | }
244 | self.setNeedsDisplay()
245 | }
246 |
247 | /// Add error if not already added
248 | func addError() {
249 | if (self.subviews.contains(errorLabel)) {
250 | return
251 | }
252 | errorLabel.font = UIFont.systemFont(ofSize: 15.0)
253 | errorLabel.numberOfLines = 0
254 | errorLabel.layer.backgroundColor = UIColor.white.cgColor
255 | errorLabel.translatesAutoresizingMaskIntoConstraints = false
256 | errorLabel.clipsToBounds = true
257 | errorLabel.frame = CGRect(x: 0, y: 0, width: self.frame.size.width, height: placeholderLabelHeight)
258 | self.addSubview(self.errorLabel)
259 | UIView.animate(withDuration: 0.5) {
260 | self.errorLabel.topAnchor.constraint(equalTo: self.bottomAnchor, constant: 10).isActive = true // Place our label 10pts below the text field
261 | self.errorLabel.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 0).isActive = true
262 | self.errorLabel.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: 0).isActive = true
263 | }
264 | setNeedsDisplay()
265 | }
266 |
267 | /// remove error
268 | func remmoveError() {
269 | if text != "" {
270 | self.errorLabel.removeFromSuperview()
271 | }
272 | setNeedsDisplay()
273 | }
274 |
275 | /// Check if current text field is valid or not
276 | /// - Parameter validationType: Validation typr if used predefine
277 | /// - Returns: return is textfield is valid or not
278 | open func isValid() -> Bool {
279 | guard let validation = type else {
280 | return !(text?.isEmpty ?? false)
281 | }
282 | if customValidationRegex != nil {
283 | return text?.isValidRegex(regex: customValidationRegex) ?? false
284 | } else {
285 | switch (validation) {
286 | case .email:
287 | return text?.isValidRegex(regex: Constants.emailRegex) ?? false
288 | case .password(let rule):
289 | switch rule {
290 | case .weak:
291 | return text?.isValidRegex(regex: Constants.weakPasswordRegex) ?? false
292 | case .medium:
293 | return text?.isValidRegex(regex: Constants.mediumPasswordRegex) ?? false
294 | case .strong:
295 | return text?.isValidRegex(regex: Constants.strongPasswordRegex) ?? false
296 | }
297 | case .phoneNumber(let mask):
298 | return text?.count == (mask?.count ?? Constants.phoneNumberMask.count)
299 | }
300 | }
301 | }
302 |
303 | }
304 |
--------------------------------------------------------------------------------
/SSFloatingLabelTextField/Classes/StringExtension.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Extension.swift
3 | // SSFloatingLabelTextField
4 | //
5 | // Created by Mohammed Hanif on 22/06/21.
6 | //
7 |
8 | import Foundation
9 |
10 | extension String {
11 |
12 | func isValidRegex(regex: String?) -> Bool {
13 | guard let regex = regex else {
14 | return !self.isEmpty
15 | }
16 | let passwordPred = NSPredicate(format: "SELF MATCHES %@", regex)
17 | return passwordPred.evaluate(with: self)
18 | }
19 |
20 | /// Phone Number Format
21 | /// - Parameters:
22 | /// - mask: Mask String
23 | /// - Returns: Formatted String
24 | func format(with mask: String) -> String {
25 | let numbers = self.replacingOccurrences(of: "[^0-9]", with: "", options: .regularExpression)
26 | var result = ""
27 | var index = numbers.startIndex
28 | for ch in mask where index < numbers.endIndex {
29 | if ch == "X" {
30 | result.append(numbers[index])
31 | index = numbers.index(after: index)
32 | } else {
33 | result.append(ch)
34 | }
35 | }
36 | return result
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/SSFloatingTextFieldDemo/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment the next line to define a global platform for your project
2 | # platform :ios, '9.0'
3 |
4 | target 'SSFloatingTextFieldDemo' do
5 | # Comment the next line if you don't want to use dynamic frameworks
6 | use_frameworks!
7 |
8 | pod 'SSFloatingLabelTextField'
9 |
10 | # Pods for SSFloatingTextFieldDemo
11 |
12 | end
13 |
--------------------------------------------------------------------------------
/SSFloatingTextFieldDemo/SSFloatingTextFieldDemo.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 51;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | AB6E00F4B3E192E39026CF21 /* Pods_SSFloatingTextFieldDemo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1BF543A35AC70E2F1AAB1FB2 /* Pods_SSFloatingTextFieldDemo.framework */; };
11 | E370DC5D26958E550096A34C /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E370DC5C26958E550096A34C /* AppDelegate.swift */; };
12 | E370DC6126958E550096A34C /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E370DC6026958E550096A34C /* ViewController.swift */; };
13 | E370DC6626958E570096A34C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E370DC6526958E570096A34C /* Assets.xcassets */; };
14 | E3CD5D9C26AA801100AA387D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E3CD5D9B26AA801100AA387D /* LaunchScreen.storyboard */; };
15 | E3CD5D9E26AA808900AA387D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E3CD5D9D26AA808900AA387D /* Main.storyboard */; };
16 | /* End PBXBuildFile section */
17 |
18 | /* Begin PBXContainerItemProxy section */
19 | E370DC7026958E570096A34C /* PBXContainerItemProxy */ = {
20 | isa = PBXContainerItemProxy;
21 | containerPortal = E370DC5126958E550096A34C /* Project object */;
22 | proxyType = 1;
23 | remoteGlobalIDString = E370DC5826958E550096A34C;
24 | remoteInfo = SSFloatingTextFieldDemo;
25 | };
26 | E370DC7B26958E570096A34C /* PBXContainerItemProxy */ = {
27 | isa = PBXContainerItemProxy;
28 | containerPortal = E370DC5126958E550096A34C /* Project object */;
29 | proxyType = 1;
30 | remoteGlobalIDString = E370DC5826958E550096A34C;
31 | remoteInfo = SSFloatingTextFieldDemo;
32 | };
33 | /* End PBXContainerItemProxy section */
34 |
35 | /* Begin PBXFileReference section */
36 | 1BF543A35AC70E2F1AAB1FB2 /* Pods_SSFloatingTextFieldDemo.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SSFloatingTextFieldDemo.framework; sourceTree = BUILT_PRODUCTS_DIR; };
37 | 8CBAF9393FE2B5F1C50BB5FE /* Pods-SSFloatingTextFieldDemo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SSFloatingTextFieldDemo.debug.xcconfig"; path = "Target Support Files/Pods-SSFloatingTextFieldDemo/Pods-SSFloatingTextFieldDemo.debug.xcconfig"; sourceTree = ""; };
38 | E370DC5926958E550096A34C /* SSFloatingTextFieldDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SSFloatingTextFieldDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
39 | E370DC5C26958E550096A34C /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
40 | E370DC6026958E550096A34C /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
41 | E370DC6526958E570096A34C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
42 | E370DC6A26958E570096A34C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
43 | E370DC6F26958E570096A34C /* SSFloatingTextFieldDemoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SSFloatingTextFieldDemoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
44 | E370DC7A26958E570096A34C /* SSFloatingTextFieldDemoUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SSFloatingTextFieldDemoUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
45 | E3CD5D9B26AA801100AA387D /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; };
46 | E3CD5D9D26AA808900AA387D /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = ""; };
47 | F1B853C161B9FD0E8A891FC4 /* Pods-SSFloatingTextFieldDemo.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SSFloatingTextFieldDemo.release.xcconfig"; path = "Target Support Files/Pods-SSFloatingTextFieldDemo/Pods-SSFloatingTextFieldDemo.release.xcconfig"; sourceTree = ""; };
48 | /* End PBXFileReference section */
49 |
50 | /* Begin PBXFrameworksBuildPhase section */
51 | E370DC5626958E550096A34C /* Frameworks */ = {
52 | isa = PBXFrameworksBuildPhase;
53 | buildActionMask = 2147483647;
54 | files = (
55 | AB6E00F4B3E192E39026CF21 /* Pods_SSFloatingTextFieldDemo.framework in Frameworks */,
56 | );
57 | runOnlyForDeploymentPostprocessing = 0;
58 | };
59 | E370DC6C26958E570096A34C /* Frameworks */ = {
60 | isa = PBXFrameworksBuildPhase;
61 | buildActionMask = 2147483647;
62 | files = (
63 | );
64 | runOnlyForDeploymentPostprocessing = 0;
65 | };
66 | E370DC7726958E570096A34C /* Frameworks */ = {
67 | isa = PBXFrameworksBuildPhase;
68 | buildActionMask = 2147483647;
69 | files = (
70 | );
71 | runOnlyForDeploymentPostprocessing = 0;
72 | };
73 | /* End PBXFrameworksBuildPhase section */
74 |
75 | /* Begin PBXGroup section */
76 | D033A6C076F3158F3840AAA7 /* Frameworks */ = {
77 | isa = PBXGroup;
78 | children = (
79 | 1BF543A35AC70E2F1AAB1FB2 /* Pods_SSFloatingTextFieldDemo.framework */,
80 | );
81 | name = Frameworks;
82 | sourceTree = "";
83 | };
84 | E370DC5026958E550096A34C = {
85 | isa = PBXGroup;
86 | children = (
87 | E370DC5B26958E550096A34C /* SSFloatingTextFieldDemo */,
88 | E370DC5A26958E550096A34C /* Products */,
89 | FE3F0F7E902D41FE4DB75ED5 /* Pods */,
90 | D033A6C076F3158F3840AAA7 /* Frameworks */,
91 | );
92 | sourceTree = "";
93 | };
94 | E370DC5A26958E550096A34C /* Products */ = {
95 | isa = PBXGroup;
96 | children = (
97 | E370DC5926958E550096A34C /* SSFloatingTextFieldDemo.app */,
98 | E370DC6F26958E570096A34C /* SSFloatingTextFieldDemoTests.xctest */,
99 | E370DC7A26958E570096A34C /* SSFloatingTextFieldDemoUITests.xctest */,
100 | );
101 | name = Products;
102 | sourceTree = "";
103 | };
104 | E370DC5B26958E550096A34C /* SSFloatingTextFieldDemo */ = {
105 | isa = PBXGroup;
106 | children = (
107 | E370DC5C26958E550096A34C /* AppDelegate.swift */,
108 | E370DC6026958E550096A34C /* ViewController.swift */,
109 | E3CD5D9D26AA808900AA387D /* Main.storyboard */,
110 | E370DC6526958E570096A34C /* Assets.xcassets */,
111 | E370DC6A26958E570096A34C /* Info.plist */,
112 | E3CD5D9B26AA801100AA387D /* LaunchScreen.storyboard */,
113 | );
114 | path = SSFloatingTextFieldDemo;
115 | sourceTree = "";
116 | };
117 | FE3F0F7E902D41FE4DB75ED5 /* Pods */ = {
118 | isa = PBXGroup;
119 | children = (
120 | 8CBAF9393FE2B5F1C50BB5FE /* Pods-SSFloatingTextFieldDemo.debug.xcconfig */,
121 | F1B853C161B9FD0E8A891FC4 /* Pods-SSFloatingTextFieldDemo.release.xcconfig */,
122 | );
123 | path = Pods;
124 | sourceTree = "";
125 | };
126 | /* End PBXGroup section */
127 |
128 | /* Begin PBXNativeTarget section */
129 | E370DC5826958E550096A34C /* SSFloatingTextFieldDemo */ = {
130 | isa = PBXNativeTarget;
131 | buildConfigurationList = E370DC8326958E570096A34C /* Build configuration list for PBXNativeTarget "SSFloatingTextFieldDemo" */;
132 | buildPhases = (
133 | 96724D939463248AC96BA2DD /* [CP] Check Pods Manifest.lock */,
134 | E370DC5526958E550096A34C /* Sources */,
135 | E370DC5626958E550096A34C /* Frameworks */,
136 | E370DC5726958E550096A34C /* Resources */,
137 | 95493138E6514B71565C88E4 /* [CP] Embed Pods Frameworks */,
138 | );
139 | buildRules = (
140 | );
141 | dependencies = (
142 | );
143 | name = SSFloatingTextFieldDemo;
144 | productName = SSFloatingTextFieldDemo;
145 | productReference = E370DC5926958E550096A34C /* SSFloatingTextFieldDemo.app */;
146 | productType = "com.apple.product-type.application";
147 | };
148 | E370DC6E26958E570096A34C /* SSFloatingTextFieldDemoTests */ = {
149 | isa = PBXNativeTarget;
150 | buildConfigurationList = E370DC8626958E570096A34C /* Build configuration list for PBXNativeTarget "SSFloatingTextFieldDemoTests" */;
151 | buildPhases = (
152 | E370DC6B26958E570096A34C /* Sources */,
153 | E370DC6C26958E570096A34C /* Frameworks */,
154 | E370DC6D26958E570096A34C /* Resources */,
155 | );
156 | buildRules = (
157 | );
158 | dependencies = (
159 | E370DC7126958E570096A34C /* PBXTargetDependency */,
160 | );
161 | name = SSFloatingTextFieldDemoTests;
162 | productName = SSFloatingTextFieldDemoTests;
163 | productReference = E370DC6F26958E570096A34C /* SSFloatingTextFieldDemoTests.xctest */;
164 | productType = "com.apple.product-type.bundle.unit-test";
165 | };
166 | E370DC7926958E570096A34C /* SSFloatingTextFieldDemoUITests */ = {
167 | isa = PBXNativeTarget;
168 | buildConfigurationList = E370DC8926958E570096A34C /* Build configuration list for PBXNativeTarget "SSFloatingTextFieldDemoUITests" */;
169 | buildPhases = (
170 | E370DC7626958E570096A34C /* Sources */,
171 | E370DC7726958E570096A34C /* Frameworks */,
172 | E370DC7826958E570096A34C /* Resources */,
173 | );
174 | buildRules = (
175 | );
176 | dependencies = (
177 | E370DC7C26958E570096A34C /* PBXTargetDependency */,
178 | );
179 | name = SSFloatingTextFieldDemoUITests;
180 | productName = SSFloatingTextFieldDemoUITests;
181 | productReference = E370DC7A26958E570096A34C /* SSFloatingTextFieldDemoUITests.xctest */;
182 | productType = "com.apple.product-type.bundle.ui-testing";
183 | };
184 | /* End PBXNativeTarget section */
185 |
186 | /* Begin PBXProject section */
187 | E370DC5126958E550096A34C /* Project object */ = {
188 | isa = PBXProject;
189 | attributes = {
190 | LastSwiftUpdateCheck = 1200;
191 | LastUpgradeCheck = 1200;
192 | TargetAttributes = {
193 | E370DC5826958E550096A34C = {
194 | CreatedOnToolsVersion = 12.0.1;
195 | };
196 | E370DC6E26958E570096A34C = {
197 | CreatedOnToolsVersion = 12.0.1;
198 | TestTargetID = E370DC5826958E550096A34C;
199 | };
200 | E370DC7926958E570096A34C = {
201 | CreatedOnToolsVersion = 12.0.1;
202 | TestTargetID = E370DC5826958E550096A34C;
203 | };
204 | };
205 | };
206 | buildConfigurationList = E370DC5426958E550096A34C /* Build configuration list for PBXProject "SSFloatingTextFieldDemo" */;
207 | compatibilityVersion = "Xcode 9.3";
208 | developmentRegion = en;
209 | hasScannedForEncodings = 0;
210 | knownRegions = (
211 | en,
212 | Base,
213 | );
214 | mainGroup = E370DC5026958E550096A34C;
215 | productRefGroup = E370DC5A26958E550096A34C /* Products */;
216 | projectDirPath = "";
217 | projectRoot = "";
218 | targets = (
219 | E370DC5826958E550096A34C /* SSFloatingTextFieldDemo */,
220 | E370DC6E26958E570096A34C /* SSFloatingTextFieldDemoTests */,
221 | E370DC7926958E570096A34C /* SSFloatingTextFieldDemoUITests */,
222 | );
223 | };
224 | /* End PBXProject section */
225 |
226 | /* Begin PBXResourcesBuildPhase section */
227 | E370DC5726958E550096A34C /* Resources */ = {
228 | isa = PBXResourcesBuildPhase;
229 | buildActionMask = 2147483647;
230 | files = (
231 | E3CD5D9C26AA801100AA387D /* LaunchScreen.storyboard in Resources */,
232 | E370DC6626958E570096A34C /* Assets.xcassets in Resources */,
233 | E3CD5D9E26AA808900AA387D /* Main.storyboard in Resources */,
234 | );
235 | runOnlyForDeploymentPostprocessing = 0;
236 | };
237 | E370DC6D26958E570096A34C /* Resources */ = {
238 | isa = PBXResourcesBuildPhase;
239 | buildActionMask = 2147483647;
240 | files = (
241 | );
242 | runOnlyForDeploymentPostprocessing = 0;
243 | };
244 | E370DC7826958E570096A34C /* Resources */ = {
245 | isa = PBXResourcesBuildPhase;
246 | buildActionMask = 2147483647;
247 | files = (
248 | );
249 | runOnlyForDeploymentPostprocessing = 0;
250 | };
251 | /* End PBXResourcesBuildPhase section */
252 |
253 | /* Begin PBXShellScriptBuildPhase section */
254 | 95493138E6514B71565C88E4 /* [CP] Embed Pods Frameworks */ = {
255 | isa = PBXShellScriptBuildPhase;
256 | buildActionMask = 2147483647;
257 | files = (
258 | );
259 | inputFileListPaths = (
260 | "${PODS_ROOT}/Target Support Files/Pods-SSFloatingTextFieldDemo/Pods-SSFloatingTextFieldDemo-frameworks-${CONFIGURATION}-input-files.xcfilelist",
261 | );
262 | name = "[CP] Embed Pods Frameworks";
263 | outputFileListPaths = (
264 | "${PODS_ROOT}/Target Support Files/Pods-SSFloatingTextFieldDemo/Pods-SSFloatingTextFieldDemo-frameworks-${CONFIGURATION}-output-files.xcfilelist",
265 | );
266 | runOnlyForDeploymentPostprocessing = 0;
267 | shellPath = /bin/sh;
268 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-SSFloatingTextFieldDemo/Pods-SSFloatingTextFieldDemo-frameworks.sh\"\n";
269 | showEnvVarsInLog = 0;
270 | };
271 | 96724D939463248AC96BA2DD /* [CP] Check Pods Manifest.lock */ = {
272 | isa = PBXShellScriptBuildPhase;
273 | buildActionMask = 2147483647;
274 | files = (
275 | );
276 | inputFileListPaths = (
277 | );
278 | inputPaths = (
279 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
280 | "${PODS_ROOT}/Manifest.lock",
281 | );
282 | name = "[CP] Check Pods Manifest.lock";
283 | outputFileListPaths = (
284 | );
285 | outputPaths = (
286 | "$(DERIVED_FILE_DIR)/Pods-SSFloatingTextFieldDemo-checkManifestLockResult.txt",
287 | );
288 | runOnlyForDeploymentPostprocessing = 0;
289 | shellPath = /bin/sh;
290 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
291 | showEnvVarsInLog = 0;
292 | };
293 | /* End PBXShellScriptBuildPhase section */
294 |
295 | /* Begin PBXSourcesBuildPhase section */
296 | E370DC5526958E550096A34C /* Sources */ = {
297 | isa = PBXSourcesBuildPhase;
298 | buildActionMask = 2147483647;
299 | files = (
300 | E370DC6126958E550096A34C /* ViewController.swift in Sources */,
301 | E370DC5D26958E550096A34C /* AppDelegate.swift in Sources */,
302 | );
303 | runOnlyForDeploymentPostprocessing = 0;
304 | };
305 | E370DC6B26958E570096A34C /* Sources */ = {
306 | isa = PBXSourcesBuildPhase;
307 | buildActionMask = 2147483647;
308 | files = (
309 | );
310 | runOnlyForDeploymentPostprocessing = 0;
311 | };
312 | E370DC7626958E570096A34C /* Sources */ = {
313 | isa = PBXSourcesBuildPhase;
314 | buildActionMask = 2147483647;
315 | files = (
316 | );
317 | runOnlyForDeploymentPostprocessing = 0;
318 | };
319 | /* End PBXSourcesBuildPhase section */
320 |
321 | /* Begin PBXTargetDependency section */
322 | E370DC7126958E570096A34C /* PBXTargetDependency */ = {
323 | isa = PBXTargetDependency;
324 | target = E370DC5826958E550096A34C /* SSFloatingTextFieldDemo */;
325 | targetProxy = E370DC7026958E570096A34C /* PBXContainerItemProxy */;
326 | };
327 | E370DC7C26958E570096A34C /* PBXTargetDependency */ = {
328 | isa = PBXTargetDependency;
329 | target = E370DC5826958E550096A34C /* SSFloatingTextFieldDemo */;
330 | targetProxy = E370DC7B26958E570096A34C /* PBXContainerItemProxy */;
331 | };
332 | /* End PBXTargetDependency section */
333 |
334 | /* Begin XCBuildConfiguration section */
335 | E370DC8126958E570096A34C /* Debug */ = {
336 | isa = XCBuildConfiguration;
337 | buildSettings = {
338 | ALWAYS_SEARCH_USER_PATHS = NO;
339 | CLANG_ANALYZER_NONNULL = YES;
340 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
341 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
342 | CLANG_CXX_LIBRARY = "libc++";
343 | CLANG_ENABLE_MODULES = YES;
344 | CLANG_ENABLE_OBJC_ARC = YES;
345 | CLANG_ENABLE_OBJC_WEAK = YES;
346 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
347 | CLANG_WARN_BOOL_CONVERSION = YES;
348 | CLANG_WARN_COMMA = YES;
349 | CLANG_WARN_CONSTANT_CONVERSION = YES;
350 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
351 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
352 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
353 | CLANG_WARN_EMPTY_BODY = YES;
354 | CLANG_WARN_ENUM_CONVERSION = YES;
355 | CLANG_WARN_INFINITE_RECURSION = YES;
356 | CLANG_WARN_INT_CONVERSION = YES;
357 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
358 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
359 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
360 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
361 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
362 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
363 | CLANG_WARN_STRICT_PROTOTYPES = YES;
364 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
365 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
366 | CLANG_WARN_UNREACHABLE_CODE = YES;
367 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
368 | COPY_PHASE_STRIP = NO;
369 | DEBUG_INFORMATION_FORMAT = dwarf;
370 | ENABLE_STRICT_OBJC_MSGSEND = YES;
371 | ENABLE_TESTABILITY = YES;
372 | GCC_C_LANGUAGE_STANDARD = gnu11;
373 | GCC_DYNAMIC_NO_PIC = NO;
374 | GCC_NO_COMMON_BLOCKS = YES;
375 | GCC_OPTIMIZATION_LEVEL = 0;
376 | GCC_PREPROCESSOR_DEFINITIONS = (
377 | "DEBUG=1",
378 | "$(inherited)",
379 | );
380 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
381 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
382 | GCC_WARN_UNDECLARED_SELECTOR = YES;
383 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
384 | GCC_WARN_UNUSED_FUNCTION = YES;
385 | GCC_WARN_UNUSED_VARIABLE = YES;
386 | IPHONEOS_DEPLOYMENT_TARGET = 14.0;
387 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
388 | MTL_FAST_MATH = YES;
389 | ONLY_ACTIVE_ARCH = YES;
390 | SDKROOT = iphoneos;
391 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
392 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
393 | };
394 | name = Debug;
395 | };
396 | E370DC8226958E570096A34C /* Release */ = {
397 | isa = XCBuildConfiguration;
398 | buildSettings = {
399 | ALWAYS_SEARCH_USER_PATHS = NO;
400 | CLANG_ANALYZER_NONNULL = YES;
401 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
402 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
403 | CLANG_CXX_LIBRARY = "libc++";
404 | CLANG_ENABLE_MODULES = YES;
405 | CLANG_ENABLE_OBJC_ARC = YES;
406 | CLANG_ENABLE_OBJC_WEAK = YES;
407 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
408 | CLANG_WARN_BOOL_CONVERSION = YES;
409 | CLANG_WARN_COMMA = YES;
410 | CLANG_WARN_CONSTANT_CONVERSION = YES;
411 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
412 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
413 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
414 | CLANG_WARN_EMPTY_BODY = YES;
415 | CLANG_WARN_ENUM_CONVERSION = YES;
416 | CLANG_WARN_INFINITE_RECURSION = YES;
417 | CLANG_WARN_INT_CONVERSION = YES;
418 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
419 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
420 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
421 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
422 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
423 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
424 | CLANG_WARN_STRICT_PROTOTYPES = YES;
425 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
426 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
427 | CLANG_WARN_UNREACHABLE_CODE = YES;
428 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
429 | COPY_PHASE_STRIP = NO;
430 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
431 | ENABLE_NS_ASSERTIONS = NO;
432 | ENABLE_STRICT_OBJC_MSGSEND = YES;
433 | GCC_C_LANGUAGE_STANDARD = gnu11;
434 | GCC_NO_COMMON_BLOCKS = YES;
435 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
436 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
437 | GCC_WARN_UNDECLARED_SELECTOR = YES;
438 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
439 | GCC_WARN_UNUSED_FUNCTION = YES;
440 | GCC_WARN_UNUSED_VARIABLE = YES;
441 | IPHONEOS_DEPLOYMENT_TARGET = 14.0;
442 | MTL_ENABLE_DEBUG_INFO = NO;
443 | MTL_FAST_MATH = YES;
444 | SDKROOT = iphoneos;
445 | SWIFT_COMPILATION_MODE = wholemodule;
446 | SWIFT_OPTIMIZATION_LEVEL = "-O";
447 | VALIDATE_PRODUCT = YES;
448 | };
449 | name = Release;
450 | };
451 | E370DC8426958E570096A34C /* Debug */ = {
452 | isa = XCBuildConfiguration;
453 | baseConfigurationReference = 8CBAF9393FE2B5F1C50BB5FE /* Pods-SSFloatingTextFieldDemo.debug.xcconfig */;
454 | buildSettings = {
455 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
456 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
457 | CODE_SIGN_STYLE = Automatic;
458 | INFOPLIST_FILE = SSFloatingTextFieldDemo/Info.plist;
459 | LD_RUNPATH_SEARCH_PATHS = (
460 | "$(inherited)",
461 | "@executable_path/Frameworks",
462 | );
463 | PRODUCT_BUNDLE_IDENTIFIER = com.simform.SSFloatingTextFieldDemo;
464 | PRODUCT_NAME = "$(TARGET_NAME)";
465 | SWIFT_VERSION = 5.0;
466 | TARGETED_DEVICE_FAMILY = "1,2";
467 | };
468 | name = Debug;
469 | };
470 | E370DC8526958E570096A34C /* Release */ = {
471 | isa = XCBuildConfiguration;
472 | baseConfigurationReference = F1B853C161B9FD0E8A891FC4 /* Pods-SSFloatingTextFieldDemo.release.xcconfig */;
473 | buildSettings = {
474 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
475 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
476 | CODE_SIGN_STYLE = Automatic;
477 | INFOPLIST_FILE = SSFloatingTextFieldDemo/Info.plist;
478 | LD_RUNPATH_SEARCH_PATHS = (
479 | "$(inherited)",
480 | "@executable_path/Frameworks",
481 | );
482 | PRODUCT_BUNDLE_IDENTIFIER = com.simform.SSFloatingTextFieldDemo;
483 | PRODUCT_NAME = "$(TARGET_NAME)";
484 | SWIFT_VERSION = 5.0;
485 | TARGETED_DEVICE_FAMILY = "1,2";
486 | };
487 | name = Release;
488 | };
489 | E370DC8726958E570096A34C /* Debug */ = {
490 | isa = XCBuildConfiguration;
491 | buildSettings = {
492 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
493 | BUNDLE_LOADER = "$(TEST_HOST)";
494 | CODE_SIGN_STYLE = Automatic;
495 | INFOPLIST_FILE = SSFloatingTextFieldDemoTests/Info.plist;
496 | IPHONEOS_DEPLOYMENT_TARGET = 14.0;
497 | LD_RUNPATH_SEARCH_PATHS = (
498 | "$(inherited)",
499 | "@executable_path/Frameworks",
500 | "@loader_path/Frameworks",
501 | );
502 | PRODUCT_BUNDLE_IDENTIFIER = com.simform.SSFloatingTextFieldDemoTests;
503 | PRODUCT_NAME = "$(TARGET_NAME)";
504 | SWIFT_VERSION = 5.0;
505 | TARGETED_DEVICE_FAMILY = "1,2";
506 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SSFloatingTextFieldDemo.app/SSFloatingTextFieldDemo";
507 | };
508 | name = Debug;
509 | };
510 | E370DC8826958E570096A34C /* Release */ = {
511 | isa = XCBuildConfiguration;
512 | buildSettings = {
513 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
514 | BUNDLE_LOADER = "$(TEST_HOST)";
515 | CODE_SIGN_STYLE = Automatic;
516 | INFOPLIST_FILE = SSFloatingTextFieldDemoTests/Info.plist;
517 | IPHONEOS_DEPLOYMENT_TARGET = 14.0;
518 | LD_RUNPATH_SEARCH_PATHS = (
519 | "$(inherited)",
520 | "@executable_path/Frameworks",
521 | "@loader_path/Frameworks",
522 | );
523 | PRODUCT_BUNDLE_IDENTIFIER = com.simform.SSFloatingTextFieldDemoTests;
524 | PRODUCT_NAME = "$(TARGET_NAME)";
525 | SWIFT_VERSION = 5.0;
526 | TARGETED_DEVICE_FAMILY = "1,2";
527 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SSFloatingTextFieldDemo.app/SSFloatingTextFieldDemo";
528 | };
529 | name = Release;
530 | };
531 | E370DC8A26958E570096A34C /* Debug */ = {
532 | isa = XCBuildConfiguration;
533 | buildSettings = {
534 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
535 | CODE_SIGN_STYLE = Automatic;
536 | INFOPLIST_FILE = SSFloatingTextFieldDemoUITests/Info.plist;
537 | LD_RUNPATH_SEARCH_PATHS = (
538 | "$(inherited)",
539 | "@executable_path/Frameworks",
540 | "@loader_path/Frameworks",
541 | );
542 | PRODUCT_BUNDLE_IDENTIFIER = com.simform.SSFloatingTextFieldDemoUITests;
543 | PRODUCT_NAME = "$(TARGET_NAME)";
544 | SWIFT_VERSION = 5.0;
545 | TARGETED_DEVICE_FAMILY = "1,2";
546 | TEST_TARGET_NAME = SSFloatingTextFieldDemo;
547 | };
548 | name = Debug;
549 | };
550 | E370DC8B26958E570096A34C /* Release */ = {
551 | isa = XCBuildConfiguration;
552 | buildSettings = {
553 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
554 | CODE_SIGN_STYLE = Automatic;
555 | INFOPLIST_FILE = SSFloatingTextFieldDemoUITests/Info.plist;
556 | LD_RUNPATH_SEARCH_PATHS = (
557 | "$(inherited)",
558 | "@executable_path/Frameworks",
559 | "@loader_path/Frameworks",
560 | );
561 | PRODUCT_BUNDLE_IDENTIFIER = com.simform.SSFloatingTextFieldDemoUITests;
562 | PRODUCT_NAME = "$(TARGET_NAME)";
563 | SWIFT_VERSION = 5.0;
564 | TARGETED_DEVICE_FAMILY = "1,2";
565 | TEST_TARGET_NAME = SSFloatingTextFieldDemo;
566 | };
567 | name = Release;
568 | };
569 | /* End XCBuildConfiguration section */
570 |
571 | /* Begin XCConfigurationList section */
572 | E370DC5426958E550096A34C /* Build configuration list for PBXProject "SSFloatingTextFieldDemo" */ = {
573 | isa = XCConfigurationList;
574 | buildConfigurations = (
575 | E370DC8126958E570096A34C /* Debug */,
576 | E370DC8226958E570096A34C /* Release */,
577 | );
578 | defaultConfigurationIsVisible = 0;
579 | defaultConfigurationName = Release;
580 | };
581 | E370DC8326958E570096A34C /* Build configuration list for PBXNativeTarget "SSFloatingTextFieldDemo" */ = {
582 | isa = XCConfigurationList;
583 | buildConfigurations = (
584 | E370DC8426958E570096A34C /* Debug */,
585 | E370DC8526958E570096A34C /* Release */,
586 | );
587 | defaultConfigurationIsVisible = 0;
588 | defaultConfigurationName = Release;
589 | };
590 | E370DC8626958E570096A34C /* Build configuration list for PBXNativeTarget "SSFloatingTextFieldDemoTests" */ = {
591 | isa = XCConfigurationList;
592 | buildConfigurations = (
593 | E370DC8726958E570096A34C /* Debug */,
594 | E370DC8826958E570096A34C /* Release */,
595 | );
596 | defaultConfigurationIsVisible = 0;
597 | defaultConfigurationName = Release;
598 | };
599 | E370DC8926958E570096A34C /* Build configuration list for PBXNativeTarget "SSFloatingTextFieldDemoUITests" */ = {
600 | isa = XCConfigurationList;
601 | buildConfigurations = (
602 | E370DC8A26958E570096A34C /* Debug */,
603 | E370DC8B26958E570096A34C /* Release */,
604 | );
605 | defaultConfigurationIsVisible = 0;
606 | defaultConfigurationName = Release;
607 | };
608 | /* End XCConfigurationList section */
609 | };
610 | rootObject = E370DC5126958E550096A34C /* Project object */;
611 | }
612 |
--------------------------------------------------------------------------------
/SSFloatingTextFieldDemo/SSFloatingTextFieldDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/SSFloatingTextFieldDemo/SSFloatingTextFieldDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/SSFloatingTextFieldDemo/SSFloatingTextFieldDemo.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/SSFloatingTextFieldDemo/SSFloatingTextFieldDemo.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/SSFloatingTextFieldDemo/SSFloatingTextFieldDemo/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // SSFloatingTextFieldDemo
4 | //
5 | // Created by Mohammed Hanif on 07/07/21.
6 | //
7 |
8 | import UIKit
9 |
10 | @main
11 | class AppDelegate: UIResponder, UIApplicationDelegate {
12 |
13 | var window: UIWindow?
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 | }
21 |
--------------------------------------------------------------------------------
/SSFloatingTextFieldDemo/SSFloatingTextFieldDemo/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 |
--------------------------------------------------------------------------------
/SSFloatingTextFieldDemo/SSFloatingTextFieldDemo/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 |
--------------------------------------------------------------------------------
/SSFloatingTextFieldDemo/SSFloatingTextFieldDemo/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/SSFloatingTextFieldDemo/SSFloatingTextFieldDemo/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 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | UILaunchStoryboardName
22 | LaunchScreen
23 | UIMainStoryboardFile
24 | Main
25 |
26 |
27 |
--------------------------------------------------------------------------------
/SSFloatingTextFieldDemo/SSFloatingTextFieldDemo/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 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/SSFloatingTextFieldDemo/SSFloatingTextFieldDemo/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 |
35 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | Password must be 8 characters long and contain atleast 1 lowercase character 1 uppercase character 1 dight and 1 special character
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
--------------------------------------------------------------------------------
/SSFloatingTextFieldDemo/SSFloatingTextFieldDemo/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // SSFloatingTextFieldDemo
4 | //
5 | // Created by Mohammed Hanif on 07/07/21.
6 | //
7 |
8 | import UIKit
9 | import SSFloatingLabelTextField
10 |
11 | class ViewController: UIViewController {
12 |
13 | @IBOutlet weak var txtUsername: SSFloatingLabelTextField!
14 | @IBOutlet weak var txtEmail: SSFloatingLabelTextField!
15 | @IBOutlet weak var txtPassword: SSFloatingLabelTextField!
16 | @IBOutlet weak var txtPhoneNumber: SSFloatingLabelTextField!
17 |
18 | override func viewDidLoad() {
19 | super.viewDidLoad()
20 | txtEmail.type = .email
21 | txtPassword.type = .password(passwordRule: .medium)
22 | txtPhoneNumber.type = .phoneNumber(formatterString: nil)
23 | hideKeyboardWhenTappedAround()
24 | }
25 |
26 | func hideKeyboardWhenTappedAround() {
27 | let tap = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))
28 | tap.cancelsTouchesInView = false
29 | view.addGestureRecognizer(tap)
30 | }
31 |
32 | @objc func dismissKeyboard() {
33 | view.endEditing(true)
34 | }
35 |
36 | @IBAction func btnValidate(_ sender: UIButton) {
37 | print(txtUsername.isValid())
38 | print(txtEmail.isValid())
39 | print(txtPassword.isValid())
40 | print(txtPhoneNumber.isValid())
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/screenshots/Installation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimformSolutionsPvtLtd/SSFloatingLabelTextField/3b425b141df546d19bf726525e10caa04c699172/screenshots/Installation.png
--------------------------------------------------------------------------------
/screenshots/SSFloatingTextField.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimformSolutionsPvtLtd/SSFloatingLabelTextField/3b425b141df546d19bf726525e10caa04c699172/screenshots/SSFloatingTextField.gif
--------------------------------------------------------------------------------
/screenshots/simformBanner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SimformSolutionsPvtLtd/SSFloatingLabelTextField/3b425b141df546d19bf726525e10caa04c699172/screenshots/simformBanner.png
--------------------------------------------------------------------------------