Convert Figma logo to code with AI

Skyscanner logoSkyFloatingLabelTextField

A beautiful and flexible text field control implementation of "Float Label Pattern". Written in Swift.

4,094
542
4,094
84

Top Related Projects

An easily internationalizable, mobile-friendly datepicker library for the web

:octocat: 📃 FoldingCell is an expanding content cell with animation made by @Ramotion

:octocat: ExpandingCollection is an animated material design UI card peek/pop controller. iOS library made by @Ramotion

:octocat: NavigationStack is a stack-modeled UI navigation controller. Swift UI library made by @Ramotion

:octocat: 🔍 RAMReel is a UI controller that allows you to choose options from a list. Swift UI library made by @Ramotion

:octocat: ⭕️ CircleMenu is a simple, elegant UI menu with a circular layout and material design animations. Swift UI library made by @Ramotion

Quick Overview

SkyFloatingLabelTextField is a subclass of UITextField that displays a floating label above the text field when it becomes the first responder. This provides a clean and modern user interface for text input fields in iOS applications.

Pros

  • Intuitive UI: The floating label design provides a clear and intuitive user experience for text input fields.
  • Customizable: The library offers a wide range of customization options, allowing developers to easily integrate it into their app's design.
  • Well-documented: The project has detailed documentation, making it easy for developers to understand and use the library.
  • Active development: The project is actively maintained, with regular updates and bug fixes.

Cons

  • Dependency on UIKit: The library is tightly coupled with UIKit, which may limit its use in cross-platform development frameworks.
  • Limited functionality: The library primarily focuses on the floating label feature and may not provide advanced text field functionality out of the box.
  • Potential performance impact: The floating label animation may have a slight performance impact on older devices.
  • Limited support for accessibility: The library may not have comprehensive support for accessibility features, such as VoiceOver.

Code Examples

// Creating a SkyFloatingLabelTextField
let textField = SkyFloatingLabelTextField(frame: CGRect(x: 20, y: 100, width: 300, height: 50))
textField.placeholder = "Enter your name"
textField.title = "Name"
view.addSubview(textField)

This code creates a SkyFloatingLabelTextField instance and adds it to the view hierarchy.

// Customizing the appearance of the text field
textField.textColor = .black
textField.selectedTitleColor = .blue
textField.selectedLineColor = .blue
textField.font = UIFont.systemFont(ofSize: 16)
textField.titleFont = UIFont.systemFont(ofSize: 12)

This code customizes the appearance of the SkyFloatingLabelTextField instance, including the text color, selected title color, selected line color, and font sizes.

// Handling text field events
textField.addTarget(self, action: #selector(textFieldDidChange(_:)), for: .editingChanged)

@objc private func textFieldDidChange(_ textField: UITextField) {
    // Handle text changes
    print("Text changed: \(textField.text ?? "")")
}

This code adds a target-action for the editingChanged event of the SkyFloatingLabelTextField instance, allowing the developer to handle text changes.

Getting Started

To get started with SkyFloatingLabelTextField, follow these steps:

  1. Add the library to your project using a dependency manager like CocoaPods or Carthage:

    # CocoaPods
    pod 'SkyFloatingLabelTextField'
    
  2. Import the library in your Swift file:

    import SkyFloatingLabelTextField
    
  3. Create an instance of SkyFloatingLabelTextField and customize its properties as needed:

    let textField = SkyFloatingLabelTextField(frame: CGRect(x: 20, y: 100, width: 300, height: 50))
    textField.placeholder = "Enter your name"
    textField.title = "Name"
    textField.textColor = .black
    textField.selectedTitleColor = .blue
    textField.selectedLineColor = .blue
    textField.font = UIFont.systemFont(ofSize: 16)
    textField.titleFont = UIFont.systemFont(ofSize: 12)
    view.addSubview(textField)
    
  4. Optionally, add event handlers for the text field:

    textField.addTarget(self, action: #selector(textFieldDidChange(_:)), for: .editingChanged)
    
    @objc private func textFieldDidChange(_ textField: UITextField) {
        // Handle text changes
        print("Text changed: \(textField.text ?? "")")
    }
    

That's it! You've now integrated the SkyFloatingLabel

Competitor Comparisons

An easily internationalizable, mobile-friendly datepicker library for the web

Pros of react-dates/react-dates

  • Extensive Customization: react-dates provides a wide range of customization options, allowing developers to tailor the date picker to their specific needs.
  • Accessibility: The library is designed with accessibility in mind, ensuring a smooth experience for users with disabilities.
  • Robust Feature Set: react-dates offers a comprehensive set of features, including date range selection, single date selection, and various date input formats.

Cons of react-dates/react-dates

  • Larger Bundle Size: Due to its extensive feature set, react-dates can result in a larger bundle size compared to SkyFloatingLabelTextField.
  • Learning Curve: The library has a steeper learning curve, as it provides a more complex API and requires more configuration to set up.
  • Dependency on Moment.js: react-dates relies on the Moment.js library for date manipulation, which some developers may consider a drawback.

Code Comparison

SkyFloatingLabelTextField

let textField = SkyFloatingLabelTextField()
textField.placeholder = "Enter text"
textField.title = "Title"
textField.selectedTitleColor = .blue
textField.selectedLineColor = .blue

react-dates

<DateRangePicker
  startDate={this.state.startDate}
  startDateId="your_unique_start_date_id"
  endDate={this.state.endDate}
  endDateId="your_unique_end_date_id"
  onDatesChange={({ startDate, endDate }) => this.setState({ startDate, endDate })}
  focusedInput={this.state.focusedInput}
  onFocusChange={focusedInput => this.setState({ focusedInput })}
/>

:octocat: 📃 FoldingCell is an expanding content cell with animation made by @Ramotion

Pros of Folding Cell

  • Folding Cell provides a unique and visually appealing way to display content, allowing users to expand and collapse sections of information.
  • The library is well-documented and includes detailed examples, making it easy to integrate into a project.
  • Folding Cell is highly customizable, allowing developers to adjust the animation, colors, and other visual aspects to fit their application's design.

Cons of Folding Cell

  • Folding Cell is a more specialized component compared to SkyFloatingLabelTextField, which provides a more general text field functionality.
  • The library may not be as widely used as SkyFloatingLabelTextField, which could mean less community support and fewer third-party integrations.
  • Folding Cell may have a steeper learning curve for developers who are not familiar with custom UI components and animations.

Code Comparison

SkyFloatingLabelTextField:

let textField = SkyFloatingLabelTextField()
textField.placeholder = "Enter text"
textField.title = "Label"
textField.textColor = .black
textField.selectedTitleColor = .blue

Folding Cell:

let foldingCell = FoldingCell()
foldingCell.cellHeight = 200
foldingCell.selectedAnimation = .default
foldingCell.isSelected = true
foldingCell.contentView.backgroundColor = .white

:octocat: ExpandingCollection is an animated material design UI card peek/pop controller. iOS library made by @Ramotion

Pros of Expanding Collection

  • Expanding Collection provides a unique and visually appealing user interface for displaying content, with a focus on animation and interactivity.
  • The library offers a variety of customization options, allowing developers to tailor the appearance and behavior of the collection to their specific needs.
  • Expanding Collection is well-documented and has a active community, making it easier for developers to get started and find support.

Cons of Expanding Collection

  • Compared to SkyFloatingLabelTextField, Expanding Collection may have a steeper learning curve, as it introduces a more complex UI paradigm.
  • The library may have a larger footprint in terms of file size and dependencies, which could be a concern for projects with strict performance requirements.
  • The level of customization offered by Expanding Collection may be overkill for some use cases, where a simpler text field solution like SkyFloatingLabelTextField may be more appropriate.

Code Comparison

SkyFloatingLabelTextField:

let textField = SkyFloatingLabelTextField()
textField.placeholder = "Enter text"
textField.title = "Label"
textField.selectedTitleColor = .blue
textField.selectedLineColor = .blue

Expanding Collection:

let expandingCollection = ExpandingCollection()
expandingCollection.cellSpacing = 16
expandingCollection.animationDuration = 0.8
expandingCollection.cellSize = CGSize(width: 200, height: 200)
expandingCollection.backgroundColor = .white

:octocat: NavigationStack is a stack-modeled UI navigation controller. Swift UI library made by @Ramotion

Pros of Navigation Stack

  • Customizable Animations: Navigation Stack provides a wide range of customizable animations for transitioning between views, allowing developers to create unique and visually appealing user experiences.
  • Flexible Navigation: The library offers a flexible navigation system that can be easily integrated into existing projects, making it a versatile choice for developers.
  • Smooth Transitions: Navigation Stack ensures smooth and seamless transitions between views, providing a polished and professional-looking user interface.

Cons of Navigation Stack

  • Steeper Learning Curve: Compared to SkyFloatingLabelTextField, Navigation Stack may have a slightly steeper learning curve, as it offers more advanced features and customization options.
  • Potential Performance Impact: Depending on the complexity of the animations and the number of views being managed, Navigation Stack may have a higher performance impact on the application, which should be considered during development.

Code Comparison

SkyFloatingLabelTextField:

let textField = SkyFloatingLabelTextField()
textField.placeholder = "Enter text"
textField.title = "Title"
textField.selectedTitleColor = .blue
textField.selectedLineColor = .blue

Navigation Stack:

let navigationController = NavigationStackController()
let viewController = UIViewController()
viewController.view.backgroundColor = .white
navigationController.push(viewController, animated: true)

:octocat: 🔍 RAMReel is a UI controller that allows you to choose options from a list. Swift UI library made by @Ramotion

Pros of Reel Search

  • Reel Search provides a unique and visually appealing search interface with a rotating wheel-like design, which can be a distinctive feature for certain applications.
  • The library includes various customization options, allowing developers to adjust the appearance and behavior of the search component to fit their specific needs.
  • Reel Search is actively maintained and has a relatively large community, with regular updates and bug fixes.

Cons of Reel Search

  • Compared to SkyFloatingLabelTextField, Reel Search may have a more limited set of features and functionality, as it is primarily focused on the search interface.
  • The learning curve for Reel Search may be slightly steeper, as developers need to understand the specific implementation details and customization options.
  • Reel Search may not be as widely adopted as SkyFloatingLabelTextField, which could mean fewer resources and community support available.

Code Comparison

SkyFloatingLabelTextField:

let textField = SkyFloatingLabelTextField()
textField.placeholder = "Enter text"
textField.title = "Label"
textField.selectedTitleColor = .blue
textField.selectedLineColor = .blue

Reel Search:

let reelSearch = ReelSearchView()
reelSearch.delegate = self
reelSearch.placeholder = "Search"
reelSearch.font = UIFont.systemFont(ofSize: 18)
reelSearch.textColor = .black

:octocat: ⭕️ CircleMenu is a simple, elegant UI menu with a circular layout and material design animations. Swift UI library made by @Ramotion

Pros of Circle Menu

  • Circle Menu provides a unique and visually appealing circular layout for menu items, which can be a more engaging and intuitive user interface compared to traditional menu layouts.
  • The library includes various customization options, allowing developers to adjust the appearance and behavior of the menu to fit their app's design.
  • Circle Menu is well-documented and has a active community, making it easier for developers to get started and find support.

Cons of Circle Menu

  • The circular layout may not be suitable for all types of applications, and may not be as efficient for navigating a large number of menu items.
  • The library may have a higher learning curve compared to simpler menu solutions, as developers need to understand the circular layout and its associated interactions.
  • The performance of Circle Menu may be a concern for developers working on resource-constrained devices, as the circular animation and layout can be more computationally intensive.

Code Comparison

Circle Menu:

let circleMenu = CircleMenu(
    frame: view.bounds,
    buttonSize: 50,
    startAngle: -90,
    menuOptions: [
        CircleMenuOption(image: UIImage(named: "home")!),
        CircleMenuOption(image: UIImage(named: "search")!),
        CircleMenuOption(image: UIImage(named: "settings")!)
    ]
)
view.addSubview(circleMenu)

SkyFloatingLabelTextField:

let textField = SkyFloatingLabelTextField(frame: CGRect(x: 20, y: 100, width: 300, height: 50))
textField.placeholder = "Enter text"
textField.title = "Title"
textField.selectedTitleColor = .blue
textField.selectedLineColor = .blue
view.addSubview(textField)

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

SkyFloatingLabelTextField

Build Status Coverage Status Pod Platform Pod License

Pod Version Carthage compatible Documentation Readme Score

SkyFloatingLabelTextField is a beautiful, flexible and customizable implementation of the space saving "Float Label Pattern". This design enables adding context to input fields that are visible at the time of typing, while minimizing the additional space used to display this additional context. This component is used in the Skyscanner TravelPro iOS application in several places, like when searching for flights.

On top of implementing the space-saving floating title, the component also supports using iconography, RTL text support (e.g. Arabic & Hebrew), various states (error, selected, highlighted states), and is very much customizable and extensible.

Versioning

Up until version 1.2 Swift 2.2 and 2.3 compatible (and there is a Swift 2.3 branch in case you need it). From version 2.0 onwards only compatible with Swift 3. Please be mindful of the version you're using.

Usage

To start using the component add it to your project using CocoaPods, Carthage or manually as per the Installation section.

The UI component can be used via the SkyFloatingLabelTextField class. To use icons on the right hand side, use the SkyFloatingLabelTextFieldWithIcon class. This control can be used very similar to UITextField - both from Interface Builder, or from code.

To create an instance of the class, use Interface builder, or do it from code. This example will create the following textbox with the placeholder and title:

let textField = SkyFloatingLabelTextField(frame: CGRect(x: 10, y: 10, width: 200, height: 45))
textField.placeholder = "Name"
textField.title = "Your full name"
self.view.addSubview(textField)

Colors

To customize the colors of the textfield, set a few properties - either from code, or from Interface builder. To use a textfield with an icon, utilize the SkyFloatingLabelTextFieldWithIcon class (and bundle the font class with your app). This example will change colors for the textfield on the right:

let lightGreyColor = UIColor(red: 197/255, green: 205/255, blue: 205/255, alpha: 1.0)
let darkGreyColor = UIColor(red: 52/255, green: 42/255, blue: 61/255, alpha: 1.0)
let overcastBlueColor = UIColor(red: 0, green: 187/255, blue: 204/255, alpha: 1.0)

let textField1 = SkyFloatingLabelTextField(frame: CGRect(x: 10, y: 10, width: 120, height: 45))
textField1.placeholder = "First name"
textField1.title = "Given name"
self.view.addSubview(textField1)

let textField2 = SkyFloatingLabelTextField(frame: CGRect(x: 150, y: 10, width: 120, height: 45))
textField2.placeholder = "Last name"
textField2.title = "Family name"

textField2.tintColor = overcastBlueColor // the color of the blinking cursor
textField2.textColor = darkGreyColor
textField2.lineColor = lightGreyColor
textField2.selectedTitleColor = overcastBlueColor
textField2.selectedLineColor = overcastBlueColor

textField2.lineHeight = 1.0 // bottom line height in points
textField2.selectedLineHeight = 2.0
self.view.addSubview(textField2)

Icons and fonts

Use the SkyFloatingLabelTextFieldWithIcon field to display icons next to the textfields. You have the option of using a font or an image as the icon by setting the iconType property (Default = IconType.font). If using an image as icon, you will have to set the iconImage property. If using a font as icon, you will have to set the iconFont property and bundle your icon with your app (if it's not a built in one). Icons can be rotated and more precise positioning is also supported:

Using a font

let overcastBlueColor = UIColor(red: 0, green: 187/255, blue: 204/255, alpha: 1.0)
let textFieldFrame = CGRect(x: 150, y: 10, width: 120, height: 45)

let textField1 = SkyFloatingLabelTextFieldWithIcon(frame: textFieldFrame, iconType: .font)
textField1.placeholder = "Departure"
textField1.title = "Flying from"
textField1.iconFont = UIFont(name: "FontAwesome", size: 15)
textField1.iconText = "\u{f072}" // plane icon as per https://fortawesome.github.io/Font-Awesome/cheatsheet/
self.view.addSubview(textField1)

let textField2 = SkyFloatingLabelTextFieldWithIcon(frame: textFieldFrame)
textField2.placeholder = "Arrival"
textField2.title = "Flying to"
textField2.tintColor = overcastBlueColor
textField2.selectedTitleColor = overcastBlueColor
textField2.selectedLineColor = overcastBlueColor

// Set icon properties
textField2.iconType = .font
textField2.iconColor = UIColor.lightGrayColor()
textField2.selectedIconColor = overcastBlueColor
textField2.iconFont = UIFont(name: "FontAwesome", size: 15)
textField2.iconText = "\u{f072}" // plane icon as per https://fortawesome.github.io/Font-Awesome/cheatsheet/
textField2.iconMarginBottom = 4.0 // more precise icon positioning. Usually needed to tweak on a per font basis.
textField2.iconRotationDegrees = 90 // rotate it 90 degrees
textField2.iconMarginLeft = 2.0
self.view.addSubview(textField2)

Using an image

let textFieldframe = CGRect(x: 150, y: 10, width: 120, height: 45)

let textField1 = SkyFloatingLabelTextFieldWithIcon(frame: textFieldframe, iconType: .image)
textField1.placeholder = "Departure"
textField1.title = "Flying from"
textField1.iconImage = UIImage(imageLiteralResourceName: "PlaneIcon")
self.view.addSubview(textField1)

Error state and delegates

The textfield supports displaying an error state - this can be useful for example when validating fields on the fly. When the errorMessage property is set on the control, then the control is highlighted with the color set in the errorColor property.

To get notified of different events happening on the textfield - such as the text changing, editing starting or ending - just set the func addTarget(_ target: Any?, action: Selector, for controlEvents: UIControl.Event) with the .editingChanged. also can set the delegate property to a class implementing the standard UITextFieldDelegate protocol:

class MyViewController: UIViewController, UITextFieldDelegate {
    override func viewDidLoad() {
        super.viewDidLoad()
        let textField1 = SkyFloatingLabelTextField(frame: CGRect(x: 10, y: 10, width: 120, height: 45))
        textField1.placeholder = "Email"
        textField1.title = "Email address"
        textField1.errorColor = UIColor.redColor()
        textField1.addTarget(self, action: #selector(textFieldDidChange(_:)), for: .editingChanged)
        self.view.addSubview(textField1)
    }
    
    // This will notify us when something has changed on the textfield
    @objc func textFieldDidChange(_ textfield: UITextField) {
        if let text = textfield.text {
            if let floatingLabelTextField = textField as? SkyFloatingLabelTextField {
                if(text.characters.count < 3 || !text.containsString("@")) {
                    floatingLabelTextField.errorMessage = "Invalid email"
                }
                else {
                    // The error message will only disappear when we reset it to nil or empty string
                    floatingLabelTextField.errorMessage = ""
                }
            }
        }
    }
}

Disabled state

The textfield also supports displaying a disabled state. When the isEnabled property is set on the control, then the control is highlighted with the color set in the disabledColor property.

    textField.disabledColor = disabledColor
    textField.isEnabled = false

RTL language support

The component automatically detects the language writing direction. When the phone has a RTL language set (e.g. Arabic or Hebrew), then it automatically adjusts to support this style.

Alternatively, set the isLTRLanguage property to manually change the writing direction.

Further customizing the control by subclassing

The control was designed to allow further customization in subclasses. The control itself inherits from UITextField, so the standard overrides from there can all be used. A few other notable customization hooks via overriding are:

  • updateColors: override this method to customize colors whenever the state of the control changes
  • Layout overrides:
    • titleLabelRectForBounds(bounds:CGRect, editing:Bool): override to change the bounds of the top title placeholder view
    • textRectForBounds(bounds: CGRect): override to change the bounds of the control (inherited from UITextField)
    • editingRectForBounds(bounds: CGRect): override to change the bounds of the control when editing / selected (inherited from UITextField)
    • placeholderRectForBounds(bounds: CGRect): override to change the bounds of the placeholder view
    • lineViewRectForBounds(bounds:CGRect, editing:Bool): override to change the bounds of the bottom line view

Documentation

See the SkyFloatingLabelTextField documentation on CocoaDocs.org for the full documentation.

Installation

CocoaPods

The control is available through CocoaPods. CocoaPods can be installed using Ruby gems:

$ gem install cocoapods

Then simply add SkyFloatingLabelTextField to your Podfile:

pod 'SkyFloatingLabelTextField', '~> 3.0'

Lastly, let CocoaPods fetch the latest version of the component by running:

$ pod update
Integrating into Objective C projects

When integrating the component into an Objective C project, in the Podfile add use_frameworks!. For example as shown in SkyFloatingLabelTextFieldObjectiveCExample:

use_frameworks!

target 'SkyFloatingLabelTextFieldObjectiveCExample' do
  pod 'SkyFloatingLabelTextField', '~> 3.0'
end

Then to use the component in your code, add the following line to your .h or .m files:

@import SkyFloatingLabelTextField;

Carthage

The component supports Carthage. Start by making sure you have the latest version of Carthage installed. Using Homebrew run this:

$ brew update
$ brew install carthage

Then add SkyFloatingLabelTextField to your Cartfile:

github "Skyscanner/SkyFloatingLabelTextField"

Finally, add the framework to the Xcode project of your App. Link the framework to your App and copy it to the App’s Frameworks directory via the “Build Phases” section.

Manual

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

Contributing

We welcome all contributions. Please read this guide before opening issues or submitting pull requests, as well as how and who to contact with questions.

Credits

The original component was built by Daniel Langh, Gergely Orosz and Raimon Laupente. Notable contributions by Shai Shamir (RTL language support).

Credits for the original design, and improving it with iconography to Matt D. Smith (@mds).

FAQ

  • Can I use it in Objective C projects?

    Of course! Please see the Integrating-into-Objective-C-projects section on how to integrate the component via CocoaPods.

  • Does the control work well with auto layout? What about using it programmatically?

    The control was built to support both use cases. It plays nicely with autolayout. As the control is a subclass of UITextField, overriding textRectForBounds(bounds:) or editingRectForBounds(bounds:) is always an option. Alternatively, overriding intrinsiccontentsize is also another possibility.

  • How can I remove the line from the bottom of the textfield?

    Set lineHeight and selectedLineHeight to 0, and the line won't be displayed.

  • I'd like to validate the textfield using the errorMessage. How can I re-validate text is typed in the textfield?

    Using a delegate implement the textField(textField:,range:string:) method. This method fires whenever the text is changed - do the validation here. Alternatively, using subclassing you can also override the becomeFirstResponder method to e.g. clear the text or error message when the textfield is selected.