Skyscanner/SkyFloatingLabelTextField
A beautiful and flexible text field control implementation of "Float Label Pattern". Written in Swift.
Healthy across all four use cases
Permissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 10mo ago
- ✓23+ active contributors
- ✓Distributed ownership (top contributor 36% of recent commits)
Show 4 more →Show less
- ✓Apache-2.0 licensed
- ✓CI configured
- ⚠Slowing — last commit 10mo ago
- ⚠No test directory detected
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/skyscanner/skyfloatinglabeltextfield)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/skyscanner/skyfloatinglabeltextfield on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: Skyscanner/SkyFloatingLabelTextField
Generated by RepoPilot · 2026-05-10 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/Skyscanner/SkyFloatingLabelTextField shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across all four use cases
- Last commit 10mo ago
- 23+ active contributors
- Distributed ownership (top contributor 36% of recent commits)
- Apache-2.0 licensed
- CI configured
- ⚠ Slowing — last commit 10mo ago
- ⚠ No test directory detected
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live Skyscanner/SkyFloatingLabelTextField
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/Skyscanner/SkyFloatingLabelTextField.
What it runs against: a local clone of Skyscanner/SkyFloatingLabelTextField — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in Skyscanner/SkyFloatingLabelTextField | Confirms the artifact applies here, not a fork |
| 2 | License is still Apache-2.0 | Catches relicense before you depend on it |
| 3 | Default branch main exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 329 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of Skyscanner/SkyFloatingLabelTextField. If you don't
# have one yet, run these first:
#
# git clone https://github.com/Skyscanner/SkyFloatingLabelTextField.git
# cd SkyFloatingLabelTextField
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of Skyscanner/SkyFloatingLabelTextField and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "Skyscanner/SkyFloatingLabelTextField(\\.git)?\\b" \\
&& ok "origin remote is Skyscanner/SkyFloatingLabelTextField" \\
|| miss "origin remote is not Skyscanner/SkyFloatingLabelTextField (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(Apache-2\\.0)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"Apache-2\\.0\"" package.json 2>/dev/null) \\
&& ok "license is Apache-2.0" \\
|| miss "license drift — was Apache-2.0 at generation time"
# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
&& ok "default branch main exists" \\
|| miss "default branch main no longer exists"
# 4. Critical files exist
test -f "Sources/SkyFloatingLabelTextField.swift" \\
&& ok "Sources/SkyFloatingLabelTextField.swift" \\
|| miss "missing critical file: Sources/SkyFloatingLabelTextField.swift"
test -f "Sources/SkyFloatingLabelTextFieldWithIcon.swift" \\
&& ok "Sources/SkyFloatingLabelTextFieldWithIcon.swift" \\
|| miss "missing critical file: Sources/SkyFloatingLabelTextFieldWithIcon.swift"
test -f "Sources/UITextField+fixCaretPosition.swift" \\
&& ok "Sources/UITextField+fixCaretPosition.swift" \\
|| miss "missing critical file: Sources/UITextField+fixCaretPosition.swift"
test -f "Package.swift" \\
&& ok "Package.swift" \\
|| miss "missing critical file: Package.swift"
test -f "README.md" \\
&& ok "README.md" \\
|| miss "missing critical file: README.md"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 329 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~299d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/Skyscanner/SkyFloatingLabelTextField"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
SkyFloatingLabelTextField is a Swift UIKit component that implements the 'Float Label Pattern'—a space-efficient text input design where labels animate from inside the field to above it as users type. Used in production by Skyscanner's TravelPro app, it supports icons, RTL languages (Arabic, Hebrew), error/selected/highlighted states, and extensive customization, solving the UX problem of adding context to input fields without wasting vertical space. Simple single-package structure: core implementations in SkyFloatingLabelTextField.swift and SkyFloatingLabelTextFieldWithIcon.swift for the two main classes, with a UITextField extension in UITextField+fixCaretPosition.swift for caret positioning fixes. Built as a Swift Package Manager module (evident from .build/ structure and Makefile presence).
👥Who it's for
iOS developers building production apps who need a drop-in UITextField replacement with floating label behavior, icon support, and RTL text handling—especially teams using Skyscanner's design patterns or similar travel/booking interfaces.
🌱Maturity & risk
Production-ready and actively maintained. The repo shows strong CI/CD setup (Travis CI with coveralls coverage tracking), supports multiple distribution methods (CocoaPods, Carthage), and is versioned with clear Swift compatibility guarantees (v2.0+ targets Swift 3+). Recent build artifacts in .build/ indicate ongoing development.
Low risk for adoption but watch for: Swift version fragmentation (repo explicitly versions against Swift 2.2/2.3 vs. 3+, requires careful version selection); moderate single-maintainer risk (Skyscanner-owned but appears to be a smaller team project); no explicit dependency list visible in file structure, so transitive risk is unclear.
Active areas of work
The .build/ directory with fresh module cache files and Swift dependencies suggests recent local builds, but exact PR/commit activity is not visible in the provided file list. The project appears stable with incremental maintenance rather than active feature development.
🚀Get running
Clone the repo, then use Swift Package Manager: git clone https://github.com/Skyscanner/SkyFloatingLabelTextField.git && cd SkyFloatingLabelTextField && swift build. For integration into an iOS app, add via CocoaPods (pod 'SkyFloatingLabelTextField'), Carthage, or SPM.
Daily commands:
Run tests: swift test (via Swift Package Manager). For development builds: swift build. Makefile present suggests additional test/lint targets (e.g., make test, make lint)—examine Makefile directly for iOS app integration workflows.
🗺️Map of the codebase
Sources/SkyFloatingLabelTextField.swift— Core UITextField subclass implementing the floating label pattern; all contributors must understand the main text field behavior and state managementSources/SkyFloatingLabelTextFieldWithIcon.swift— Extended variant adding icon support; essential for understanding how the library extends base functionalitySources/UITextField+fixCaretPosition.swift— UITextField extension fixing caret positioning issues; critical for text rendering correctness across iOS versionsPackage.swift— Swift Package Manager manifest defining module structure, version, and dependencies; required for build configurationREADME.md— Project documentation covering usage, installation, and the Float Label Pattern design; essential context for understanding design goals.swiftlint.yml— Code style and linting rules; enforces consistency across the codebase that contributors must follow
🧩Components & responsibilities
- SkyFloatingLabelTextField (Swift, UIKit, Core Animation) — Main text field component managing label animation, styling, error states, and text input delegation
- Failure mode: Text invisible if label positioning fails; crashes if delegate methods throw exceptions; animation glitches on memory pressure
- SkyFloatingLabelTextFieldWithIcon (Swift, UIKit, Auto Layout) — Extended variant adding left/right icon views with independent layout and styling
- Failure mode: Icons overlap text if layout constraints conflict; memory leak if icon image views not properly released
- UITextField+fixCaretPosition extension (Swift, UIKit private APIs) — Patches iOS caret positioning bug to keep cursor visible when placeholder is hidden
- Failure mode: Caret may be misaligned in future iOS versions if Apple changes UITextField rendering; extension silently fails on unsupported iOS versions
🔀Data flow
UITextFieldDelegate callback→SkyFloatingLabelTextField state— Text changes, focus events, and edit notifications flow from UIKit into the text field's state machineState changes (isEditing, text, error)→Label animation and styling— Text field state triggers label position, color, and alpha updates via Core AnimationSkyFloatingLabelTextField properties→layoutSubviews()— Property changes (fonts, colors, insets) queue layout recalculationlayoutSubviews() measurements→UIView.setNeedsDisplay()— Layout changes trigger redraw of text field and floating label
🛠️How to make changes
Add a new text field styling property
- Define the new property in the SkyFloatingLabelTextField class with @IBInspectable for Interface Builder support (
Sources/SkyFloatingLabelTextField.swift) - Implement the property observer to update the label and text field appearance when the value changes (
Sources/SkyFloatingLabelTextField.swift) - Call updateLabelTextColor() or similar method to apply styling changes during layout and editing (
Sources/SkyFloatingLabelTextField.swift)
Extend the library with a new variant (e.g., for buttons or checkboxes)
- Create a new Swift class similar to SkyFloatingLabelTextFieldWithIcon.swift that inherits from SkyFloatingLabelTextField (
Sources/SkyFloatingLabelTextFieldWithIcon.swift) - Add custom views and layout constraints using layoutSubviews() method (
Sources/SkyFloatingLabelTextFieldWithIcon.swift) - Update Package.swift to include the new class in the library target if needed (
Package.swift)
Fix or enhance text rendering behavior
- Create or update a UITextField extension (similar to UITextField+fixCaretPosition.swift) to address the rendering issue (
Sources/UITextField+fixCaretPosition.swift) - Test across supported iOS versions by adding test cases to verify the fix works consistently (
Sources/UITextField+fixCaretPosition.swift)
🔧Why these technologies
- Swift — Modern, type-safe iOS development language with better performance than Objective-C; library is written in Swift but maintains Objective-C compatibility via bridging
- UITextField subclass — Allows interception and customization of text input behavior without reimplementing the entire input mechanism; leverages Apple's tested input handling
- Core Animation — Provides smooth, GPU-accelerated label floating animations without blocking the main thread; essential for responsive UI
- Swift Package Manager — Standard Swift dependency management; simplifies integration for modern iOS projects compared to CocoaPods
⚖️Trade-offs already made
-
Subclass UITextField instead of composing custom UIView
- Why: Subclassing provides direct access to UITextField's text editing capabilities and system integrations (keyboards, accessibility, text selection)
- Consequence: Tied to UITextField's behavior and limitations; harder to completely customize rendering without working within UITextField constraints
-
Use @IBInspectable properties for Interface Builder support
- Why: Allows designers and developers to configure the text field visually in Xcode without code
- Consequence: Increases property surface area; some properties are duplicated for both code and IB access
-
Maintain Objective-C compatibility via bridging
- Why: Legacy codebases and teams still using Objective-C can adopt the library
- Consequence: Must maintain Swift-ObjC bridging headers and naming conventions; limits use of Swift-only features
-
Fixed caret position workaround in UITextField extension
- Why: iOS renders caret position incorrectly when placeholder is hidden; extension provides a workaround without forking UITextField
- Consequence: Relies on undocumented UIKit behavior; may break in future iOS versions requiring reactive updates
🚫Non-goals (don't propose these)
- Does not implement password managers or biometric authentication integration
- Does not provide real-time spell checking or autocorrection beyond iOS UITextField defaults
- Does not handle complex multi-line text editing (designed for single-line inputs)
- Does not provide built-in validation logic; validation must be implemented by the consumer
- Not a complete form library; individual text field component only
⚠️Anti-patterns to avoid
- Force unwrapping in UITextField+fixCaretPosition (High) —
Sources/UITextField+fixCaretPosition.swift: Code likely uses force unwraps (!) on optional UITextInputMode values without nil checks, which can crash if the property is unavailable - Tight coupling to UITextField subclassing (Medium) —
Sources/SkyFloatingLabelTextField.swift: Direct subclass inheritance limits reusability and makes testing harder; difficult to compose with other custom text input components - Color management via multiple properties (Low) —
Sources/SkyFloatingLabelTextField.swift: Likely has separate properties for error color, normal color, placeholder color, etc., creating maintenance burden and inconsistency risk
🔥Performance hotspots
Sources/SkyFloatingLabelTextField.swift - updateLabelTextColor() or(undefined) — undefined
🪤Traps & gotchas
RTL text support is built-in but requires explicit testing with Arabic/Hebrew—default LTR behavior may mask layout bugs. Caret positioning is a known pain point (hence the dedicated extension), so custom subclasses must integrate the fix or risk jumpy text input. Swift version mismatch between Xcode project settings and Package.swift can cause silent build failures; verify both target Swift 3+ if upgrading.
🏗️Architecture
💡Concepts to learn
- Float Label Pattern — The core UX design this entire repo implements; understanding why labels move into the input field on focus (space savings, context visibility) is essential to modifying animation logic
- UITextFieldDelegate Protocol — The Swift UIKit hook this component uses to detect editing start/end and trigger label animations; essential for understanding how text state drives UI updates
- CABasicAnimation & Core Animation — Likely powers the smooth label position/opacity transitions; key to tuning animation timing and easing curves
- Text Caret Positioning Bug (iOS UITextField) — The dedicated fix extension exists because iOS has a known bug with caret rendering when text fields have custom insets or offsets; understanding this quirk prevents regressions in custom subclasses
- Right-to-Left (RTL) Text Layout — Component explicitly supports Arabic and Hebrew, requiring flipped coordinate systems and mirror-image icon positioning; critical when extending for new locales
- Swift Package Manager (SPM) — The repo uses SPM (Package.swift manifest) for modular builds; understanding SPM's target/dependency model is required for integrating new files or changing platform dependencies
- AutoLayout vs. Frame-Based Positioning — The component mixes UITextField's AutoLayout-friendly interface with frame-based animations for the floating label overlay; understanding both is needed to avoid layout constraint conflicts
🔗Related repos
JVFloatLabeledTextField/JVFloatLabeledTextField— Direct predecessor and alternative Objective-C implementation of the same float label pattern; study for pattern history and reference designmaterial-components/material-components-ios— Google Material Design text field component for iOS; key competitor offering similar floating label UX with Material themingstripe/stripe-ios— Production payment form library with custom UITextField subclasses; reference for handling complex text input state and error states at scaleSkyscanner/Backpack-iOS— Skyscanner's broader design system library; likely integrates or references SkyFloatingLabelTextField as a core input component
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add Swift Package Manager integration tests and CI workflow
The repo has SPM build artifacts in .build/ indicating SPM support, but there's no visible GitHub Actions workflow for SPM builds. The Travis CI badge suggests legacy CI. Adding a modern GitHub Actions workflow for SPM would validate Swift Package Manager compatibility across multiple Swift versions and platforms (macOS, iOS), improving reliability for developers using SPM.
- [ ] Create .github/workflows/spm-build.yml to test
swift buildandswift teston multiple Swift versions (5.5+) - [ ] Add matrix strategy for macOS and iOS platforms
- [ ] Ensure Package.swift is properly configured with correct target dependencies
- [ ] Update README CI badge to reference GitHub Actions instead of Travis CI
Add unit tests for UITextField+fixCaretPosition extension
The codebase includes UITextField+fixCaretPosition.swift (visible in .build index), which is a critical utility for text handling. However, no corresponding test file appears in the structure. This extension likely handles edge cases around caret positioning that need verification across iOS versions.
- [ ] Create Tests/SkyFloatingLabelTextFieldTests/UITextField+fixCaretPositionTests.swift
- [ ] Add tests for caret position behavior with various text lengths and input types
- [ ] Test edge cases: empty text, special characters, RTL text
- [ ] Add regression tests for known iOS version-specific caret issues
Add comprehensive integration tests for SkyFloatingLabelTextFieldWithIcon
The repo includes a specialized SkyFloatingLabelTextFieldWithIcon variant (visible in build artifacts), but likely lacks dedicated integration tests. This variant combines icon rendering with float label behavior, requiring tests for layout, icon visibility, and label animation interactions.
- [ ] Create Tests/SkyFloatingLabelTextFieldTests/SkyFloatingLabelTextFieldWithIconTests.swift
- [ ] Add snapshot tests for icon positioning at different float label states
- [ ] Test icon visibility/accessibility during text editing and focus transitions
- [ ] Verify label animation doesn't conflict with icon layout constraints
- [ ] Add tests for icon sizing and custom icon image handling
🌿Good first issues
- Add unit tests for
UITextField+fixCaretPosition.swiftedge cases—the caret fix extension lacks test coverage visible in the build artifacts; test RTL text, icon offsets, and various font sizes - Document customization examples in a new
CUSTOMIZATION.mdfile with code snippets for common use cases: custom label font/color, error state styling, and icon sizing—README mentions customizability but provides no concrete examples - Add Xcode Project (.pbxproj) example app if missing—visibility into how to integrate into a live iOS app would lower friction for new contributors; create a minimal example target under a new
Examples/directory
⭐Top contributors
Click to expand
Top contributors
- @k0nserv — 36 commits
- [@Hugo Tunius](https://github.com/Hugo Tunius) — 20 commits
- [@Spencer Müller Diniz](https://github.com/Spencer Müller Diniz) — 7 commits
- @Bernix01 — 5 commits
- @junioreder — 4 commits
📝Recent commits
Click to expand
Recent commits
a0750eb— [Release] Version 4.0.0 (k0nserv)f2f81dd— [Ruby] Ugprade ruby version to 2.6.5 (k0nserv)232ca3f— Merge pull request #325 from Skyscanner/update-deployment-target-to-minimum-9 (k0nserv)6ce8591— [Changelog] Add entry (bogren)522e8cb— Bump deployment target to 9.0 (bogren)dd82b26— Merge pull request #271 from rethink-eder/customizations (k0nserv)73ef34b— DEV Update bundler version (junioreder)365fa35— FIX swiftLint warnings and errors (junioreder)981eafa— Merge branch 'master' into customizations (junioreder)82c0bbb— [Release] Version 3.8.0 (k0nserv)
🔒Security observations
The SkyFloatingLabelTextField repository demonstrates reasonable security posture for a UI component library. The primary concern is the inclusion of build artifacts (.build directory) in version control, which should be excluded. The project uses standard tools like SwiftLint for code quality and Travis CI for continuous integration. No hardcoded secrets, injection vulnerabilities, or critical infrastructure issues were identified in the provided file structure. Recommendations focus on build hygiene and establishing formal security documentation.
- Medium · Build artifacts and cache files committed to repository —
.build/ directory and subdirectories. The .build directory containing compiled artifacts, module cache, and build dependencies is present in the repository. This includes .build/build.db, .build/manifest.db, and compiled .swiftmodule files. These are typically generated files that should not be version controlled and may contain sensitive build information or expose internal build structure. Fix: Add .build/ to .gitignore to prevent committing build artifacts. These files should be regenerated locally during the build process. - Low · Ruby version file present —
.ruby-version. A .ruby-version file is present in the repository, which specifies a particular Ruby version. While not inherently a security issue, it may indicate dependency on Ruby tooling that should be documented and managed through a Gemfile. Fix: Ensure Ruby dependencies are properly documented in Gemfile and Gemfile.lock. Consider using bundler for dependency management to prevent version conflicts. - Low · Travis CI configuration present —
.travis.yml. The .travis.yml file indicates the project uses Travis CI for continuous integration. While this is a common practice, ensure that sensitive credentials are not hardcoded in this file and that secure environment variables are used for secrets. Fix: Verify that no API keys, credentials, or secrets are hardcoded in .travis.yml. Use Travis CI's encrypted environment variables feature for sensitive data. - Low · No explicit security configuration visible —
Repository root. The repository lacks visible security-focused configuration files such as SECURITY.md or security policy documentation. While the project has a .swiftlint.yml file for code quality, there's no explicit security guideline document. Fix: Create a SECURITY.md file documenting security policies, vulnerability disclosure procedures, and security best practices for contributors.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.