Code Monkey home page Code Monkey logo

floatinglabeltextfieldswiftui's Introduction

FloatingLabelTextFieldSwiftUI

CI Status Version License Platform

FloatingLabelTextFieldSwiftUI is a small and lightweight SwiftUI framework written in completely swiftUI (not using UIViewRepresentable) that allows to create beautiful and customisable floating label textfield! This library support RTL text (eg. Arabic) and easy to add left view and right view to your text field and customizable.

If you like the project, please do not forget to star β˜… this repository and follow me on GitHub.

πŸ“¦ Requirements

  • iOS 13.0+
  • Xcode 11.2+
  • Swift 5.0

πŸ’» Usage

To start using the component add it to your project using CocoaPods or Swift Package. First of all import FloatingLabelTextFieldSwiftUI

import FloatingLabelTextFieldSwiftUI

struct ContentView: View {
    
    @State private var firstName: String = ""
    
    var body: some View {
        
        FloatingLabelTextField($firstName, placeholder: "First Name", editingChanged: { (isChanged) in
            
        }) {
            
        }.frame(height: 70)
    }
}

FloatingLabelTextFieldStyle and Colors:

You can customize the colors of the textfield by using FloatingLabelTextFieldStyle property or create your own style and set a few properties.

Property

struct ContentView: View {
    
    @State private var firstName: String = ""
    
    var body: some View {
        
        FloatingLabelTextField($firstName, placeholder: "First Name", editingChanged: { (isChanged) in
            
        }) {
            
        }
        .titleColor(.green)
        .selectedLineColor(.blue)
        .selectedTextColor(.blue)
        .selectedTitleColor(.blue)
        .frame(height: 70)
    }
}

FloatingLabelTextFieldStyle

Just two step for create and add style to FloatingLabelTextField.

  1. Create your own theme style. Set property as per your theme.
struct ThemeTextFieldStyle: FloatingLabelTextFieldStyle {
    func body(content: FloatingLabelTextField) -> FloatingLabelTextField {
        content
            .spaceBetweenTitleText(15) // Sets the space between title and text.
            .textAlignment(.leading) // Sets the alignment for text.
            .lineHeight(1) // Sets the line height.
            .selectedLineHeight(1.5) // Sets the selected line height.
            .lineColor(.gray) // Sets the line color.
            .selectedLineColor(.blue) // Sets the selected line color.
            .titleColor(.gray) // Sets the title color.
            .selectedTitleColor(.blue) // Sets the selected title color.
            .titleFont(.system(size: 12)) // Sets the title font.
            .textColor(.black) // Sets the text color.
            .selectedTextColor(.blue) // Sets the selected text color.
            .textFont(.system(size: 15)) // Sets the text font.
            .placeholderColor(.gray) // Sets the placeholder color.
            .placeholderFont(.system(size: 15)) // Sets the placeholder font.
            .errorColor(.red) // Sets the error color.
            .addDisableEditingAction([.paste]) // Disable text field editing action. Like cut, copy, past, all etc.
            .enablePlaceholderOnFocus(true) // Enable the placeholder label when the textfield is focused.
            .allowsHitTesting(true) // Whether this view participates in hit test operations.
            .disabled(false) // Whether users can interact with this.
    }
}
  1. Add style to FloatingLabelTextField.
struct ContentView: View {
    
    @State private var firstName: String = ""
    
    var body: some View {
        FloatingLabelTextField($firstName, placeholder: "First Name", editingChanged: { (isChanged) in
            
        }) {
            
        }
        .floatingStyle(ThemeTextFieldStyle())
        .frame(height: 70)
    }
}

Secure Text Entry

To enable Secure Text Entry use .isSecureTextEntry(true) property.

struct ContentView: View {
    
    @State private var password: String = ""
    
    var body: some View {
        HStack(spacing: 20) {
            FloatingLabelTextField($password, placeholder: "Password", editingChanged: { (isChanged) in
                
            }) {
                
            }
            .isSecureTextEntry(true)
            .frame(height: 70)
        }
    }
}

Left - Right View

Yes, you can easily add your own views, buttons or image to left view or right view of the FloatingLabelTextField.

struct ContentView: View {
    
    @State private var password: String = ""
    @State private var isPasswordShow: Bool = false
    
    var body: some View {
        FloatingLabelTextField($password, placeholder: "Password", editingChanged: { (isChanged) in
            
        }) {
            
        }
        .isSecureTextEntry(!self.isPasswordShow)
            .leftView({ // Add left view.
                Image("password")
            })
            .rightView({ // Add right view.
                Button(action: {
                    withAnimation {
                        self.isPasswordShow.toggle()
                    }
                    
                }) {
                    Image(self.isPasswordShow ? "eye_close" : "eye_show")
                }
            })
            .frame(height: 70)
            .padding()
    }
}

Error Message & Validation

FloatingLableTextFieldSwiftUI supports displaying an error and add text field validations. This can be helpfull for adding validation on your form text field. To enable isShowError property to true and pass text field validations array to text field with message according condition. You can also add validation checker variable to check is text field is valid or not on submit button action.

FloatingLabelTextFieldSwiftUI also have some inbuilt validation regex checker fields like email, password, name, number.. etc.

Here is some example

  1. Email Validation

struct ContentView: View {
    
    @State private var email: String = ""
    @State private var isValidEmail: Bool = false
    
    var body: some View {
        VStack {
            FloatingLabelTextField($email, validtionChecker: $isValidEmail, placeholder: "Email", editingChanged: { (isChanged) in
                
            }) {
                
            }
            .addValidation(.init(condition: email.isValid(.email), errorMessage: "Invalid Email")) /// Sets the validation condition.
                .isShowError(true) /// Sets the is show error message.
                .errorColor(.red) /// Sets the error color.
                .keyboardType(.emailAddress)
                .frame(height: 70)
                .padding()
            
            Button(action: {
                self.endEditing(true)
                
                if self.isValidEmail {
                    print("Valid Email")
                    
                } else {
                    print("Invalid Email")
                }
                
            }) {
                Text("Create")
            }
        }
    }
}
  1. Name Validation

struct ContentView: View {
    
    @State private var lastName: String = ""
    
    var body: some View {
        FloatingLabelTextField($lastName, placeholder: "Last Name", editingChanged: { (isChanged) in
            
        }) {
            
        }
        .isShowError(true) /// Sets the is show error message.
        .addValidations([.init(condition: lastName.isValid(.alphabet), errorMessage: "Invalid Name"),
                         .init(condition: lastName.count >= 2, errorMessage: "Minimum two character long")
        ]) /// Sets the validation conditions.
            .floatingStyle(ThemeTextFieldStyle2())
            .frame(height: 70)
    }
}

🐾 Examples

To run the example project, clone the repo, and run pod install from the Example directory first.

πŸ’Ύ Installation

CocoaPods:

FloatingLabelTextFieldSwiftUI is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod 'FloatingLabelTextFieldSwiftUI'

Swift Package Manager

The Swift Package Manager is a tool for managing the distribution of Swift code. It’s integrated with the Swift build system to automate the process of downloading, compiling, and linking dependencies.

To integrate FloatingLabelTextFieldSwiftUI into your Xcode project using Xcode 11+, specify it in File > Swift Packages > Add:

https://github.com/kishanraja/FloatingLabelTextFieldSwiftUI.git

Manual

You can download the latest files from our Releases page. After doing so, copy the files in the Sources folder to your project.

πŸ™‹πŸ»β€β™‚οΈ Author

kishanraja, [email protected]

πŸ’° Contribution

Feel free to fork the project and send me a pull-request!

πŸ“ Feedback

Please file an Issue.

πŸ“œ License

FloatingLabelTextFieldSwiftUI is available under the MIT license. See the LICENSE file for more info.

floatinglabeltextfieldswiftui's People

Contributors

afern247 avatar hyperlinkkishanr avatar kishanraja avatar michallaskowski avatar mohsalahnassar avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

floatinglabeltextfieldswiftui's Issues

validtionChecker becomes TRUE only after closing the keyboard

I defined a FloatingLabelTextField (with var isValidMasterPwd2 as validtionChecker) whose content must be the same as the string inserted in another TextField. If I insert a string identical to the other in this TextField, the variable isValidMasterPwd2 becomes TRUE only after closing the keyboard.
Is there a way for the variable to immediately become TRUE as soon as the validity conditions are satisfied?

FloatingLabelTextField($masterPwd2, validtionChecker: $isValidMasterPwd2, 
placeholder: "Re-type Password", editingChanged: { (isChanged) in
                }) {
                }
                .isShowError(true)
                .addValidations([.init(condition: masterPwd1 == masterPwd2, errorMessage: "Password not equal")])
                .isRequiredField(true, with: "Password field is required")
                .isSecureTextEntry(!self.isMasterPwd2Show)
                .modifier(ThemeTextField())

Validation issue

I was using multiple FloatingLabelTextField on clicked submit button ValidationChecker until validate first text field second text field flag state not change even second text valid.

     FloatingLabelTextField($registrationDetails.firstName,validtionChecker: $isValidFirstname, placeholder: "Voornaam *")
          .addValidations([.init(condition: registrationDetails.firstName.isValid(.name), errorMessage: "Enter Valid Firstname")
          ])
          .isShowError(true)
          .isRequiredField(true, with: "Enter Firstname")
      .floatingStyle(ThemeTextFieldStyle())
      .padding(8)
      .frame(height: 60)
      .background(RoundedRectangle(cornerRadius: 4)
            .fill(Color("textfieldBackgroundColor"))
                    .shadow(color: Color("shadowColor"), radius: 5, x: 0, y: 0))
      .padding()

      FloatingLabelTextField($registrationDetails.middleName, placeholder: "Tussenvoegsel ")
          .addValidations([.init(condition: registrationDetails.middleName.isValid(.name), errorMessage: "Enter Valid Middlename")
          ])
          .isShowError(true)
      .floatingStyle(ThemeTextFieldStyle())
      .padding(8)
      .frame(width: 300, height: 60, alignment: .leading)
      .background(RoundedRectangle(cornerRadius: 4)
            .fill(Color("textfieldBackgroundColor"))
                    .shadow(color: Color("shadowColor"), radius: 5, x: 0, y: 0))
      .padding()

      FloatingLabelTextField($registrationDetails.lastName,validtionChecker: $isValidLastname, placeholder: "Achternaam *")
          .addValidations([.init(condition: registrationDetails.lastName.isValid(.name), errorMessage: "Enter Valid Lastname")
          ])
          .isShowError(true)
          .isRequiredField(true, with: "Enter Lastname")
      .floatingStyle(ThemeTextFieldStyle())
      .padding(8)
      .frame(height: 60)
      .background(RoundedRectangle(cornerRadius: 4)
            .fill(Color("textfieldBackgroundColor"))
                    .shadow(color: Color("shadowColor"), radius: 5, x: 0, y: 0))
      .padding()

Can you please help.

Non compliant display of .secureTextEntry

When applying .secureTextEntry as proposed in the example:

  • When setting displayPassword to false => the password doesn't even appear instead of dots
  • The rightView alone has no effect and doesn't display the expected icon

Xcode 14.2, iOS 16.0

UI Test Case for FloatingLabelTextField

How can i give accessibilityIdentifier to text field, because if i add accessibilityIdentifier to FloatingLabelTextField it did not work with UI Test Case

Example:

FloatingLabelTextField($firstName, placeholder: "First Name", editingChanged: { (isChanged) in 
})
accessibilityIdentifier("firstname_textfield")

Than i code in Test Case

let firstnameTextField = app.textFields["firstname_textfield"]
        firstnameTextField.tap()
        firstnameTextField.typeText("test user")

in text field it is not typing "test user"
can you please let me know how to make working in UI Test Case?

Clicking but not setting focus (Make the label clickable).

Hi,

One problem our users have complained about is that when they click a field to set focus it does not work. We think what's happening is that they are clicking the label area instead of the text field. It would be good if that when a user clicks the label it sets focus to the text field. It would also be good if the label expanded to 100% width of the area so that you can click anywhere in the field to get it to accept focus.

Thanks,
-Mark

Issues with validation

Consider the following source code:

I have discovered a few issue with validation.

  • When a field is required I cannot figure out how to display the error. I am using the below code however the error message just flashes briefly.
   FloatingLabelTextField($username, validtionChecker: $isValidUsername, placeholder: "Username")
      .addValidation(.init(condition: !username.isEmpty, errorMessage: "Username is required"))
      .isShowError(true)
      .errorColor(.red)
      .frame(height: 50)
  • Validation does not appear to work on SecureTextEntry fields. In the below example isValidPassword is always false
FloatingLabelTextField($password, validtionChecker: $isValidPassword, placeholder: "Password")
   .addValidation(.init(condition: !password.isEmpty, errorMessage: "Password is required"))
   .isShowError(true)
   .errorColor(.red)
   .isSecureTextEntry(!self.isPasswordShow)
   .frame(height: 50)

Any assistance would be appreciated

Disable editing but enable right/left view buttons

Feature request: Disable editing of the text field, while still enabling buttons added to a left/right view. For example (based on the sample code provided), I can do this:

var body: some View {
        FloatingLabelTextField($password, placeholder: "Password", editingChanged: { (isChanged) in
            
        }) {
            
        }
        .isSecureTextEntry(!self.isPasswordShow)
            .leftView({ // Add left view.
                Image("password")
            })
            .rightView({ // Add right view.
                Button(action: {
                    withAnimation {
                        self.isPasswordShow.toggle()
                    }
                    
                }) {
                    Image(self.isPasswordShow ? "eye_close" : "eye_show")
                }
            })
            .frame(height: 70)
            .padding()
    }

However, if I want the text field itself to be read-only and i set disabled(true), that also disables the Button in rightView. I'd like to be able to still toggle the visibility of the field while disabling the ability to edit.

Add text limit

Is it possible to add a limit to the amount of text entered?

Geometry Behavior

Thanks for the great package. Unfortunately due to your use of .frame(... maxHeight: .infinity ...), the view tries to grab the maximum of space, which means e.g., in a VBox, it overrides your any Spacers, etc. and aligns itself always to the bottom.

I think it would be more versatile without these settings.

Localization for placeholder

How should i localize the placeholder to multiple language if the placeholder field isn't from LocalizedStringKey class ?

Updating error message to below

Is there any possibility to show the error message to display below the textfield instead of replacing the placeholder text

Unable to set Input View

how can I set input view with FloatingLabelTextField ? I wanted to display picker instead of keyboard ? but currently can't find a way to set input view.
let me know if there is a way.

How to set border?

Hi Raja,

Your library is exactly match my requirements. But only problem is I don't know how to set border for this? Can you suggest pls.

Binding<Int>

In the example, how would you make it work if the mobile number where an Integer instead of a String?

Validation always returning false

Validation checker $isValidEmail and $isValidPassword always getting false. Am I missing something?

                   FloatingLabelTextField($txtEmail,
                                           validtionChecker: $isValidEmail,
                                           placeholder: TextFieldPlaceholder.email) { isChanged in
                        print("email text field ---- \(isChanged)")
                    }
                    .addValidation(.init(condition: txtEmail.isValid(.email),
                                         errorMessage: ErrorMessage.invalidEmail))
                    .isShowError(true)
                    .errorColor(.red)
                    .keyboardType(.emailAddress)
                    .textInputAutocapitalization(.never)
                    .frame(height: 70)
                    .padding(EdgeInsets(.init(top: 0, leading: 30, bottom: 0, trailing: 30)))
                    
                    //------------Password
                    FloatingLabelTextField($txtPassword,
                                           validtionChecker: $isValidPassword,
                                           placeholder: TextFieldPlaceholder.newPassword) { isChanged in
                        print("password text field ---- \(isChanged)")
                    }
                    .addValidations([.init(condition: txtPassword.isValid(.password),
                                           errorMessage: ErrorMessage.invalidPassword),
                                     .init(condition: txtPassword.count >= 5,
                                           errorMessage: ErrorMessage.minimumPasswordLength)
                    ])
                    .isSecureTextEntry(!self.isPasswordShow)
                    .rightView({
                        Button(action: {
                            self.isPasswordShow.toggle()
                        }, label: {
                            Image(systemName: self.isPasswordShow ? "eye.slash.fill" : "eye.fill")
                        })
                    })
                    .isShowError(true)
                    .errorColor(.red)
                    .keyboardType(.default)
                    .frame(height: 70)
                    .padding(EdgeInsets(top: 0, leading: 30, bottom: 0, trailing: 30))

Secure Entry not working on iOS 14.2

FloatingLabelTextField($passwordText, validtionChecker: $passwordValid, placeholder: "Password") { (bool) in
            
        } commit: {
            
        }
        .isSecureTextEntry(true)
        
        .isShowError(true) /// Sets the is show error message.
                        .errorColor(.red) /// Sets the error color.
        .floatingStyle(MeterTextFieldStyle())
        .frame(height: 51)

That is my code and it does not work properly when run on an iPhone 12 mini. This is the field that shows up:
image

add option to disable all animations

Is there a way to disable all animations for FloatingLabelTextFieldSwiftUI?

Whenever other sibling views are added/removed above it (from the viewModel's state such as validation errors), the FloatingLabelTextFieldSwiftUI gets pushed down/up on the view. This animates the title label to lag behind the rest of the UI components, creating an undesirable effect.

It would be preferable to turn off the animation in this context.

validtion Checker

hi,
the validtion Checker variable is being changed to false when not passing the validation but not becoming true when it passes it
the error label is not showing but the binding variable still false
please advise
regards

Keyboard type should not allow character and special symbols when type is Numberpad?

I am creating mobile number field and setting keyboard type as NumberPad. Then following scenario occurs:

When running with iPad keyboard we are able to enter special characters. (iPad only)
We can paste the text which is copied earlier(iPad and iPhone).
How to find out each and every character typed? callbacks not calling

I am able to do this without your library by reading this tutorial https://programmingwithswift.com/numbers-only-textfield-with-swiftui/

see image here:

Screen Shot 2020-10-17 at 12 48 44 PM

I don"t have clear idea where to implement this in your class files. It would much better with those features.

Hope you got my points, Thanks for your great work.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.