├── .gitignore
├── JVFloatLabeledTextFieldTests
├── en.lproj
│ └── InfoPlist.strings
├── JVFloatLabeledTextFieldTests-Prefix.pch
├── JVFloatLabeledTextFieldTests-Info.plist
├── JVFloatLabeledTextViewTests.m
└── JVFloatLabeledTextFieldTests.m
├── JVFloatLabeledTextField
├── SPMHeaders
│ ├── JVFloatLabeledTextView.h
│ ├── JVFloatLabeledTextField-Interface.h
│ └── JVFloatLabeledTextField.h
├── images
│ ├── Default.png
│ ├── Default@2x.png
│ └── Default-568h@2x.png
├── JVFloatLabeledTextFieldXIBViewController.h
├── JVFloatLabeledTextField-Prefix.pch
├── JVFloatLabeledText-Info.plist
├── JVFloatLabeledTextFieldXIBViewController.m
├── JVFloatLabeledTextField-Info.plist
├── JVFloatLabeledTextFieldViewController.h
├── JVAppDelegate.h
├── main.m
├── JVFloatLabeledText.h
├── JVFloatLabeledTextField
│ ├── NSString+TextDirectionality.h
│ ├── JVFloatLabeledTextView.h
│ ├── JVFloatLabeledTextField.h
│ ├── JVFloatLabeledTextField.m
│ ├── JVFloatLabeledTextView.m
│ └── NSString+TextDirectionality.m
├── JVAppDelegate.m
├── JVFloatLabeledTextFieldXIBViewController.xib
└── JVFloatLabeledTextFieldViewController.m
├── .travis.yml
├── .swiftpm
└── xcode
│ ├── package.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcuserdata
│ │ └── dayalaja.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
│ └── xcuserdata
│ └── dayalaja.xcuserdatad
│ └── xcschemes
│ └── xcschememanagement.plist
├── JVFloatLabeledTextField.xcodeproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcuserdata
│ │ ├── david.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
│ │ └── dayalaja.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
├── xcuserdata
│ └── david.xcuserdatad
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
├── xcshareddata
│ └── xcschemes
│ │ ├── JVFloatLabeledText.xcscheme
│ │ ├── JVFloatLabeledTextFieldTests.xcscheme
│ │ └── JVFloatLabeledTextField.xcscheme
└── project.pbxproj
├── Package.swift
├── JVFloatLabeledTextField.podspec
├── LICENSE
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 |
--------------------------------------------------------------------------------
/JVFloatLabeledTextFieldTests/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/JVFloatLabeledTextField/SPMHeaders/JVFloatLabeledTextView.h:
--------------------------------------------------------------------------------
1 | ../JVFloatLabeledTextField/JVFloatLabeledTextView.h
--------------------------------------------------------------------------------
/JVFloatLabeledTextField/SPMHeaders/JVFloatLabeledTextField-Interface.h:
--------------------------------------------------------------------------------
1 | ../JVFloatLabeledTextField/JVFloatLabeledTextField.h
--------------------------------------------------------------------------------
/JVFloatLabeledTextField/images/Default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jverdi/JVFloatLabeledTextField/HEAD/JVFloatLabeledTextField/images/Default.png
--------------------------------------------------------------------------------
/JVFloatLabeledTextField/images/Default@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jverdi/JVFloatLabeledTextField/HEAD/JVFloatLabeledTextField/images/Default@2x.png
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: objective-c
2 | script: xctool -project JVFloatLabeledTextField.xcodeproj -scheme JVFloatLabeledTextFieldTests -sdk iphonesimulator test
3 |
--------------------------------------------------------------------------------
/JVFloatLabeledTextField/images/Default-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jverdi/JVFloatLabeledTextField/HEAD/JVFloatLabeledTextField/images/Default-568h@2x.png
--------------------------------------------------------------------------------
/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.swiftpm/xcode/package.xcworkspace/xcuserdata/dayalaja.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jverdi/JVFloatLabeledTextField/HEAD/.swiftpm/xcode/package.xcworkspace/xcuserdata/dayalaja.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/JVFloatLabeledTextField.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/JVFloatLabeledTextField.xcodeproj/project.xcworkspace/xcuserdata/david.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jverdi/JVFloatLabeledTextField/HEAD/JVFloatLabeledTextField.xcodeproj/project.xcworkspace/xcuserdata/david.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/JVFloatLabeledTextField.xcodeproj/project.xcworkspace/xcuserdata/dayalaja.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jverdi/JVFloatLabeledTextField/HEAD/JVFloatLabeledTextField.xcodeproj/project.xcworkspace/xcuserdata/dayalaja.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/JVFloatLabeledTextFieldTests/JVFloatLabeledTextFieldTests-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header
3 | //
4 | // The contents of this file are implicitly included at the beginning of every source file.
5 | //
6 |
7 | #ifdef __OBJC__
8 | #import
9 | #import
10 | #endif
11 |
--------------------------------------------------------------------------------
/JVFloatLabeledTextField/JVFloatLabeledTextFieldXIBViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // JVFloatLabeledTextFieldXIBViewController.h
3 | // JVFloatLabeledTextField
4 | //
5 | // Created by Jared Verdi on 4/2/16.
6 | // Copyright © 2016 Jared Verdi. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface JVFloatLabeledTextFieldXIBViewController : UIViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/JVFloatLabeledTextField/JVFloatLabeledTextField-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header
3 | //
4 | // The contents of this file are implicitly included at the beginning of every source file.
5 | //
6 |
7 | #import
8 |
9 | #ifndef __IPHONE_3_0
10 | #warning "This project uses features only available in iOS SDK 3.0 and later."
11 | #endif
12 |
13 | #ifdef __OBJC__
14 | #import
15 | #import
16 | #endif
17 |
--------------------------------------------------------------------------------
/.swiftpm/xcode/xcuserdata/dayalaja.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | JVFloatLabeledTextField.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | JVFloatLabeledTextField
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:5.2
2 | // The swift-tools-version declares the minimum version of Swift required to build this package.
3 |
4 | import PackageDescription
5 |
6 | let package = Package(
7 | name: "JVFloatLabeledTextField",
8 | platforms: [
9 | .iOS(.v9)
10 | ],
11 | products: [
12 | .library(
13 | name: "JVFloatLabeledTextField",
14 | targets: ["JVFloatLabeledTextField"]),
15 | ],
16 | dependencies: [
17 |
18 | ],
19 | targets: [
20 | .target(
21 | name: "JVFloatLabeledTextField",
22 | dependencies: [],
23 | path: "JVFloatLabeledTextField",
24 | sources: ["JVFloatLabeledTextField"],
25 | publicHeadersPath: "SPMHeaders"
26 | )
27 | ]
28 | )
29 |
--------------------------------------------------------------------------------
/JVFloatLabeledTextFieldTests/JVFloatLabeledTextFieldTests-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundlePackageType
14 | BNDL
15 | CFBundleShortVersionString
16 | 1.0
17 | CFBundleSignature
18 | ????
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/JVFloatLabeledTextField/JVFloatLabeledText-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(CURRENT_PROJECT_VERSION)
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/JVFloatLabeledTextField.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = "JVFloatLabeledTextField"
3 | s.version = "1.2.5"
4 | s.summary = "The original UITextField subclass implementing the Float Label Pattern."
5 | s.homepage = "http://github.com/jverdi/JVFloatLabeledTextField"
6 | s.screenshot = "https://github-camo.global.ssl.fastly.net/be57d040ec0ce5d6467fb73564c6bcb6c76d5a7b/687474703a2f2f6472696262626c652e73332e616d617a6f6e6177732e636f6d2f75736572732f363431302f73637265656e73686f74732f313235343433392f666f726d2d616e696d6174696f6e2d5f6769665f2e676966"
7 | s.license = { :type => 'MIT', :file => 'LICENSE' }
8 | s.author = { "Jared Verdi" => "jared@jaredverdi.com" }
9 | s.source = { :git => "https://github.com/jverdi/JVFloatLabeledTextField.git", :tag => s.version.to_s }
10 | s.platform = :ios
11 | s.source_files = 'JVFloatLabeledTextField/JVFloatLabeledTextField/*.{h,m}'
12 | s.frameworks = 'Foundation', 'UIKit'
13 | s.requires_arc = true
14 | end
15 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2013-2015 Jared Verdi
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | 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, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/JVFloatLabeledTextField/JVFloatLabeledTextFieldXIBViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // JVFloatLabeledTextFieldXIBViewController.m
3 | // JVFloatLabeledTextField
4 | //
5 | // Created by Jared Verdi on 4/2/16.
6 | // Copyright © 2016 Jared Verdi. All rights reserved.
7 | //
8 |
9 | #import "JVFloatLabeledTextFieldXIBViewController.h"
10 |
11 | @interface JVFloatLabeledTextFieldXIBViewController ()
12 |
13 | @end
14 |
15 | @implementation JVFloatLabeledTextFieldXIBViewController
16 |
17 | - (void)viewDidLoad {
18 | [super viewDidLoad];
19 | // Do any additional setup after loading the view from its nib.
20 | }
21 |
22 | - (void)didReceiveMemoryWarning {
23 | [super didReceiveMemoryWarning];
24 | // Dispose of any resources that can be recreated.
25 | }
26 |
27 | /*
28 | #pragma mark - Navigation
29 |
30 | // In a storyboard-based application, you will often want to do a little preparation before navigation
31 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
32 | // Get the new view controller using [segue destinationViewController].
33 | // Pass the selected object to the new view controller.
34 | }
35 | */
36 |
37 | @end
38 |
--------------------------------------------------------------------------------
/JVFloatLabeledTextField/JVFloatLabeledTextField-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | ${PRODUCT_NAME}
9 | CFBundleExecutable
10 | ${EXECUTABLE_NAME}
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | ${PRODUCT_NAME}
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1.0
25 | LSRequiresIPhoneOS
26 |
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/JVFloatLabeledTextField.xcodeproj/xcuserdata/david.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | JVFloatLabeledText.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 1
11 |
12 | JVFloatLabeledTextField.xcscheme_^#shared#^_
13 |
14 | orderHint
15 | 0
16 |
17 |
18 | SuppressBuildableAutocreation
19 |
20 | 639EABAE1B0B5D6C001DD7B5
21 |
22 | primary
23 |
24 |
25 | 639EABB81B0B5D6C001DD7B5
26 |
27 | primary
28 |
29 |
30 | 639EABD41B0B5E6F001DD7B5
31 |
32 | primary
33 |
34 |
35 | 639EABDE1B0B5E6F001DD7B5
36 |
37 | primary
38 |
39 |
40 | 7F394932199DE5E10069C867
41 |
42 | primary
43 |
44 |
45 | 7F50335517FA7B0A0026FB7F
46 |
47 | primary
48 |
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/JVFloatLabeledTextField/SPMHeaders/JVFloatLabeledTextField.h:
--------------------------------------------------------------------------------
1 | //
2 | // JVFloatLabeledTextField.h
3 | // JVFloatLabeledTextField
4 | //
5 | // The MIT License (MIT)
6 | //
7 | // Copyright (c) 2013-2015 Jared Verdi
8 | // Original Concept by Matt D. Smith
9 | // http://dribbble.com/shots/1254439--GIF-Mobile-Form-Interaction?list=users
10 | //
11 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
12 | // this software and associated documentation files (the "Software"), to deal in
13 | // the Software without restriction, including without limitation the rights to
14 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
15 | // the Software, and to permit persons to whom the Software is furnished to do so,
16 | // subject to the following conditions:
17 | //
18 | // The above copyright notice and this permission notice shall be included in all
19 | // copies or substantial portions of the Software.
20 | //
21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
23 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
24 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
25 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
26 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 |
28 | #import "JVFloatLabeledTextField-Interface.h"
29 | #import "JVFloatLabeledTextView.h"
30 |
--------------------------------------------------------------------------------
/JVFloatLabeledTextField/JVFloatLabeledTextFieldViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // JVFloatLabeledTextFieldViewController.h
3 | // JVFloatLabeledTextField
4 | //
5 | // The MIT License (MIT)
6 | //
7 | // Copyright (c) 2013-2015 Jared Verdi
8 | // Original Concept by Matt D. Smith
9 | // http://dribbble.com/shots/1254439--GIF-Mobile-Form-Interaction?list=users
10 | //
11 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
12 | // this software and associated documentation files (the "Software"), to deal in
13 | // the Software without restriction, including without limitation the rights to
14 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
15 | // the Software, and to permit persons to whom the Software is furnished to do so,
16 | // subject to the following conditions:
17 | //
18 | // The above copyright notice and this permission notice shall be included in all
19 | // copies or substantial portions of the Software.
20 | //
21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
23 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
24 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
25 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
26 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 |
28 | #import
29 |
30 | @interface JVFloatLabeledTextFieldViewController : UIViewController
31 |
32 | @end
33 |
--------------------------------------------------------------------------------
/JVFloatLabeledTextField/JVAppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // JVAppDelegate.h
3 | // JVFloatLabeledTextField
4 | //
5 | // The MIT License (MIT)
6 | //
7 | // Copyright (c) 2013-2015 Jared Verdi
8 | // Original Concept by Matt D. Smith
9 | // http://dribbble.com/shots/1254439--GIF-Mobile-Form-Interaction?list=users
10 | //
11 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
12 | // this software and associated documentation files (the "Software"), to deal in
13 | // the Software without restriction, including without limitation the rights to
14 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
15 | // the Software, and to permit persons to whom the Software is furnished to do so,
16 | // subject to the following conditions:
17 | //
18 | // The above copyright notice and this permission notice shall be included in all
19 | // copies or substantial portions of the Software.
20 | //
21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
23 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
24 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
25 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
26 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 |
28 | #import
29 |
30 | @interface JVAppDelegate : UIResponder
31 |
32 | @property (strong, nonatomic) UIWindow *window;
33 |
34 | @end
35 |
--------------------------------------------------------------------------------
/JVFloatLabeledTextField/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // JVFloatLabeledTextField
4 | //
5 | // The MIT License (MIT)
6 | //
7 | // Copyright (c) 2013-2015 Jared Verdi
8 | // Original Concept by Matt D. Smith
9 | // http://dribbble.com/shots/1254439--GIF-Mobile-Form-Interaction?list=users
10 | //
11 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
12 | // this software and associated documentation files (the "Software"), to deal in
13 | // the Software without restriction, including without limitation the rights to
14 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
15 | // the Software, and to permit persons to whom the Software is furnished to do so,
16 | // subject to the following conditions:
17 | //
18 | // The above copyright notice and this permission notice shall be included in all
19 | // copies or substantial portions of the Software.
20 | //
21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
23 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
24 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
25 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
26 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 |
28 | #import
29 |
30 | #import "JVAppDelegate.h"
31 |
32 | int main(int argc, char * argv[])
33 | {
34 | @autoreleasepool {
35 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([JVAppDelegate class]));
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/JVFloatLabeledTextField/JVFloatLabeledText.h:
--------------------------------------------------------------------------------
1 | //
2 | // JVFloatLabeledText.h
3 | // JVFloatLabeledTextField
4 | //
5 | // The MIT License (MIT)
6 | //
7 | // Copyright (c) 2013-2015 Jared Verdi
8 | // Original Concept by Matt D. Smith
9 | // http://dribbble.com/shots/1254439--GIF-Mobile-Form-Interaction?list=users
10 | //
11 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
12 | // this software and associated documentation files (the "Software"), to deal in
13 | // the Software without restriction, including without limitation the rights to
14 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
15 | // the Software, and to permit persons to whom the Software is furnished to do so,
16 | // subject to the following conditions:
17 | //
18 | // The above copyright notice and this permission notice shall be included in all
19 | // copies or substantial portions of the Software.
20 | //
21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
23 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
24 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
25 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
26 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 |
28 | #import
29 |
30 | //! Project version number for JVFloatLabeledText.
31 | FOUNDATION_EXPORT double JVFloatLabeledTextVersionNumber;
32 |
33 | //! Project version string for JVFloatLabeledTextField.
34 | FOUNDATION_EXPORT const unsigned char JVFloatLabeledTextVersionString[];
35 |
36 | #import
37 | #import
38 |
--------------------------------------------------------------------------------
/JVFloatLabeledTextField/JVFloatLabeledTextField/NSString+TextDirectionality.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSString+TextDirectionality.h
3 | // JVFloatLabeledTextField
4 | //
5 | // The MIT License (MIT)
6 | //
7 | // Copyright (c) 2013-2015 Jared Verdi
8 | // Original Concept by Matt D. Smith
9 | // http://dribbble.com/shots/1254439--GIF-Mobile-Form-Interaction?list=users
10 | //
11 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
12 | // this software and associated documentation files (the "Software"), to deal in
13 | // the Software without restriction, including without limitation the rights to
14 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
15 | // the Software, and to permit persons to whom the Software is furnished to do so,
16 | // subject to the following conditions:
17 | //
18 | // The above copyright notice and this permission notice shall be included in all
19 | // copies or substantial portions of the Software.
20 | //
21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
23 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
24 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
25 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
26 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 |
28 | // Based on a Stack Overflow answer http://stackoverflow.com/a/13697277/900251
29 |
30 | #import
31 |
32 | /**
33 | * `JVTextDirection` indicates text directionality, such as Neutral, Left-to-Right, and Right-to-Left
34 | */
35 | typedef NS_ENUM(NSUInteger, JVTextDirection) {
36 | /**
37 | * `JVTextDirectionNeutral` indicates text with no directionality
38 | */
39 | JVTextDirectionNeutral = 0,
40 |
41 | /**
42 | * `JVTextDirectionLeftToRight` indicates text left-to-right directionality
43 | */
44 | JVTextDirectionLeftToRight,
45 |
46 | /**
47 | * `JVTextDirectionRightToLeft` indicates text right-to-left directionality
48 | */
49 | JVTextDirectionRightToLeft,
50 | };
51 |
52 | /**
53 | * `NSString (TextDirectionality)` is an NSString category that is used to infer the text directionality of a string.
54 | */
55 | @interface NSString (TextDirectionality)
56 |
57 | /**
58 | * Inspects the string and makes a best guess at text directionality.
59 | *
60 | * @return the inferred text directionality of this string.
61 | */
62 | - (JVTextDirection)getBaseDirection;
63 |
64 | @end
65 |
--------------------------------------------------------------------------------
/JVFloatLabeledTextField/JVAppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // JVAppDelegate.m
3 | // JVFloatLabeledTextField
4 | //
5 | // The MIT License (MIT)
6 | //
7 | // Copyright (c) 2013-2015 Jared Verdi
8 | // Original Concept by Matt D. Smith
9 | // http://dribbble.com/shots/1254439--GIF-Mobile-Form-Interaction?list=users
10 | //
11 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
12 | // this software and associated documentation files (the "Software"), to deal in
13 | // the Software without restriction, including without limitation the rights to
14 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
15 | // the Software, and to permit persons to whom the Software is furnished to do so,
16 | // subject to the following conditions:
17 | //
18 | // The above copyright notice and this permission notice shall be included in all
19 | // copies or substantial portions of the Software.
20 | //
21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
23 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
24 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
25 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
26 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 |
28 | #define TEST_XIB_CONFIGURATION 0
29 |
30 | #import "JVAppDelegate.h"
31 |
32 | #if TEST_XIB_CONFIGURATION
33 | #import "JVFloatLabeledTextFieldXIBViewController.h"
34 | #else
35 | #import "JVFloatLabeledTextFieldViewController.h"
36 | #endif
37 |
38 | @implementation JVAppDelegate
39 |
40 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
41 | {
42 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
43 | // Override point for customization after application launch.
44 | self.window.backgroundColor = [UIColor whiteColor];
45 |
46 | #if TEST_XIB_CONFIGURATION
47 | JVFloatLabeledTextFieldXIBViewController *viewController = [JVFloatLabeledTextFieldXIBViewController new];
48 | #else
49 | JVFloatLabeledTextFieldViewController *viewController = [JVFloatLabeledTextFieldViewController new];
50 | #endif
51 |
52 | UINavigationController *navigationController =
53 | [[UINavigationController alloc] initWithRootViewController:viewController];
54 |
55 | self.window.rootViewController = navigationController;
56 | [self.window makeKeyAndVisible];
57 | return YES;
58 | }
59 |
60 | - (void)applicationWillResignActive:(UIApplication *)application
61 | {
62 | }
63 |
64 | - (void)applicationDidEnterBackground:(UIApplication *)application
65 | {
66 | }
67 |
68 | - (void)applicationWillEnterForeground:(UIApplication *)application
69 | {
70 | }
71 |
72 | - (void)applicationDidBecomeActive:(UIApplication *)application
73 | {
74 | }
75 |
76 | - (void)applicationWillTerminate:(UIApplication *)application
77 | {
78 | }
79 |
80 | @end
81 |
--------------------------------------------------------------------------------
/JVFloatLabeledTextField.xcodeproj/xcshareddata/xcschemes/JVFloatLabeledText.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
31 |
32 |
33 |
34 |
35 |
36 |
47 |
48 |
54 |
55 |
56 |
57 |
58 |
59 |
65 |
66 |
72 |
73 |
74 |
75 |
77 |
78 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/JVFloatLabeledTextFieldTests/JVFloatLabeledTextViewTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // JVFloatLabeledTextViewTests.m
3 | // JVFloatLabeledTextField
4 | //
5 | // The MIT License (MIT)
6 | //
7 | // Copyright (c) 2013-2015 Jared Verdi
8 | // Original Concept by Matt D. Smith
9 | // http://dribbble.com/shots/1254439--GIF-Mobile-Form-Interaction?list=users
10 | //
11 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
12 | // this software and associated documentation files (the "Software"), to deal in
13 | // the Software without restriction, including without limitation the rights to
14 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
15 | // the Software, and to permit persons to whom the Software is furnished to do so,
16 | // subject to the following conditions:
17 | //
18 | // The above copyright notice and this permission notice shall be included in all
19 | // copies or substantial portions of the Software.
20 | //
21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
23 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
24 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
25 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
26 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 |
28 | #import
29 | #import "JVFloatLabeledTextView.h"
30 |
31 | @interface JVFloatLabeledTextViewTests : XCTestCase
32 | @property (nonatomic, strong) JVFloatLabeledTextView * testView;
33 | @end
34 |
35 | @implementation JVFloatLabeledTextViewTests
36 |
37 | - (void)setUp
38 | {
39 | [super setUp];
40 |
41 | self.testView = [[JVFloatLabeledTextView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 100.0f, 44.0f)];
42 | self.testView.placeholder = @"Test";
43 | }
44 |
45 | - (void)tearDown
46 | {
47 | [super tearDown];
48 | }
49 |
50 | - (void)testDefaults
51 | {
52 | XCTAssertEqual(self.testView.placeholderLabel.text, self.testView.placeholder);
53 | XCTAssertEqual(self.testView.floatingLabelYPadding, 0.0f);
54 | XCTAssertEqual(self.testView.placeholderYPadding, 0.0f);
55 | XCTAssertNotNil(self.testView.floatingLabelFont);
56 | XCTAssertEqual(self.testView.floatingLabelFont, self.testView.floatingLabel.font);
57 | XCTAssert(CGColorEqualToColor(self.testView.floatingLabelTextColor.CGColor,
58 | [UIColor grayColor].CGColor));
59 | XCTAssert(CGColorEqualToColor(self.testView.floatingLabelTextColor.CGColor,
60 | self.testView.floatingLabel.textColor.CGColor));
61 | XCTAssertNil(self.testView.floatingLabelActiveTextColor);
62 | XCTAssertEqual(self.testView.floatingLabelShouldLockToTop, 1);
63 | XCTAssert(CGColorEqualToColor(self.testView.placeholderTextColor.CGColor,
64 | [[UIColor lightGrayColor] colorWithAlphaComponent:0.65f].CGColor));
65 | XCTAssertEqual(self.testView.animateEvenIfNotFirstResponder, 0);
66 | XCTAssertEqual(self.testView.floatingLabelShowAnimationDuration, 0.3f);
67 | XCTAssertEqual(self.testView.floatingLabelHideAnimationDuration, 0.3f);
68 | }
69 |
70 | - (void)testHorizontalOffset
71 | {
72 | self.testView.floatingLabelXPadding = -100;
73 | [self.testView layoutSubviews];
74 | XCTAssertEqual(self.testView.floatingLabel.frame.origin.x, -100);
75 | }
76 |
77 | @end
78 |
--------------------------------------------------------------------------------
/JVFloatLabeledTextField.xcodeproj/xcshareddata/xcschemes/JVFloatLabeledTextFieldTests.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
38 |
39 |
45 |
46 |
48 |
54 |
55 |
56 |
57 |
58 |
64 |
65 |
66 |
67 |
68 |
69 |
80 |
81 |
82 |
83 |
89 |
90 |
92 |
93 |
96 |
97 |
98 |
--------------------------------------------------------------------------------
/JVFloatLabeledTextFieldTests/JVFloatLabeledTextFieldTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // JVFloatLabeledTextFieldTests.m
3 | // JVFloatLabeledTextFieldTests
4 | //
5 | // The MIT License (MIT)
6 | //
7 | // Copyright (c) 2013-2015 Jared Verdi
8 | // Original Concept by Matt D. Smith
9 | // http://dribbble.com/shots/1254439--GIF-Mobile-Form-Interaction?list=users
10 | //
11 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
12 | // this software and associated documentation files (the "Software"), to deal in
13 | // the Software without restriction, including without limitation the rights to
14 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
15 | // the Software, and to permit persons to whom the Software is furnished to do so,
16 | // subject to the following conditions:
17 | //
18 | // The above copyright notice and this permission notice shall be included in all
19 | // copies or substantial portions of the Software.
20 | //
21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
23 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
24 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
25 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
26 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 |
28 | #import
29 | #import "JVFloatLabeledTextField.h"
30 |
31 | @interface JVFloatLabeledTextFieldTests : XCTestCase
32 | @property (nonatomic, strong) JVFloatLabeledTextField * testField;
33 | @end
34 |
35 | @implementation JVFloatLabeledTextFieldTests
36 |
37 | - (void)setUp
38 | {
39 | [super setUp];
40 |
41 | self.testField = [[JVFloatLabeledTextField alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 100.0f, 44.0f)];
42 | self.testField.placeholder = @"Test";
43 | }
44 |
45 | - (void)tearDown
46 | {
47 | [super tearDown];
48 | }
49 |
50 | - (void)testDefaults
51 | {
52 | XCTAssertEqual(self.testField.floatingLabelYPadding, 0.0f);
53 | XCTAssertEqual(self.testField.placeholderYPadding, 0.0f);
54 | XCTAssertNotNil(self.testField.floatingLabelFont);
55 | XCTAssertEqual(self.testField.floatingLabelFont, self.testField.floatingLabel.font);
56 | XCTAssert(CGColorEqualToColor(self.testField.floatingLabelTextColor.CGColor,
57 | [UIColor grayColor].CGColor));
58 | XCTAssert(CGColorEqualToColor(self.testField.floatingLabelTextColor.CGColor,
59 | self.testField.floatingLabel.textColor.CGColor));
60 | XCTAssertNil(self.testField.floatingLabelActiveTextColor);
61 | XCTAssertEqual(self.testField.animateEvenIfNotFirstResponder, 0);
62 | XCTAssertEqual(self.testField.floatingLabelShowAnimationDuration, 0.3f);
63 | XCTAssertEqual(self.testField.floatingLabelHideAnimationDuration, 0.3f);
64 | }
65 |
66 | - (void)testHorizontalOffset
67 | {
68 | self.testField.floatingLabelXPadding = -100;
69 | [self.testField layoutSubviews];
70 | XCTAssertEqual(self.testField.floatingLabel.frame.origin.x, -100);
71 | }
72 |
73 | - (void)testKeepBaseline
74 | {
75 | self.testField.keepBaseline = 1;
76 |
77 | CGRect textRectInitial = [self.testField textRectForBounds:self.testField.bounds];
78 | CGRect editRectInitial = [self.testField editingRectForBounds:self.testField.bounds];
79 | CGRect clearRectInitial = [self.testField clearButtonRectForBounds:self.testField.bounds];
80 |
81 | self.testField.text = @"hello world!";
82 |
83 | CGRect textRectFinal = [self.testField textRectForBounds:self.testField.bounds];
84 | CGRect editRectFinal = [self.testField editingRectForBounds:self.testField.bounds];
85 | CGRect clearRectFinal = [self.testField clearButtonRectForBounds:self.testField.bounds];
86 |
87 | XCTAssert(CGRectEqualToRect(textRectInitial, textRectFinal));
88 | XCTAssert(CGRectEqualToRect(editRectInitial, editRectFinal));
89 | XCTAssert(CGRectEqualToRect(clearRectInitial, clearRectFinal));
90 | }
91 |
92 | -(void)testIntrinsicContentHeight
93 | {
94 | self.testField.text = @"foo";
95 | CGFloat firstHeight = self.testField.intrinsicContentSize.height;
96 |
97 | self.testField.text = @"bar";
98 | CGFloat secondHeight = self.testField.intrinsicContentSize.height;
99 |
100 | XCTAssertEqual(firstHeight, secondHeight);
101 | }
102 |
103 | @end
104 |
--------------------------------------------------------------------------------
/JVFloatLabeledTextField.xcodeproj/xcshareddata/xcschemes/JVFloatLabeledTextField.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
38 |
39 |
45 |
46 |
48 |
54 |
55 |
56 |
57 |
58 |
64 |
65 |
66 |
67 |
68 |
69 |
80 |
82 |
88 |
89 |
90 |
91 |
92 |
93 |
99 |
101 |
107 |
108 |
109 |
110 |
112 |
113 |
116 |
117 |
118 |
--------------------------------------------------------------------------------
/JVFloatLabeledTextField/JVFloatLabeledTextFieldXIBViewController.xib:
--------------------------------------------------------------------------------
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 |
36 |
37 |
38 |
39 |
40 |
41 |
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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | JVFloatLabeledTextField
2 | =======================
3 | [](https://travis-ci.org/jverdi/JVFloatLabeledTextField)
4 | [](#carthage)
5 | [](http://cocoadocs.org/docsets/JVFloatLabeledTextField/)
6 | [](http://cocoadocs.org/docsets/JVFloatLabeledTextField/)
7 | [](http://jaredverdi.mit-license.org)
8 | [](https://github.com/jverdi/JVFloatLabeledTextField)
9 |
10 | `JVFloatLabeledTextField` is the first implementation of a UX pattern that has come to be known the **"Float Label Pattern"**.
11 |
12 | Due to space constraints on mobile devices, it is common to rely solely on placeholders as a means to label fields.
13 | This presents a UX problem, in that, once the user begins to fill out a form, no labels are present.
14 |
15 | This UI component library, which includes both a `UITextField` and `UITextView` subclass, aims to improve the user experience by having placeholders transition into floating labels that hover above the fields after they are populated with text.
16 |
17 | Credits for the concept to Matt D. Smith ([@mds](https://twitter.com/mds)), and his [original design](https://dribbble.com/shots/1254439--GIF-Mobile-Form-Interaction?list=users):
18 |
19 | 
20 |
21 |
22 | The component is officially supported for iOS 9 and greater.
23 |
24 |
25 | Getting started via CocoaPods
26 | =============================
27 | ```
28 | sudo gem install cocoapods
29 | ```
30 |
31 | Create a ```Podfile``` in your project directory:
32 | ```
33 | pod init
34 | ```
35 |
36 | Add the following to your ```Podfile``` project's target:
37 | ```
38 | pod 'JVFloatLabeledTextField'
39 | ```
40 |
41 | Then run CocoaPods with ```pod install```.
42 |
43 | Finally, include ```JVFloatLabeledTextField.h``` and ```JVFloatLabeledTextView.h``` in your project.
44 |
45 |
46 | Getting started via Carthage
47 | ============================
48 | ```
49 | brew update
50 | brew install carthage
51 | ```
52 |
53 | Create a ```Cartfile``` in your project directory that contains:
54 | ```
55 | github "jverdi/JVFloatLabeledTextField"
56 | ```
57 |
58 | Then run carthage with ```carthage update``` and add ```JVFloatLabeledText.framework``` to your project from the ```Carthage/Build/iOS``` directory.
59 |
60 | Finally, include ```JVFloatLabeledText.h``` in your project:
61 | ```
62 | #import
63 | ```
64 |
65 | Getting started via SPM (Xcode 11+)
66 | ============================
67 |
68 | Click `File` -> `Swift Packages` -> `Add Package Dependency`, enter [JVFloatLabeledText repo's URL](https://github.com/jverdi/JVFloatLabeledTextField).
69 |
70 | After select the package, you can choose the dependency type (tagged version, branch or commit). Then Xcode will setup all the stuff for you.
71 |
72 | If you're a framework author and use JVFloatLabeledTextField as a dependency, update your `Package.swift` file:
73 |
74 | ```swift
75 | let package = Package(
76 | dependencies: [
77 | .package(url: "https://github.com/jverdi/JVFloatLabeledTextField", from: "1.2.2")
78 | ],
79 | )
80 | ```
81 |
82 | Additional References
83 | =======================
84 | [How the Float Label Pattern Started](http://mds.is/float-label-pattern/) - Matt D. Smith
85 | [Float Label Pattern](http://bradfrost.com/blog/post/float-label-pattern/) - Brad Frost
86 | [Material Design - Floating Labels](http://www.google.com/design/spec/components/text-fields.html#text-fields-floating-labels) - Google
87 |
88 | Ports and Alternate Implementations
89 | =====================================
90 | [Android](https://github.com/wrapp/floatlabelededittext) - Henrik Sandström
91 | [Android](https://github.com/weddingparty/AndroidFloatLabel) - Kaushik Gopal
92 | [Android](https://github.com/KevinJ90825/FloatLabelPattern) - Kevin Johnson
93 | [Xamarin.iOS](https://github.com/gshackles/FloatLabeledEntry) - Greg Shackles
94 | [Xamarin.Android](https://github.com/Johan-dutoit/JVFloatSharp) - Johan du Toit
95 | [CSS](http://snook.ca/archives/html_and_css/floated-label-pattern-css) Jonathan Snook
96 | [JQuery / Zepto.js](https://github.com/maman/JVFloat.js) - Achmad Mahardi
97 | [JQuery](https://github.com/m10l/FloatLabel.js) - Mike Mitchell
98 | [AngularJS](https://github.com/dmackerman/angular-better-placeholders) - Dave Ackerman
99 | [Bootstrap plugin](https://github.com/fauxparse/bootstrap-floating-labels) - Matt Powell
100 | [JavaFX](https://github.com/andytill/floaty-field) - Andy Till
101 | [Swift](https://github.com/dirkfabisch/B68FloatingLabelTextField) - Dirk Fabisch
102 | [Swift](https://github.com/FahimF/FloatLabelFields) - Fahim Farook
103 | [Swift](https://github.com/kNeerajPro/CGFLoatingUIKit) - Neeraj Kumar
104 | [Swift](https://github.com/varshylmobile/VMFloatLabel) - Jimmy Jose
105 | [Swift](https://github.com/Skyscanner/SkyFloatingLabelTextField) - Skyscanner (Daniel Langh, Gergely Orosz, Raimon Lapuente)
106 | [ObjC](https://github.com/ArtSabintsev/UIFloatLabelTextField) - Arthur Ariel Sabintsev
107 | [ObjC](https://github.com/iwasrobbed/RPFloatingPlaceholders) - Rob Phillips
108 | [4D](http://forums.4d.fr/Post/EN/15995553/0/0/) - Maurice Inzirillo
109 | [Appcelerator Titanium](https://github.com/TheSmiths-Widgets/ts.floatlabelfield) - The Smiths
110 | [B4i](https://www.b4x.com/android/forum/threads/floatlabelededittext-iui8.64096/#post-405516) - Erel Uziel
111 |
112 |
113 | Added a port? Let me know - [@jverdi](https://twitter.com/jverdi)
114 |
--------------------------------------------------------------------------------
/JVFloatLabeledTextField/JVFloatLabeledTextField/JVFloatLabeledTextView.h:
--------------------------------------------------------------------------------
1 | //
2 | // JVFloatLabeledTextView.h
3 | // JVFloatLabeledTextField
4 | //
5 | // The MIT License (MIT)
6 | //
7 | // Copyright (c) 2013-2015 Jared Verdi
8 | // Original Concept by Matt D. Smith
9 | // http://dribbble.com/shots/1254439--GIF-Mobile-Form-Interaction?list=users
10 | //
11 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
12 | // this software and associated documentation files (the "Software"), to deal in
13 | // the Software without restriction, including without limitation the rights to
14 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
15 | // the Software, and to permit persons to whom the Software is furnished to do so,
16 | // subject to the following conditions:
17 | //
18 | // The above copyright notice and this permission notice shall be included in all
19 | // copies or substantial portions of the Software.
20 | //
21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
23 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
24 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
25 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
26 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 |
28 | #import
29 |
30 | /**
31 | * `JVFloatLabeledTextView` is a `UITextView` subclass that implements the "Float Label Pattern".
32 | *
33 | * Due to space constraints on mobile devices, it is common to rely solely on placeholders as a means to label fields.
34 | * This presents a UX problem, in that, once the user begins to fill out a form, no labels are present.
35 | *
36 | * `JVFloatLabeledTextView` aims to improve the user experience by having placeholders transition into "floating labels"
37 | * that hover above the text view after it is populated with text.
38 | *
39 | * JVFloatLabeledTextView supports iOS 9+.
40 | *
41 | * Credits for the concept to Matt D. Smith (@mds), and his original design: http://mattdsmith.com/float-label-pattern/
42 | */
43 | IB_DESIGNABLE
44 | @interface JVFloatLabeledTextView : UITextView
45 |
46 | /**
47 | * The placeholder string to be shown in the text view when no other text is present.
48 | */
49 | @property (nonatomic, copy) IBInspectable NSString * placeholder;
50 |
51 | /**
52 | * Read-only access to the placeholder label.
53 | */
54 | @property (nonatomic, strong, readonly) UILabel * placeholderLabel;
55 |
56 | /**
57 | * Read-only access to the floating label.
58 | */
59 | @property (nonatomic, strong, readonly) UILabel * floatingLabel;
60 |
61 | /**
62 | * Padding to be applied to the y coordinate of the floating label upon presentation.
63 | */
64 | @property (nonatomic) IBInspectable CGFloat floatingLabelYPadding;
65 |
66 | /**
67 | * Padding to be applied to the x coordinate of the floating label upon presentation.
68 | */
69 | @property (nonatomic) IBInspectable CGFloat floatingLabelXPadding;
70 |
71 | /**
72 | * Padding to be applied to the y coordinate of the placeholder.
73 | */
74 | @property (nonatomic) IBInspectable CGFloat placeholderYPadding;
75 |
76 | /**
77 | * Font to be applied to the floating label. Defaults to `[UIFont boldSystemFontOfSize:12.0f]`.
78 | * Provided for the convenience of using as an appearance proxy.
79 | */
80 | @property (nonatomic, strong) UIFont * floatingLabelFont;
81 |
82 | /**
83 | * Text color to be applied to the floating label while the text view is not a first responder.
84 | * Defaults to `[UIColor grayColor]`.
85 | * Provided for the convenience of using as an appearance proxy.
86 | */
87 | @property (nonatomic, strong) IBInspectable UIColor * floatingLabelTextColor;
88 |
89 | /**
90 | * Text color to be applied to the floating label while the text view is a first responder.
91 | * Tint color is used by default if an `floatingLabelActiveTextColor` is not provided.
92 | */
93 | @property (nonatomic, strong) IBInspectable UIColor * floatingLabelActiveTextColor;
94 |
95 | /**
96 | * Indicates whether the floating label should lock to the top of the text view, or scroll away with text when the text
97 | * view is scrollable. By default, floating labels will lock to the top of the text view and their background color will
98 | * be set to the text view's background color
99 | * Note that this works best when floating labels have a non-clear background color.
100 | */
101 | @property (nonatomic, assign) IBInspectable BOOL floatingLabelShouldLockToTop;
102 |
103 | /**
104 | * Text color to be applied to the placeholder.
105 | * Defaults to `[[UIColor lightGrayColor] colorWithAlphaComponent:0.65f]`.
106 | */
107 | @property (nonatomic, strong) IBInspectable UIColor * placeholderTextColor;
108 |
109 | /**
110 | * Indicates whether the floating label's appearance should be animated regardless of first responder status.
111 | * By default, animation only occurs if the text field is a first responder.
112 | */
113 | @property (nonatomic, assign) IBInspectable BOOL animateEvenIfNotFirstResponder;
114 |
115 | /**
116 | * Duration of the animation when showing the floating label.
117 | * Defaults to 0.3 seconds.
118 | */
119 | @property (nonatomic, assign) NSTimeInterval floatingLabelShowAnimationDuration UI_APPEARANCE_SELECTOR;
120 |
121 | /**
122 | * Duration of the animation when hiding the floating label.
123 | * Defaults to 0.3 seconds.
124 | */
125 | @property (nonatomic, assign) NSTimeInterval floatingLabelHideAnimationDuration UI_APPEARANCE_SELECTOR;
126 |
127 | /**
128 | * Force floating label to be always visible
129 | * Defaults to NO
130 | */
131 | @property (nonatomic, assign) BOOL alwaysShowFloatingLabel;
132 |
133 | /**
134 | * Top value for textContainerInset
135 | * Change this value if you need more padding between text input and floating label
136 | */
137 | @property (nonatomic) CGFloat startingTextContainerInsetTop;
138 |
139 | /**
140 | * Sets the placeholder and the floating title
141 | *
142 | * @param placeholder The string that to be shown in the text view when no other text is present.
143 | * @param floatingTitle The string to be shown above the text view once it has been populated with text by the user.
144 | */
145 | - (void)setPlaceholder:(NSString *)placeholder floatingTitle:(NSString *)floatingTitle;
146 |
147 | @end
148 |
--------------------------------------------------------------------------------
/JVFloatLabeledTextField/JVFloatLabeledTextField/JVFloatLabeledTextField.h:
--------------------------------------------------------------------------------
1 | //
2 | // JVFloatLabeledTextField.h
3 | // JVFloatLabeledTextField
4 | //
5 | // The MIT License (MIT)
6 | //
7 | // Copyright (c) 2013-2015 Jared Verdi
8 | // Original Concept by Matt D. Smith
9 | // http://dribbble.com/shots/1254439--GIF-Mobile-Form-Interaction?list=users
10 | //
11 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
12 | // this software and associated documentation files (the "Software"), to deal in
13 | // the Software without restriction, including without limitation the rights to
14 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
15 | // the Software, and to permit persons to whom the Software is furnished to do so,
16 | // subject to the following conditions:
17 | //
18 | // The above copyright notice and this permission notice shall be included in all
19 | // copies or substantial portions of the Software.
20 | //
21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
23 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
24 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
25 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
26 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 |
28 | #import
29 |
30 | /**
31 | * `JVFloatLabeledTextField` is a `UITextField` subclass that implements the "Float Label Pattern".
32 | *
33 | * Due to space constraints on mobile devices, it is common to rely solely on placeholders as a means to label fields.
34 | * This presents a UX problem, in that, once the user begins to fill out a form, no labels are present.
35 | *
36 | * `JVFloatLabeledTextField` aims to improve the user experience by having placeholders transition into
37 | * "floating labels" that hover above the text field after it is populated with text.
38 | *
39 | * JVFloatLabeledTextField supports iOS 9+.
40 | *
41 | * Credits for the concept to Matt D. Smith (@mds), and his original design: http://mattdsmith.com/float-label-pattern/
42 | */
43 | IB_DESIGNABLE
44 | @interface JVFloatLabeledTextField : UITextField
45 |
46 | /**
47 | * Read-only access to the floating label.
48 | */
49 | @property (nonatomic, strong, readonly) UILabel * floatingLabel;
50 |
51 | /**
52 | * Padding to be applied to the y coordinate of the floating label upon presentation.
53 | * Defaults to zero.
54 | */
55 | @property (nonatomic) IBInspectable CGFloat floatingLabelYPadding;
56 |
57 | /**
58 | * Padding to be applied to the x coordinate of the floating label upon presentation.
59 | * Defaults to zero
60 | */
61 | @property (nonatomic) IBInspectable CGFloat floatingLabelXPadding;
62 |
63 | /**
64 | * Ratio by which to modify the font size of the floating label.
65 | * Defaults to 70
66 | */
67 | @property (nonatomic) IBInspectable CGFloat floatingLabelReductionRatio;
68 |
69 | /**
70 | * Padding to be applied to the y coordinate of the placeholder.
71 | * Defaults to zero.
72 | */
73 | @property (nonatomic) IBInspectable CGFloat placeholderYPadding;
74 |
75 | /**
76 | * Font to be applied to the floating label.
77 | * Defaults to the first applicable of the following:
78 | * - the custom specified attributed placeholder font at 70% of its size
79 | * - the custom specified textField font at 70% of its size
80 | */
81 | @property (nonatomic, strong) UIFont * floatingLabelFont;
82 |
83 | /**
84 | * Text color to be applied to the floating label.
85 | * Defaults to `[UIColor grayColor]`.
86 | */
87 | @property (nonatomic, strong) IBInspectable UIColor * floatingLabelTextColor;
88 |
89 | /**
90 | * Text color to be applied to the floating label while the field is a first responder.
91 | * Tint color is used by default if an `floatingLabelActiveTextColor` is not provided.
92 | */
93 | @property (nonatomic, strong) IBInspectable UIColor * floatingLabelActiveTextColor;
94 |
95 | /**
96 | * Indicates whether the floating label's appearance should be animated regardless of first responder status.
97 | * By default, animation only occurs if the text field is a first responder.
98 | */
99 | @property (nonatomic, assign) IBInspectable BOOL animateEvenIfNotFirstResponder;
100 |
101 | /**
102 | * Duration of the animation when showing the floating label.
103 | * Defaults to 0.3 seconds.
104 | */
105 | @property (nonatomic, assign) NSTimeInterval floatingLabelShowAnimationDuration;
106 |
107 | /**
108 | * Duration of the animation when hiding the floating label.
109 | * Defaults to 0.3 seconds.
110 | */
111 | @property (nonatomic, assign) NSTimeInterval floatingLabelHideAnimationDuration;
112 |
113 | /**
114 | * Indicates whether the clearButton position is adjusted to align with the text
115 | * Defaults to 1.
116 | */
117 | @property (nonatomic, assign) IBInspectable BOOL adjustsClearButtonRect;
118 |
119 | /**
120 | * Indicates whether or not to drop the baseline when entering text. Setting to YES (not the default) means the standard greyed-out placeholder will be aligned with the entered text
121 | * Defaults to NO (standard placeholder will be above whatever text is entered)
122 | */
123 | @property (nonatomic, assign) IBInspectable BOOL keepBaseline;
124 |
125 | /**
126 | * Force floating label to be always visible
127 | * Defaults to NO
128 | */
129 | @property (nonatomic, assign) BOOL alwaysShowFloatingLabel;
130 |
131 | /**
132 | * Color of the placeholder
133 | */
134 | @property (nonatomic, strong) IBInspectable UIColor * placeholderColor;
135 |
136 | /**
137 | * Sets the placeholder and the floating title
138 | *
139 | * @param placeholder The string that to be shown in the text field when no other text is present.
140 | * @param floatingTitle The string to be shown above the text field once it has been populated with text by the user.
141 | */
142 | - (void)setPlaceholder:(NSString *)placeholder floatingTitle:(NSString *)floatingTitle;
143 |
144 | /**
145 | * Sets the attributed placeholder and the floating title
146 | *
147 | * @param attributedPlaceholder The string that to be shown in the text field when no other text is present.
148 | * @param floatingTitle The string to be shown above the text field once it has been populated with text by the user.
149 | */
150 | - (void)setAttributedPlaceholder:(NSAttributedString *)attributedPlaceholder floatingTitle:(NSString *)floatingTitle;
151 |
152 | @end
153 |
--------------------------------------------------------------------------------
/JVFloatLabeledTextField/JVFloatLabeledTextFieldViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // JVFloatLabeledTextFieldViewController.m
3 | // JVFloatLabeledTextField
4 | //
5 | // The MIT License (MIT)
6 | //
7 | // Copyright (c) 2013-2015 Jared Verdi
8 | // Original Concept by Matt D. Smith
9 | // http://dribbble.com/shots/1254439--GIF-Mobile-Form-Interaction?list=users
10 | //
11 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
12 | // this software and associated documentation files (the "Software"), to deal in
13 | // the Software without restriction, including without limitation the rights to
14 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
15 | // the Software, and to permit persons to whom the Software is furnished to do so,
16 | // subject to the following conditions:
17 | //
18 | // The above copyright notice and this permission notice shall be included in all
19 | // copies or substantial portions of the Software.
20 | //
21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
23 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
24 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
25 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
26 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 |
28 | #import "JVFloatLabeledTextFieldViewController.h"
29 | #import "JVFloatLabeledTextField.h"
30 | #import "JVFloatLabeledTextView.h"
31 |
32 | const static CGFloat kJVFieldHeight = 44.0f;
33 | const static CGFloat kJVFieldHMargin = 10.0f;
34 |
35 | const static CGFloat kJVFieldFontSize = 16.0f;
36 |
37 | const static CGFloat kJVFieldFloatingLabelFontSize = 11.0f;
38 |
39 | @interface JVFloatLabeledTextFieldViewController ()
40 |
41 | @end
42 |
43 | @implementation JVFloatLabeledTextFieldViewController
44 |
45 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
46 | {
47 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
48 | if (self) {
49 | self.title = NSLocalizedString(@"Floating Label Demo", @"");
50 | }
51 | return self;
52 | }
53 |
54 | - (void)viewDidLoad
55 | {
56 | [super viewDidLoad];
57 | // Do any additional setup after loading the view.
58 |
59 | self.edgesForExtendedLayout = UIRectEdgeNone;
60 |
61 | #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
62 | [self.view setTintColor:[UIColor blueColor]];
63 | #endif
64 |
65 | UIColor *floatingLabelColor = [UIColor brownColor];
66 |
67 | JVFloatLabeledTextField *titleField = [[JVFloatLabeledTextField alloc] initWithFrame:CGRectZero];
68 | titleField.font = [UIFont systemFontOfSize:kJVFieldFontSize];
69 | titleField.attributedPlaceholder =
70 | [[NSAttributedString alloc] initWithString:NSLocalizedString(@"Title", @"")
71 | attributes:@{NSForegroundColorAttributeName: [UIColor darkGrayColor]}];
72 | titleField.floatingLabelFont = [UIFont boldSystemFontOfSize:kJVFieldFloatingLabelFontSize];
73 | titleField.floatingLabelTextColor = floatingLabelColor;
74 | titleField.clearButtonMode = UITextFieldViewModeWhileEditing;
75 | [self.view addSubview:titleField];
76 | titleField.translatesAutoresizingMaskIntoConstraints = NO;
77 | titleField.keepBaseline = YES;
78 |
79 | UIView *div1 = [UIView new];
80 | div1.backgroundColor = [[UIColor lightGrayColor] colorWithAlphaComponent:0.3f];
81 | [self.view addSubview:div1];
82 | div1.translatesAutoresizingMaskIntoConstraints = NO;
83 |
84 | JVFloatLabeledTextField *priceField = [[JVFloatLabeledTextField alloc] initWithFrame:CGRectZero];
85 | priceField.font = [UIFont systemFontOfSize:kJVFieldFontSize];
86 | priceField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:NSLocalizedString(@"Price", @"")
87 | attributes:@{NSForegroundColorAttributeName: [UIColor darkGrayColor]}];
88 | priceField.floatingLabelFont = [UIFont boldSystemFontOfSize:kJVFieldFloatingLabelFontSize];
89 | priceField.floatingLabelTextColor = floatingLabelColor;
90 | [self.view addSubview:priceField];
91 | priceField.translatesAutoresizingMaskIntoConstraints = NO;
92 |
93 | UIView *div2 = [UIView new];
94 | div2.backgroundColor = [[UIColor lightGrayColor] colorWithAlphaComponent:0.3f];
95 | [self.view addSubview:div2];
96 | div2.translatesAutoresizingMaskIntoConstraints = NO;
97 |
98 | JVFloatLabeledTextField *locationField = [[JVFloatLabeledTextField alloc] initWithFrame:CGRectZero];
99 | locationField.font = [UIFont systemFontOfSize:kJVFieldFontSize];
100 | locationField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:NSLocalizedString(@"Specific Location (optional)", @"")
101 | attributes:@{NSForegroundColorAttributeName: [UIColor darkGrayColor]}];
102 | locationField.floatingLabelFont = [UIFont boldSystemFontOfSize:kJVFieldFloatingLabelFontSize];
103 | locationField.floatingLabelTextColor = floatingLabelColor;
104 | [self.view addSubview:locationField];
105 | locationField.translatesAutoresizingMaskIntoConstraints = NO;
106 |
107 | UIView *div3 = [UIView new];
108 | div3.backgroundColor = [[UIColor lightGrayColor] colorWithAlphaComponent:0.3f];
109 | [self.view addSubview:div3];
110 | div3.translatesAutoresizingMaskIntoConstraints = NO;
111 |
112 | JVFloatLabeledTextView *descriptionField = [[JVFloatLabeledTextView alloc] initWithFrame:CGRectZero];
113 | descriptionField.font = [UIFont systemFontOfSize:kJVFieldFontSize];
114 | descriptionField.placeholder = NSLocalizedString(@"Description", @"");
115 | descriptionField.placeholderTextColor = [UIColor darkGrayColor];
116 | descriptionField.floatingLabelFont = [UIFont boldSystemFontOfSize:kJVFieldFloatingLabelFontSize];
117 | descriptionField.floatingLabelTextColor = floatingLabelColor;
118 | [self.view addSubview:descriptionField];
119 | descriptionField.translatesAutoresizingMaskIntoConstraints = NO;
120 |
121 | [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(xMargin)-[titleField]-(xMargin)-|" options:0 metrics:@{@"xMargin": @(kJVFieldHMargin)} views:NSDictionaryOfVariableBindings(titleField)]];
122 | [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[div1]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(div1)]];
123 | [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(xMargin)-[priceField]-(xMargin)-[div2(1)]-(xMargin)-[locationField]-(xMargin)-|" options:NSLayoutFormatAlignAllCenterY metrics:@{@"xMargin": @(kJVFieldHMargin)} views:NSDictionaryOfVariableBindings(priceField, div2, locationField)]];
124 | [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[div3]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(div3)]];
125 | [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(xMargin)-[descriptionField]-(xMargin)-|" options:0 metrics:@{@"xMargin": @(kJVFieldHMargin)} views:NSDictionaryOfVariableBindings(descriptionField)]];
126 |
127 | [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[titleField(>=minHeight)][div1(1)][priceField(>=minHeight)][div3(1)][descriptionField]|" options:0 metrics:@{@"minHeight": @(kJVFieldHeight)} views:NSDictionaryOfVariableBindings(titleField, div1, priceField, div3, descriptionField)]];
128 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:priceField attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:div2 attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0.0]];
129 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:priceField attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:locationField attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0.0]];
130 |
131 | [titleField becomeFirstResponder];
132 | }
133 |
134 | - (void)didReceiveMemoryWarning
135 | {
136 | [super didReceiveMemoryWarning];
137 | // Dispose of any resources that can be recreated.
138 | }
139 |
140 | @end
141 |
--------------------------------------------------------------------------------
/JVFloatLabeledTextField/JVFloatLabeledTextField/JVFloatLabeledTextField.m:
--------------------------------------------------------------------------------
1 | //
2 | // JVFloatLabeledTextField.m
3 | // JVFloatLabeledTextField
4 | //
5 | // The MIT License (MIT)
6 | //
7 | // Copyright (c) 2013-2015 Jared Verdi
8 | // Original Concept by Matt D. Smith
9 | // http://dribbble.com/shots/1254439--GIF-Mobile-Form-Interaction?list=users
10 | //
11 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
12 | // this software and associated documentation files (the "Software"), to deal in
13 | // the Software without restriction, including without limitation the rights to
14 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
15 | // the Software, and to permit persons to whom the Software is furnished to do so,
16 | // subject to the following conditions:
17 | //
18 | // The above copyright notice and this permission notice shall be included in all
19 | // copies or substantial portions of the Software.
20 | //
21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
23 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
24 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
25 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
26 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 |
28 | #import "JVFloatLabeledTextField.h"
29 | #import "NSString+TextDirectionality.h"
30 |
31 | static CGFloat const kFloatingLabelShowAnimationDuration = 0.3f;
32 | static CGFloat const kFloatingLabelHideAnimationDuration = 0.3f;
33 |
34 | @implementation JVFloatLabeledTextField
35 | {
36 | BOOL _isFloatingLabelFontDefault;
37 | }
38 |
39 | - (instancetype)initWithFrame:(CGRect)frame
40 | {
41 | self = [super initWithFrame:frame];
42 | if (self) {
43 | [self commonInit];
44 | }
45 | return self;
46 | }
47 |
48 | - (instancetype)initWithCoder:(NSCoder *)aDecoder
49 | {
50 | self = [super initWithCoder:aDecoder];
51 | if (self) {
52 | [self commonInit];
53 | }
54 | return self;
55 | }
56 |
57 | - (void)commonInit
58 | {
59 | _floatingLabel = [UILabel new];
60 | _floatingLabel.alpha = 0.0f;
61 | [self addSubview:_floatingLabel];
62 |
63 | // some basic default fonts/colors
64 | _floatingLabelReductionRatio = 70;
65 | _floatingLabelFont = [self defaultFloatingLabelFont];
66 | _floatingLabel.font = _floatingLabelFont;
67 | _floatingLabelTextColor = [UIColor grayColor];
68 | _floatingLabel.textColor = _floatingLabelTextColor;
69 | _animateEvenIfNotFirstResponder = NO;
70 | _floatingLabelShowAnimationDuration = kFloatingLabelShowAnimationDuration;
71 | _floatingLabelHideAnimationDuration = kFloatingLabelHideAnimationDuration;
72 | [self setFloatingLabelText:self.placeholder];
73 |
74 | _adjustsClearButtonRect = YES;
75 | _isFloatingLabelFontDefault = YES;
76 | }
77 |
78 | #pragma mark -
79 |
80 | - (UIFont *)defaultFloatingLabelFont
81 | {
82 | UIFont *textFieldFont = nil;
83 |
84 | if (!textFieldFont && self.attributedPlaceholder && self.attributedPlaceholder.length > 0) {
85 | textFieldFont = [self.attributedPlaceholder attribute:NSFontAttributeName atIndex:0 effectiveRange:NULL];
86 | }
87 | if (!textFieldFont && self.attributedText && self.attributedText.length > 0) {
88 | textFieldFont = [self.attributedText attribute:NSFontAttributeName atIndex:0 effectiveRange:NULL];
89 | }
90 | if (!textFieldFont) {
91 | textFieldFont = self.font;
92 | }
93 |
94 | return [textFieldFont fontWithSize:roundf(textFieldFont.pointSize * (_floatingLabelReductionRatio/100))];
95 | }
96 |
97 | - (void)updateDefaultFloatingLabelFont
98 | {
99 | UIFont *derivedFont = [self defaultFloatingLabelFont];
100 |
101 | if (_isFloatingLabelFontDefault) {
102 | self.floatingLabelFont = derivedFont;
103 | }
104 | else {
105 | // dont apply to the label, just store for future use where floatingLabelFont may be reset to nil
106 | _floatingLabelFont = derivedFont;
107 | }
108 | }
109 |
110 | - (UIColor *)labelActiveColor
111 | {
112 | if (_floatingLabelActiveTextColor) {
113 | return _floatingLabelActiveTextColor;
114 | }
115 | else if ([self respondsToSelector:@selector(tintColor)]) {
116 | return [self performSelector:@selector(tintColor)];
117 | }
118 | return [UIColor blueColor];
119 | }
120 |
121 | - (void)setFloatingLabelFont:(UIFont *)floatingLabelFont
122 | {
123 | if (floatingLabelFont != nil) {
124 | _floatingLabelFont = floatingLabelFont;
125 | }
126 | _floatingLabel.font = _floatingLabelFont ? _floatingLabelFont : [self defaultFloatingLabelFont];
127 | _isFloatingLabelFontDefault = floatingLabelFont == nil;
128 | [self invalidateIntrinsicContentSize];
129 | }
130 |
131 | - (void)showFloatingLabel:(BOOL)animated
132 | {
133 | void (^showBlock)(void) = ^{
134 | self->_floatingLabel.alpha = 1.0f;
135 | self->_floatingLabel.frame = CGRectMake(self->_floatingLabel.frame.origin.x,
136 | self->_floatingLabelYPadding,
137 | self->_floatingLabel.frame.size.width,
138 | self->_floatingLabel.frame.size.height);
139 | };
140 |
141 | if (animated || 0 != _animateEvenIfNotFirstResponder) {
142 | [UIView animateWithDuration:_floatingLabelShowAnimationDuration
143 | delay:0.0f
144 | options:UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionCurveEaseOut
145 | animations:showBlock
146 | completion:nil];
147 | }
148 | else {
149 | showBlock();
150 | }
151 | }
152 |
153 | - (void)hideFloatingLabel:(BOOL)animated
154 | {
155 | void (^hideBlock)(void) = ^{
156 | self->_floatingLabel.alpha = 0.0f;
157 | self->_floatingLabel.frame = CGRectMake(self->_floatingLabel.frame.origin.x,
158 | self->_floatingLabel.font.lineHeight + self->_placeholderYPadding,
159 | self->_floatingLabel.frame.size.width,
160 | self->_floatingLabel.frame.size.height);
161 |
162 | };
163 |
164 | if (animated || 0 != _animateEvenIfNotFirstResponder) {
165 | [UIView animateWithDuration:_floatingLabelHideAnimationDuration
166 | delay:0.0f
167 | options:UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionCurveEaseIn
168 | animations:hideBlock
169 | completion:nil];
170 | }
171 | else {
172 | hideBlock();
173 | }
174 | }
175 |
176 | - (void)setLabelOriginForTextAlignment
177 | {
178 | CGRect textRect = [self textRectForBounds:self.bounds];
179 |
180 | CGFloat originX = textRect.origin.x;
181 |
182 | if (self.textAlignment == NSTextAlignmentCenter) {
183 | originX = textRect.origin.x + (textRect.size.width/2) - (_floatingLabel.frame.size.width/2);
184 | }
185 | else if (self.textAlignment == NSTextAlignmentRight) {
186 | originX = textRect.origin.x + textRect.size.width - _floatingLabel.frame.size.width;
187 | }
188 | else if (self.textAlignment == NSTextAlignmentNatural) {
189 | JVTextDirection baseDirection = [_floatingLabel.text getBaseDirection];
190 | if (baseDirection == JVTextDirectionRightToLeft) {
191 | originX = textRect.origin.x + textRect.size.width - _floatingLabel.frame.size.width;
192 | }
193 | }
194 |
195 | _floatingLabel.frame = CGRectMake(originX + _floatingLabelXPadding, _floatingLabel.frame.origin.y,
196 | _floatingLabel.frame.size.width, _floatingLabel.frame.size.height);
197 | }
198 |
199 | - (void)setFloatingLabelText:(NSString *)text
200 | {
201 | self.accessibilityLabel = text;
202 | _floatingLabel.text = text;
203 | [self setNeedsLayout];
204 | }
205 |
206 | #pragma mark - UITextField
207 |
208 | - (void)setFont:(UIFont *)font
209 | {
210 | [super setFont:font];
211 | [self updateDefaultFloatingLabelFont];
212 | }
213 |
214 | - (void)setFloatingLabelReductionRatio:(CGFloat)floatingLabelReductionRatio
215 | {
216 | _floatingLabelReductionRatio = floatingLabelReductionRatio;
217 | _floatingLabelFont = [self defaultFloatingLabelFont];
218 | _floatingLabel.font = _floatingLabelFont;
219 | }
220 |
221 | - (void)setAttributedText:(NSAttributedString *)attributedText
222 | {
223 | [super setAttributedText:attributedText];
224 | [self updateDefaultFloatingLabelFont];
225 | }
226 |
227 | - (CGSize)intrinsicContentSize
228 | {
229 | CGSize textFieldIntrinsicContentSize = [super intrinsicContentSize];
230 | [_floatingLabel sizeToFit];
231 | return CGSizeMake(textFieldIntrinsicContentSize.width,
232 | textFieldIntrinsicContentSize.height + _floatingLabelYPadding + _floatingLabel.bounds.size.height);
233 | }
234 |
235 | - (void)setCorrectPlaceholder:(NSString *)placeholder
236 | {
237 | if (self.placeholderColor && placeholder) {
238 | NSAttributedString *attributedPlaceholder = [[NSAttributedString alloc] initWithString:placeholder
239 | attributes:@{NSForegroundColorAttributeName: self.placeholderColor}];
240 | [super setAttributedPlaceholder:attributedPlaceholder];
241 | } else {
242 | [super setPlaceholder:placeholder];
243 | }
244 | }
245 |
246 | - (void)setPlaceholder:(NSString *)placeholder
247 | {
248 | [self setCorrectPlaceholder:placeholder];
249 | [self setFloatingLabelText:placeholder];
250 | }
251 |
252 | - (void)setAttributedPlaceholder:(NSAttributedString *)attributedPlaceholder
253 | {
254 | [super setAttributedPlaceholder:attributedPlaceholder];
255 | [self setFloatingLabelText:attributedPlaceholder.string];
256 | [self updateDefaultFloatingLabelFont];
257 | }
258 |
259 | - (void)setPlaceholder:(NSString *)placeholder floatingTitle:(NSString *)floatingTitle
260 | {
261 | [self setCorrectPlaceholder:placeholder];
262 | [self setFloatingLabelText:floatingTitle];
263 | }
264 |
265 | - (void)setAttributedPlaceholder:(NSAttributedString *)attributedPlaceholder floatingTitle:(NSString *)floatingTitle
266 | {
267 | [super setAttributedPlaceholder:attributedPlaceholder];
268 | [self setFloatingLabelText:floatingTitle];
269 | }
270 |
271 | - (void)setPlaceholderColor:(UIColor *)color
272 | {
273 | _placeholderColor = color;
274 | [self setCorrectPlaceholder:self.placeholder];
275 | }
276 |
277 | - (CGRect)textRectForBounds:(CGRect)bounds
278 | {
279 | CGRect rect = [super textRectForBounds:bounds];
280 | if ([self.text length] || self.keepBaseline) {
281 | rect = [self insetRectForBounds:rect];
282 | }
283 | return rect;
284 | }
285 |
286 | - (CGRect)editingRectForBounds:(CGRect)bounds
287 | {
288 | CGRect rect = [super editingRectForBounds:bounds];
289 | if ([self.text length] || self.keepBaseline) {
290 | rect = [self insetRectForBounds:rect];
291 | }
292 | return rect;
293 | }
294 |
295 | - (CGRect)insetRectForBounds:(CGRect)rect
296 | {
297 | CGFloat topInset = ceilf(_floatingLabel.bounds.size.height + _placeholderYPadding);
298 | topInset = MIN(topInset, [self maxTopInset]);
299 | return CGRectMake(rect.origin.x, rect.origin.y + topInset / 2.0f, rect.size.width, rect.size.height);
300 | }
301 |
302 | - (CGRect)clearButtonRectForBounds:(CGRect)bounds
303 | {
304 | CGRect rect = [super clearButtonRectForBounds:bounds];
305 | if (0 != self.adjustsClearButtonRect
306 | && _floatingLabel.text.length // for when there is no floating title label text
307 | ) {
308 | if ([self.text length] || self.keepBaseline) {
309 | CGFloat topInset = ceilf(_floatingLabel.font.lineHeight + _placeholderYPadding);
310 | topInset = MIN(topInset, [self maxTopInset]);
311 | rect = CGRectMake(rect.origin.x, rect.origin.y + topInset / 2.0f, rect.size.width, rect.size.height);
312 | }
313 | }
314 | return rect;
315 | }
316 |
317 | - (CGRect)leftViewRectForBounds:(CGRect)bounds
318 | {
319 | CGRect rect = [super leftViewRectForBounds:bounds];
320 |
321 | CGFloat topInset = ceilf(_floatingLabel.font.lineHeight + _placeholderYPadding);
322 | topInset = MIN(topInset, [self maxTopInset]);
323 | rect = CGRectOffset(rect, 0, topInset / 2.0f);
324 |
325 | return rect;
326 | }
327 |
328 | - (CGRect)rightViewRectForBounds:(CGRect)bounds
329 | {
330 |
331 | CGRect rect = [super rightViewRectForBounds:bounds];
332 |
333 | CGFloat topInset = ceilf(_floatingLabel.font.lineHeight + _placeholderYPadding);
334 | topInset = MIN(topInset, [self maxTopInset]);
335 | rect = CGRectOffset(rect, 0, topInset / 2.0f);
336 |
337 | return rect;
338 | }
339 |
340 | - (CGFloat)maxTopInset
341 | {
342 | return MAX(0, floorf(self.bounds.size.height - self.font.lineHeight - 4.0f));
343 | }
344 |
345 | - (void)setTextAlignment:(NSTextAlignment)textAlignment
346 | {
347 | [super setTextAlignment:textAlignment];
348 | [self setNeedsLayout];
349 | }
350 |
351 | - (void)setAlwaysShowFloatingLabel:(BOOL)alwaysShowFloatingLabel
352 | {
353 | _alwaysShowFloatingLabel = alwaysShowFloatingLabel;
354 | [self setNeedsLayout];
355 | }
356 |
357 | - (void)layoutSubviews
358 | {
359 | [super layoutSubviews];
360 |
361 | [self setLabelOriginForTextAlignment];
362 |
363 | CGSize floatingLabelSize = [_floatingLabel sizeThatFits:_floatingLabel.superview.bounds.size];
364 |
365 | _floatingLabel.frame = CGRectMake(_floatingLabel.frame.origin.x,
366 | _floatingLabel.frame.origin.y,
367 | floatingLabelSize.width,
368 | floatingLabelSize.height);
369 |
370 | BOOL firstResponder = self.isFirstResponder;
371 | _floatingLabel.textColor = (firstResponder && self.text && self.text.length > 0 ?
372 | self.labelActiveColor : self.floatingLabelTextColor);
373 | if ((!self.text || 0 == [self.text length]) && !self.alwaysShowFloatingLabel) {
374 | [self hideFloatingLabel:firstResponder];
375 | }
376 | else {
377 | [self showFloatingLabel:firstResponder];
378 | }
379 | }
380 |
381 | @end
382 |
--------------------------------------------------------------------------------
/JVFloatLabeledTextField/JVFloatLabeledTextField/JVFloatLabeledTextView.m:
--------------------------------------------------------------------------------
1 | //
2 | // JVFloatLabeledTextView.m
3 | // JVFloatLabeledTextField
4 | //
5 | // The MIT License (MIT)
6 | //
7 | // Copyright (c) 2013-2015 Jared Verdi
8 | // Original Concept by Matt D. Smith
9 | // http://dribbble.com/shots/1254439--GIF-Mobile-Form-Interaction?list=users
10 | //
11 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
12 | // this software and associated documentation files (the "Software"), to deal in
13 | // the Software without restriction, including without limitation the rights to
14 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
15 | // the Software, and to permit persons to whom the Software is furnished to do so,
16 | // subject to the following conditions:
17 | //
18 | // The above copyright notice and this permission notice shall be included in all
19 | // copies or substantial portions of the Software.
20 | //
21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
23 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
24 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
25 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
26 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 |
28 | #import "JVFloatLabeledTextView.h"
29 | #import "NSString+TextDirectionality.h"
30 |
31 | static CGFloat const kFloatingLabelShowAnimationDuration = 0.3f;
32 | static CGFloat const kFloatingLabelHideAnimationDuration = 0.3f;
33 |
34 | @interface JVFloatLabeledTextView ()
35 |
36 |
37 | @end
38 |
39 | @implementation JVFloatLabeledTextView
40 |
41 | - (instancetype)initWithFrame:(CGRect)frame
42 | {
43 | self = [super initWithFrame:frame];
44 | if (self) {
45 | [self commonInit];
46 | }
47 | return self;
48 | }
49 |
50 | - (instancetype)initWithFrame:(CGRect)frame textContainer:(NSTextContainer *)textContainer
51 | {
52 | self = [super initWithFrame:frame textContainer:textContainer];
53 | if (self) {
54 | [self commonInit];
55 | }
56 | return self;
57 | }
58 |
59 | - (instancetype)initWithCoder:(NSCoder *)aDecoder
60 | {
61 | self = [super initWithCoder:aDecoder];
62 | if (self) {
63 | [self commonInit];
64 |
65 | // force setter to be called on a placeholder defined in a NIB/Storyboard
66 | if (self.placeholder) {
67 | self.placeholder = self.placeholder;
68 | }
69 | }
70 | return self;
71 | }
72 |
73 | - (void)commonInit
74 | {
75 | self.startingTextContainerInsetTop = self.textContainerInset.top;
76 | self.floatingLabelShouldLockToTop = YES;
77 | self.textContainer.lineFragmentPadding = 0;
78 |
79 | _placeholderLabel = [[UILabel alloc] initWithFrame:self.frame];
80 | if (!self.font) {
81 | // by default self.font may be nil - so make UITextView use UILabel's default
82 | self.font = _placeholderLabel.font;
83 | }
84 | _placeholderLabel.font = self.font;
85 | _placeholderLabel.text = self.placeholder;
86 | _placeholderLabel.numberOfLines = 0;
87 | _placeholderLabel.lineBreakMode = NSLineBreakByWordWrapping;
88 | _placeholderLabel.backgroundColor = [UIColor clearColor];
89 | _placeholderTextColor = [JVFloatLabeledTextView defaultiOSPlaceholderColor];
90 | _placeholderLabel.textColor = _placeholderTextColor;
91 | [self insertSubview:_placeholderLabel atIndex:0];
92 |
93 | _floatingLabel = [UILabel new];
94 | _floatingLabel.alpha = 0.0f;
95 | _floatingLabel.backgroundColor = self.backgroundColor;
96 | [self addSubview:_floatingLabel];
97 |
98 | // some basic default fonts/colors
99 | _floatingLabelFont = [self defaultFloatingLabelFont];
100 | _floatingLabel.font = _floatingLabelFont;
101 | _floatingLabelTextColor = [UIColor grayColor];
102 | _floatingLabel.textColor = _floatingLabelTextColor;
103 | _animateEvenIfNotFirstResponder = NO;
104 | _floatingLabelShowAnimationDuration = kFloatingLabelShowAnimationDuration;
105 | _floatingLabelHideAnimationDuration = kFloatingLabelHideAnimationDuration;
106 |
107 | [[NSNotificationCenter defaultCenter] addObserver:self
108 | selector:@selector(layoutSubviews)
109 | name:UITextViewTextDidChangeNotification
110 | object:self];
111 | [[NSNotificationCenter defaultCenter] addObserver:self
112 | selector:@selector(layoutSubviews)
113 | name:UITextViewTextDidBeginEditingNotification
114 | object:self];
115 | [[NSNotificationCenter defaultCenter] addObserver:self
116 | selector:@selector(layoutSubviews)
117 | name:UITextViewTextDidEndEditingNotification
118 | object:self];
119 | }
120 |
121 | - (void)dealloc
122 | {
123 | [[NSNotificationCenter defaultCenter] removeObserver:self
124 | name:UITextViewTextDidChangeNotification
125 | object:self];
126 | [[NSNotificationCenter defaultCenter] removeObserver:self
127 | name:UITextViewTextDidBeginEditingNotification
128 | object:self];
129 | [[NSNotificationCenter defaultCenter] removeObserver:self
130 | name:UITextViewTextDidEndEditingNotification
131 | object:self];
132 | }
133 |
134 | #pragma mark -
135 |
136 | - (UIFont *)defaultFloatingLabelFont
137 | {
138 | UIFont *textViewFont = nil;
139 |
140 | if (!textViewFont && self.placeholderLabel.attributedText && self.placeholderLabel.attributedText.length > 0) {
141 | textViewFont = [self.placeholderLabel.attributedText attribute:NSFontAttributeName atIndex:0 effectiveRange:NULL];
142 | }
143 | if (!textViewFont) {
144 | textViewFont = self.placeholderLabel.font;
145 | }
146 |
147 | return [textViewFont fontWithSize:roundf(textViewFont.pointSize * 0.7f)];
148 | }
149 |
150 | - (void)setPlaceholder:(NSString *)placeholder
151 | {
152 | _placeholder = placeholder;
153 | _placeholderLabel.text = placeholder;
154 | _floatingLabel.text = placeholder;
155 |
156 | if (0 != self.floatingLabelShouldLockToTop) {
157 | _floatingLabel.frame = CGRectMake(_floatingLabel.frame.origin.x,
158 | _floatingLabel.frame.origin.y,
159 | self.frame.size.width,
160 | _floatingLabel.frame.size.height);
161 | }
162 |
163 | [self setNeedsLayout];
164 | }
165 |
166 | - (void)setPlaceholder:(NSString *)placeholder floatingTitle:(NSString *)floatingTitle
167 | {
168 | _placeholder = placeholder;
169 | _placeholderLabel.text = placeholder;
170 | _floatingLabel.text = floatingTitle;
171 |
172 | [self setNeedsLayout];
173 | }
174 |
175 | - (void)layoutSubviews
176 | {
177 | [super layoutSubviews];
178 | [self adjustTextContainerInsetTop];
179 |
180 | CGSize floatingLabelSize = [_floatingLabel sizeThatFits:_floatingLabel.superview.bounds.size];
181 |
182 | _floatingLabel.frame = CGRectMake(_floatingLabel.frame.origin.x,
183 | _floatingLabel.frame.origin.y,
184 | self.frame.size.width,
185 | floatingLabelSize.height);
186 |
187 | CGSize placeholderLabelSize = [_placeholderLabel sizeThatFits:_placeholderLabel.superview.bounds.size];
188 |
189 | CGRect textRect = [self textRect];
190 |
191 | _placeholderLabel.alpha = [self.text length] > 0 ? 0.0f : 1.0f;
192 | _placeholderLabel.frame = CGRectMake(textRect.origin.x, textRect.origin.y,
193 | placeholderLabelSize.width, placeholderLabelSize.height);
194 |
195 | [self setLabelOriginForTextAlignment];
196 |
197 | BOOL firstResponder = self.isFirstResponder;
198 | _floatingLabel.textColor = (firstResponder && self.text && self.text.length > 0 ?
199 | self.labelActiveColor : self.floatingLabelTextColor);
200 | if ((!self.text || 0 == [self.text length]) && !self.alwaysShowFloatingLabel) {
201 | [self hideFloatingLabel:firstResponder];
202 | }
203 | else {
204 | [self showFloatingLabel:firstResponder];
205 | }
206 |
207 | // Without this code, the size of the view is not calculated correctly when it
208 | // is first displayed. Only seems relevant when scroll is disabled.
209 | if (!self.scrollEnabled && !CGSizeEqualToSize(self.bounds.size, [self intrinsicContentSize])) {
210 | [self invalidateIntrinsicContentSize];
211 | }
212 | }
213 |
214 | - (CGSize)intrinsicContentSize
215 | {
216 | CGSize textFieldIntrinsicContentSize = [super intrinsicContentSize];
217 |
218 | if (self.text != nil && self.text.length > 0) {
219 | return textFieldIntrinsicContentSize;
220 | } else {
221 | CGFloat additionalHeight = _placeholderLabel.bounds.size.height - (_floatingLabel.bounds.size.height + _floatingLabelYPadding);
222 |
223 | return CGSizeMake(textFieldIntrinsicContentSize.width,
224 | textFieldIntrinsicContentSize.height + additionalHeight);
225 | }
226 | }
227 |
228 | - (UIColor *)labelActiveColor
229 | {
230 | if (_floatingLabelActiveTextColor) {
231 | return _floatingLabelActiveTextColor;
232 | }
233 | else if ([self respondsToSelector:@selector(tintColor)]) {
234 | return [self performSelector:@selector(tintColor)];
235 | }
236 | return [UIColor blueColor];
237 | }
238 |
239 | - (void)setAlwaysShowFloatingLabel:(BOOL)alwaysShowFloatingLabel
240 | {
241 | _alwaysShowFloatingLabel = alwaysShowFloatingLabel;
242 | [self setNeedsLayout];
243 | }
244 |
245 | - (void)showFloatingLabel:(BOOL)animated
246 | {
247 | void (^showBlock)(void) = ^{
248 | self->_floatingLabel.alpha = 1.0f;
249 | CGFloat top = self->_floatingLabelYPadding;
250 | if (0 != self.floatingLabelShouldLockToTop) {
251 | top += self.contentOffset.y;
252 | }
253 | self->_floatingLabel.frame = CGRectMake(self->_floatingLabel.frame.origin.x,
254 | top,
255 | self->_floatingLabel.frame.size.width,
256 | self->_floatingLabel.frame.size.height);
257 | };
258 |
259 | if ((animated || 0 != _animateEvenIfNotFirstResponder)
260 | && (0 == self.floatingLabelShouldLockToTop || _floatingLabel.alpha != 1.0f)) {
261 | [UIView animateWithDuration:_floatingLabelShowAnimationDuration
262 | delay:0.0f
263 | options:UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionCurveEaseOut
264 | animations:showBlock
265 | completion:nil];
266 | }
267 | else {
268 | showBlock();
269 | }
270 | }
271 |
272 | - (void)hideFloatingLabel:(BOOL)animated
273 | {
274 | void (^hideBlock)(void) = ^{
275 | self->_floatingLabel.alpha = 0.0f;
276 | self->_floatingLabel.frame = CGRectMake(self->_floatingLabel.frame.origin.x,
277 | self->_floatingLabel.font.lineHeight + self->_placeholderYPadding,
278 | self->_floatingLabel.frame.size.width,
279 | self->_floatingLabel.frame.size.height);
280 |
281 | };
282 |
283 | if (animated || 0 != _animateEvenIfNotFirstResponder) {
284 | [UIView animateWithDuration:_floatingLabelHideAnimationDuration
285 | delay:0.0f
286 | options:UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionCurveEaseIn
287 | animations:hideBlock
288 | completion:nil];
289 | }
290 | else {
291 | hideBlock();
292 | }
293 | }
294 |
295 | - (void)adjustTextContainerInsetTop
296 | {
297 | self.textContainerInset = UIEdgeInsetsMake(self.startingTextContainerInsetTop
298 | + _floatingLabel.font.lineHeight + _placeholderYPadding,
299 | self.textContainerInset.left,
300 | self.textContainerInset.bottom,
301 | self.textContainerInset.right);
302 | }
303 |
304 | - (void)setLabelOriginForTextAlignment
305 | {
306 | CGFloat floatingLabelOriginX = [self textRect].origin.x;
307 | CGFloat placeholderLabelOriginX = floatingLabelOriginX;
308 |
309 | if (self.textAlignment == NSTextAlignmentCenter) {
310 | floatingLabelOriginX = (self.frame.size.width/2) - (_floatingLabel.frame.size.width/2);
311 | placeholderLabelOriginX = (self.frame.size.width/2) - (_placeholderLabel.frame.size.width/2);
312 | }
313 | else if (self.textAlignment == NSTextAlignmentRight) {
314 | floatingLabelOriginX = self.frame.size.width - _floatingLabel.frame.size.width;
315 | placeholderLabelOriginX = (self.frame.size.width
316 | - _placeholderLabel.frame.size.width - self.textContainerInset.right);
317 | }
318 | else if (self.textAlignment == NSTextAlignmentNatural) {
319 | JVTextDirection baseDirection = [_floatingLabel.text getBaseDirection];
320 | if (baseDirection == JVTextDirectionRightToLeft) {
321 | floatingLabelOriginX = self.frame.size.width - _floatingLabel.frame.size.width;
322 | placeholderLabelOriginX = (self.frame.size.width
323 | - _placeholderLabel.frame.size.width - self.textContainerInset.right);
324 | }
325 | }
326 |
327 | _floatingLabel.frame = CGRectMake(floatingLabelOriginX + _floatingLabelXPadding, _floatingLabel.frame.origin.y,
328 | _floatingLabel.frame.size.width, _floatingLabel.frame.size.height);
329 |
330 | _placeholderLabel.frame = CGRectMake(placeholderLabelOriginX, _placeholderLabel.frame.origin.y,
331 | _placeholderLabel.frame.size.width, _placeholderLabel.frame.size.height);
332 | }
333 |
334 | - (CGRect)textRect
335 | {
336 | CGRect rect = UIEdgeInsetsInsetRect(self.bounds, self.contentInset);
337 |
338 | if (self.textContainer) {
339 | rect.origin.x += self.textContainer.lineFragmentPadding;
340 | rect.origin.y += self.textContainerInset.top;
341 | }
342 |
343 | return rect;
344 | }
345 |
346 | - (void)setFloatingLabelFont:(UIFont *)floatingLabelFont
347 | {
348 | _floatingLabelFont = floatingLabelFont;
349 | _floatingLabel.font = _floatingLabelFont ? _floatingLabelFont : [self defaultFloatingLabelFont];
350 | self.placeholder = self.placeholder; // Force the label to lay itself out with the new font.
351 | }
352 |
353 | #pragma mark - Apple UITextView defaults
354 |
355 | + (UIColor *)defaultiOSPlaceholderColor
356 | {
357 | return [[UIColor lightGrayColor] colorWithAlphaComponent:0.65f];
358 | }
359 |
360 | #pragma mark - UITextView
361 |
362 | - (void)setTextAlignment:(NSTextAlignment)textAlignment
363 | {
364 | [super setTextAlignment:textAlignment];
365 | [self setNeedsLayout];
366 | }
367 |
368 | - (void)setFont:(UIFont *)font
369 | {
370 | [super setFont:font];
371 | self.placeholderLabel.font = self.font;
372 | [self layoutSubviews];
373 | }
374 |
375 | - (void)setText:(NSString *)text
376 | {
377 | [super setText:text];
378 | [self layoutSubviews];
379 | }
380 |
381 | - (void)setPlaceholderTextColor:(UIColor *)placeholderTextColor
382 | {
383 | _placeholderTextColor = placeholderTextColor;
384 | _placeholderLabel.textColor = _placeholderTextColor;
385 | }
386 |
387 | - (void)setBackgroundColor:(UIColor *)backgroundColor
388 | {
389 | [super setBackgroundColor:backgroundColor];
390 |
391 | if (0 != self.floatingLabelShouldLockToTop) {
392 | _floatingLabel.backgroundColor = self.backgroundColor;
393 | }
394 | }
395 |
396 | @end
397 |
--------------------------------------------------------------------------------
/JVFloatLabeledTextField/JVFloatLabeledTextField/NSString+TextDirectionality.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSString+TextDirectionality.m
3 | // JVFloatLabeledTextField
4 | //
5 | // The MIT License (MIT)
6 | //
7 | // Copyright (c) 2013-2015 Jared Verdi
8 | // Original Concept by Matt D. Smith
9 | // http://dribbble.com/shots/1254439--GIF-Mobile-Form-Interaction?list=users
10 | //
11 | // Permission is hereby granted, free of charge, to any person obtaining a copy of
12 | // this software and associated documentation files (the "Software"), to deal in
13 | // the Software without restriction, including without limitation the rights to
14 | // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
15 | // the Software, and to permit persons to whom the Software is furnished to do so,
16 | // subject to the following conditions:
17 | //
18 | // The above copyright notice and this permission notice shall be included in all
19 | // copies or substantial portions of the Software.
20 | //
21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
23 | // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
24 | // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
25 | // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
26 | // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 |
28 | // Based on a Stack Overflow answer http://stackoverflow.com/a/13697277/900251
29 |
30 | #import "NSString+TextDirectionality.h"
31 |
32 | @implementation NSString (TextDirectionality)
33 |
34 | // Function takes UTF32 character, and not a unichar (=UTF16 character),
35 | // because some Unicode characters need full 32 bits to represent.
36 | static BOOL isCodePointStrongRTL(UTF32Char c)
37 | {
38 | return ((c == 0x5BE) || (c == 0x5C0) || (c == 0x5C3) || (c == 0x5C6) || (c >= 0x5D0 && c <= 0x5EA) || (c >= 0x5F0 && c <= 0x5F4) || (c == 0x608) || (c == 0x60B) || (c == 0x60D) || (c == 0x61B) || (c >= 0x61E && c <= 0x64A) || (c >= 0x66D && c <= 0x66F) || (c >= 0x671 && c <= 0x6D5) || (c >= 0x6E5 && c <= 0x6E6) || (c >= 0x6EE && c <= 0x6EF) || (c >= 0x6FA && c <= 0x70D) || (c >= 0x70F && c <= 0x710) || (c >= 0x712 && c <= 0x72F) || (c >= 0x74D && c <= 0x7A5) || (c == 0x7B1) || (c >= 0x7C0 && c <= 0x7EA) || (c >= 0x7F4 && c <= 0x7F5) || (c == 0x7FA) || (c >= 0x800 && c <= 0x815) || (c == 0x81A) || (c == 0x824) || (c == 0x828) || (c >= 0x830 && c <= 0x83E) || (c >= 0x840 && c <= 0x858) || (c == 0x85E) || (c == 0x8A0) || (c >= 0x8A2 && c <= 0x8AC) || (c == 0x200F) || (c == 0xFB1D) || (c >= 0xFB1F && c <= 0xFB28) || (c >= 0xFB2A && c <= 0xFB36) || (c >= 0xFB38 && c <= 0xFB3C) || (c == 0xFB3E) || (c >= 0xFB40 && c <= 0xFB41) || (c >= 0xFB43 && c <= 0xFB44) || (c >= 0xFB46 && c <= 0xFBC1) || (c >= 0xFBD3 && c <= 0xFD3D) || (c >= 0xFD50 && c <= 0xFD8F) || (c >= 0xFD92 && c <= 0xFDC7) || (c >= 0xFDF0 && c <= 0xFDFC) || (c >= 0xFE70 && c <= 0xFE74) || (c >= 0xFE76 && c <= 0xFEFC) || (c >= 0x10800 && c <= 0x10805) || (c == 0x10808) || (c >= 0x1080A && c <= 0x10835) || (c >= 0x10837 && c <= 0x10838) || (c == 0x1083C) || (c >= 0x1083F && c <= 0x10855) || (c >= 0x10857 && c <= 0x1085F) || (c >= 0x10900 && c <= 0x1091B) || (c >= 0x10920 && c <= 0x10939) || (c == 0x1093F) || (c >= 0x10980 && c <= 0x109B7) || (c >= 0x109BE && c <= 0x109BF) || (c == 0x10A00) || (c >= 0x10A10 && c <= 0x10A13) || (c >= 0x10A15 && c <= 0x10A17) || (c >= 0x10A19 && c <= 0x10A33) || (c >= 0x10A40 && c <= 0x10A47) || (c >= 0x10A50 && c <= 0x10A58) || (c >= 0x10A60 && c <= 0x10A7F) || (c >= 0x10B00 && c <= 0x10B35) || (c >= 0x10B40 && c <= 0x10B55) || (c >= 0x10B58 && c <= 0x10B72) || (c >= 0x10B78 && c <= 0x10B7F) || (c >= 0x10C00 && c <= 0x10C48) || (c >= 0x1EE00 && c <= 0x1EE03) || (c >= 0x1EE05 && c <= 0x1EE1F) || (c >= 0x1EE21 && c <= 0x1EE22) || (c == 0x1EE24) || (c == 0x1EE27) || (c >= 0x1EE29 && c <= 0x1EE32) || (c >= 0x1EE34 && c <= 0x1EE37) || (c == 0x1EE39) || (c == 0x1EE3B) || (c == 0x1EE42) || (c == 0x1EE47) || (c == 0x1EE49) || (c == 0x1EE4B) || (c >= 0x1EE4D && c <= 0x1EE4F) || (c >= 0x1EE51 && c <= 0x1EE52) || (c == 0x1EE54) || (c == 0x1EE57) || (c == 0x1EE59) || (c == 0x1EE5B) || (c == 0x1EE5D) || (c == 0x1EE5F) || (c >= 0x1EE61 && c <= 0x1EE62) || (c == 0x1EE64) || (c >= 0x1EE67 && c <= 0x1EE6A) || (c >= 0x1EE6C && c <= 0x1EE72) || (c >= 0x1EE74 && c <= 0x1EE77) || (c >= 0x1EE79 && c <= 0x1EE7C) || (c == 0x1EE7E) || (c >= 0x1EE80 && c <= 0x1EE89) || (c >= 0x1EE8B && c <= 0x1EE9B) || (c >= 0x1EEA1 && c <= 0x1EEA3) || (c >= 0x1EEA5 && c <= 0x1EEA9) || (c >= 0x1EEAB && c <= 0x1EEBB));
39 | }
40 |
41 | static BOOL isCodePointStrongLTR(UTF32Char c)
42 | {
43 | return (c >= 0x41 && c <= 0x5A) || (c >= 0x61 && c <= 0x7A) || (c == 0xAA) || (c == 0xB5) || (c == 0xBA) || (c >= 0xC0 && c <= 0xD6) || (c >= 0xD8 && c <= 0xF6) || (c >= 0xF8 && c <= 0x2B8) || (c >= 0x2BB && c <= 0x2C1) || (c >= 0x2D0 && c <= 0x2D1) || (c >= 0x2E0 && c <= 0x2E4) || (c == 0x2EE) || (c >= 0x370 && c <= 0x373) || (c >= 0x376 && c <= 0x377) || (c >= 0x37A && c <= 0x37D) || (c == 0x386) || (c >= 0x388 && c <= 0x38A) || (c == 0x38C) || (c >= 0x38E && c <= 0x3A1) || (c >= 0x3A3 && c <= 0x3F5) || (c >= 0x3F7 && c <= 0x482) || (c >= 0x48A && c <= 0x527) || (c >= 0x531 && c <= 0x556) || (c >= 0x559 && c <= 0x55F) || (c >= 0x561 && c <= 0x587) || (c == 0x589) || (c >= 0x903 && c <= 0x939) || (c == 0x93B) || (c >= 0x93D && c <= 0x940) || (c >= 0x949 && c <= 0x94C) || (c >= 0x94E && c <= 0x950) || (c >= 0x958 && c <= 0x961) || (c >= 0x964 && c <= 0x977) || (c >= 0x979 && c <= 0x97F) || (c >= 0x982 && c <= 0x983) || (c >= 0x985 && c <= 0x98C) || (c >= 0x98F && c <= 0x990) || (c >= 0x993 && c <= 0x9A8) || (c >= 0x9AA && c <= 0x9B0) || (c == 0x9B2) || (c >= 0x9B6 && c <= 0x9B9) || (c >= 0x9BD && c <= 0x9C0) || (c >= 0x9C7 && c <= 0x9C8) || (c >= 0x9CB && c <= 0x9CC) || (c == 0x9CE) || (c == 0x9D7) || (c >= 0x9DC && c <= 0x9DD) || (c >= 0x9DF && c <= 0x9E1) || (c >= 0x9E6 && c <= 0x9F1) || (c >= 0x9F4 && c <= 0x9FA) || (c == 0xA03) || (c >= 0xA05 && c <= 0xA0A) || (c >= 0xA0F && c <= 0xA10) || (c >= 0xA13 && c <= 0xA28) || (c >= 0xA2A && c <= 0xA30) || (c >= 0xA32 && c <= 0xA33) || (c >= 0xA35 && c <= 0xA36) || (c >= 0xA38 && c <= 0xA39) || (c >= 0xA3E && c <= 0xA40) || (c >= 0xA59 && c <= 0xA5C) || (c == 0xA5E) || (c >= 0xA66 && c <= 0xA6F) || (c >= 0xA72 && c <= 0xA74) || (c == 0xA83) || (c >= 0xA85 && c <= 0xA8D) || (c >= 0xA8F && c <= 0xA91) || (c >= 0xA93 && c <= 0xAA8) || (c >= 0xAAA && c <= 0xAB0) || (c >= 0xAB2 && c <= 0xAB3) || (c >= 0xAB5 && c <= 0xAB9) || (c >= 0xABD && c <= 0xAC0) || (c == 0xAC9) || (c >= 0xACB && c <= 0xACC) || (c == 0xAD0) || (c >= 0xAE0 && c <= 0xAE1) || (c >= 0xAE6 && c <= 0xAF0) || (c >= 0xB02 && c <= 0xB03) || (c >= 0xB05 && c <= 0xB0C) || (c >= 0xB0F && c <= 0xB10) || (c >= 0xB13 && c <= 0xB28) || (c >= 0xB2A && c <= 0xB30) || (c >= 0xB32 && c <= 0xB33) || (c >= 0xB35 && c <= 0xB39) || (c >= 0xB3D && c <= 0xB3E) || (c == 0xB40) || (c >= 0xB47 && c <= 0xB48) || (c >= 0xB4B && c <= 0xB4C) || (c == 0xB57) || (c >= 0xB5C && c <= 0xB5D) || (c >= 0xB5F && c <= 0xB61) || (c >= 0xB66 && c <= 0xB77) || (c == 0xB83) || (c >= 0xB85 && c <= 0xB8A) || (c >= 0xB8E && c <= 0xB90) || (c >= 0xB92 && c <= 0xB95) || (c >= 0xB99 && c <= 0xB9A) || (c == 0xB9C) || (c >= 0xB9E && c <= 0xB9F) || (c >= 0xBA3 && c <= 0xBA4) || (c >= 0xBA8 && c <= 0xBAA) || (c >= 0xBAE && c <= 0xBB9) || (c >= 0xBBE && c <= 0xBBF) || (c >= 0xBC1 && c <= 0xBC2) || (c >= 0xBC6 && c <= 0xBC8) || (c >= 0xBCA && c <= 0xBCC) || (c == 0xBD0) || (c == 0xBD7) || (c >= 0xBE6 && c <= 0xBF2) || (c >= 0xC01 && c <= 0xC03) || (c >= 0xC05 && c <= 0xC0C) || (c >= 0xC0E && c <= 0xC10) || (c >= 0xC12 && c <= 0xC28) || (c >= 0xC2A && c <= 0xC33) || (c >= 0xC35 && c <= 0xC39) || (c == 0xC3D) || (c >= 0xC41 && c <= 0xC44) || (c >= 0xC58 && c <= 0xC59) || (c >= 0xC60 && c <= 0xC61) || (c >= 0xC66 && c <= 0xC6F) || (c == 0xC7F) || (c >= 0xC82 && c <= 0xC83) || (c >= 0xC85 && c <= 0xC8C) || (c >= 0xC8E && c <= 0xC90) || (c >= 0xC92 && c <= 0xCA8) || (c >= 0xCAA && c <= 0xCB3) || (c >= 0xCB5 && c <= 0xCB9) || (c >= 0xCBD && c <= 0xCC4) || (c >= 0xCC6 && c <= 0xCC8) || (c >= 0xCCA && c <= 0xCCB) || (c >= 0xCD5 && c <= 0xCD6) || (c == 0xCDE) || (c >= 0xCE0 && c <= 0xCE1) || (c >= 0xCE6 && c <= 0xCEF) || (c >= 0xCF1 && c <= 0xCF2) || (c >= 0xD02 && c <= 0xD03) || (c >= 0xD05 && c <= 0xD0C) || (c >= 0xD0E && c <= 0xD10) || (c >= 0xD12 && c <= 0xD3A) || (c >= 0xD3D && c <= 0xD40) || (c >= 0xD46 && c <= 0xD48) || (c >= 0xD4A && c <= 0xD4C) || (c == 0xD4E) || (c == 0xD57) || (c >= 0xD60 && c <= 0xD61) || (c >= 0xD66 && c <= 0xD75) || (c >= 0xD79 && c <= 0xD7F) || (c >= 0xD82 && c <= 0xD83) || (c >= 0xD85 && c <= 0xD96) || (c >= 0xD9A && c <= 0xDB1) || (c >= 0xDB3 && c <= 0xDBB) || (c == 0xDBD) || (c >= 0xDC0 && c <= 0xDC6) || (c >= 0xDCF && c <= 0xDD1) || (c >= 0xDD8 && c <= 0xDDF) || (c >= 0xDF2 && c <= 0xDF4) || (c >= 0xE01 && c <= 0xE30) || (c >= 0xE32 && c <= 0xE33) || (c >= 0xE40 && c <= 0xE46) || (c >= 0xE4F && c <= 0xE5B) || (c >= 0xE81 && c <= 0xE82) || (c == 0xE84) || (c >= 0xE87 && c <= 0xE88) || (c == 0xE8A) || (c == 0xE8D) || (c >= 0xE94 && c <= 0xE97) || (c >= 0xE99 && c <= 0xE9F) || (c >= 0xEA1 && c <= 0xEA3) || (c == 0xEA5) || (c == 0xEA7) || (c >= 0xEAA && c <= 0xEAB) || (c >= 0xEAD && c <= 0xEB0) || (c >= 0xEB2 && c <= 0xEB3) || (c == 0xEBD) || (c >= 0xEC0 && c <= 0xEC4) || (c == 0xEC6) || (c >= 0xED0 && c <= 0xED9) || (c >= 0xEDC && c <= 0xEDF) || (c >= 0xF00 && c <= 0xF17) || (c >= 0xF1A && c <= 0xF34) || (c == 0xF36) || (c == 0xF38) || (c >= 0xF3E && c <= 0xF47) || (c >= 0xF49 && c <= 0xF6C) || (c == 0xF7F) || (c == 0xF85) || (c >= 0xF88 && c <= 0xF8C) || (c >= 0xFBE && c <= 0xFC5) || (c >= 0xFC7 && c <= 0xFCC) || (c >= 0xFCE && c <= 0xFDA) || (c >= 0x1000 && c <= 0x102C) || (c == 0x1031) || (c == 0x1038) || (c >= 0x103B && c <= 0x103C) || (c >= 0x103F && c <= 0x1057) || (c >= 0x105A && c <= 0x105D) || (c >= 0x1061 && c <= 0x1070) || (c >= 0x1075 && c <= 0x1081) || (c >= 0x1083 && c <= 0x1084) || (c >= 0x1087 && c <= 0x108C) || (c >= 0x108E && c <= 0x109C) || (c >= 0x109E && c <= 0x10C5) || (c == 0x10C7) || (c == 0x10CD) || (c >= 0x10D0 && c <= 0x1248) || (c >= 0x124A && c <= 0x124D) || (c >= 0x1250 && c <= 0x1256) || (c == 0x1258) || (c >= 0x125A && c <= 0x125D) || (c >= 0x1260 && c <= 0x1288) || (c >= 0x128A && c <= 0x128D) || (c >= 0x1290 && c <= 0x12B0) || (c >= 0x12B2 && c <= 0x12B5) || (c >= 0x12B8 && c <= 0x12BE) || (c == 0x12C0) || (c >= 0x12C2 && c <= 0x12C5) || (c >= 0x12C8 && c <= 0x12D6) || (c >= 0x12D8 && c <= 0x1310) || (c >= 0x1312 && c <= 0x1315) || (c >= 0x1318 && c <= 0x135A) || (c >= 0x1360 && c <= 0x137C) || (c >= 0x1380 && c <= 0x138F) || (c >= 0x13A0 && c <= 0x13F4) || (c >= 0x1401 && c <= 0x167F) || (c >= 0x1681 && c <= 0x169A) || (c >= 0x16A0 && c <= 0x16F0) || (c >= 0x1700 && c <= 0x170C) || (c >= 0x170E && c <= 0x1711) || (c >= 0x1720 && c <= 0x1731) || (c >= 0x1735 && c <= 0x1736) || (c >= 0x1740 && c <= 0x1751) || (c >= 0x1760 && c <= 0x176C) || (c >= 0x176E && c <= 0x1770) || (c >= 0x1780 && c <= 0x17B3) || (c == 0x17B6) || (c >= 0x17BE && c <= 0x17C5) || (c >= 0x17C7 && c <= 0x17C8) || (c >= 0x17D4 && c <= 0x17DA) || (c == 0x17DC) || (c >= 0x17E0 && c <= 0x17E9) || (c >= 0x1810 && c <= 0x1819) || (c >= 0x1820 && c <= 0x1877) || (c >= 0x1880 && c <= 0x18A8) || (c == 0x18AA) || (c >= 0x18B0 && c <= 0x18F5) || (c >= 0x1900 && c <= 0x191C) || (c >= 0x1923 && c <= 0x1926) || (c >= 0x1929 && c <= 0x192B) || (c >= 0x1930 && c <= 0x1931) || (c >= 0x1933 && c <= 0x1938) || (c >= 0x1946 && c <= 0x196D) || (c >= 0x1970 && c <= 0x1974) || (c >= 0x1980 && c <= 0x19AB) || (c >= 0x19B0 && c <= 0x19C9) || (c >= 0x19D0 && c <= 0x19DA) || (c >= 0x1A00 && c <= 0x1A16) || (c >= 0x1A19 && c <= 0x1A1B) || (c >= 0x1A1E && c <= 0x1A55) || (c == 0x1A57) || (c == 0x1A61) || (c >= 0x1A63 && c <= 0x1A64) || (c >= 0x1A6D && c <= 0x1A72) || (c >= 0x1A80 && c <= 0x1A89) || (c >= 0x1A90 && c <= 0x1A99) || (c >= 0x1AA0 && c <= 0x1AAD) || (c >= 0x1B04 && c <= 0x1B33) || (c == 0x1B35) || (c == 0x1B3B) || (c >= 0x1B3D && c <= 0x1B41) || (c >= 0x1B43 && c <= 0x1B4B) || (c >= 0x1B50 && c <= 0x1B6A) || (c >= 0x1B74 && c <= 0x1B7C) || (c >= 0x1B82 && c <= 0x1BA1) || (c >= 0x1BA6 && c <= 0x1BA7) || (c == 0x1BAA) || (c >= 0x1BAC && c <= 0x1BE5) || (c == 0x1BE7) || (c >= 0x1BEA && c <= 0x1BEC) || (c == 0x1BEE) || (c >= 0x1BF2 && c <= 0x1BF3) || (c >= 0x1BFC && c <= 0x1C2B) || (c >= 0x1C34 && c <= 0x1C35) || (c >= 0x1C3B && c <= 0x1C49) || (c >= 0x1C4D && c <= 0x1C7F) || (c >= 0x1CC0 && c <= 0x1CC7) || (c == 0x1CD3) || (c == 0x1CE1) || (c >= 0x1CE9 && c <= 0x1CEC) || (c >= 0x1CEE && c <= 0x1CF3) || (c >= 0x1CF5 && c <= 0x1CF6) || (c >= 0x1D00 && c <= 0x1DBF) || (c >= 0x1E00 && c <= 0x1F15) || (c >= 0x1F18 && c <= 0x1F1D) || (c >= 0x1F20 && c <= 0x1F45) || (c >= 0x1F48 && c <= 0x1F4D) || (c >= 0x1F50 && c <= 0x1F57) || (c == 0x1F59) || (c == 0x1F5B) || (c == 0x1F5D) || (c >= 0x1F5F && c <= 0x1F7D) || (c >= 0x1F80 && c <= 0x1FB4) || (c >= 0x1FB6 && c <= 0x1FBC) || (c == 0x1FBE) || (c >= 0x1FC2 && c <= 0x1FC4) || (c >= 0x1FC6 && c <= 0x1FCC) || (c >= 0x1FD0 && c <= 0x1FD3) || (c >= 0x1FD6 && c <= 0x1FDB) || (c >= 0x1FE0 && c <= 0x1FEC) || (c >= 0x1FF2 && c <= 0x1FF4) || (c >= 0x1FF6 && c <= 0x1FFC) || (c == 0x200E) || (c == 0x2071) || (c == 0x207F) || (c >= 0x2090 && c <= 0x209C) || (c == 0x2102) || (c == 0x2107) || (c >= 0x210A && c <= 0x2113) || (c == 0x2115) || (c >= 0x2119 && c <= 0x211D) || (c == 0x2124) || (c == 0x2126) || (c == 0x2128) || (c >= 0x212A && c <= 0x212D) || (c >= 0x212F && c <= 0x2139) || (c >= 0x213C && c <= 0x213F) || (c >= 0x2145 && c <= 0x2149) || (c >= 0x214E && c <= 0x214F) || (c >= 0x2160 && c <= 0x2188) || (c >= 0x2336 && c <= 0x237A) || (c == 0x2395) || (c >= 0x249C && c <= 0x24E9) || (c == 0x26AC) || (c >= 0x2800 && c <= 0x28FF) || (c >= 0x2C00 && c <= 0x2C2E) || (c >= 0x2C30 && c <= 0x2C5E) || (c >= 0x2C60 && c <= 0x2CE4) || (c >= 0x2CEB && c <= 0x2CEE) || (c >= 0x2CF2 && c <= 0x2CF3) || (c >= 0x2D00 && c <= 0x2D25) || (c == 0x2D27) || (c == 0x2D2D) || (c >= 0x2D30 && c <= 0x2D67) || (c >= 0x2D6F && c <= 0x2D70) || (c >= 0x2D80 && c <= 0x2D96) || (c >= 0x2DA0 && c <= 0x2DA6) || (c >= 0x2DA8 && c <= 0x2DAE) || (c >= 0x2DB0 && c <= 0x2DB6) || (c >= 0x2DB8 && c <= 0x2DBE) || (c >= 0x2DC0 && c <= 0x2DC6) || (c >= 0x2DC8 && c <= 0x2DCE) || (c >= 0x2DD0 && c <= 0x2DD6) || (c >= 0x2DD8 && c <= 0x2DDE) || (c >= 0x3005 && c <= 0x3007) || (c >= 0x3021 && c <= 0x3029) || (c >= 0x302E && c <= 0x302F) || (c >= 0x3031 && c <= 0x3035) || (c >= 0x3038 && c <= 0x303C) || (c >= 0x3041 && c <= 0x3096) || (c >= 0x309D && c <= 0x309F) || (c >= 0x30A1 && c <= 0x30FA) || (c >= 0x30FC && c <= 0x30FF) || (c >= 0x3105 && c <= 0x312D) || (c >= 0x3131 && c <= 0x318E) || (c >= 0x3190 && c <= 0x31BA) || (c >= 0x31F0 && c <= 0x321C) || (c >= 0x3220 && c <= 0x324F) || (c >= 0x3260 && c <= 0x327B) || (c >= 0x327F && c <= 0x32B0) || (c >= 0x32C0 && c <= 0x32CB) || (c >= 0x32D0 && c <= 0x32FE) || (c >= 0x3300 && c <= 0x3376) || (c >= 0x337B && c <= 0x33DD) || (c >= 0x33E0 && c <= 0x33FE) || (c == 0x3400) || (c == 0x4DB5) || (c == 0x4E00) || (c == 0x9FCC) || (c >= 0xA000 && c <= 0xA48C) || (c >= 0xA4D0 && c <= 0xA60C) || (c >= 0xA610 && c <= 0xA62B) || (c >= 0xA640 && c <= 0xA66E) || (c >= 0xA680 && c <= 0xA697) || (c >= 0xA6A0 && c <= 0xA6EF) || (c >= 0xA6F2 && c <= 0xA6F7) || (c >= 0xA722 && c <= 0xA787) || (c >= 0xA789 && c <= 0xA78E) || (c >= 0xA790 && c <= 0xA793) || (c >= 0xA7A0 && c <= 0xA7AA) || (c >= 0xA7F8 && c <= 0xA801) || (c >= 0xA803 && c <= 0xA805) || (c >= 0xA807 && c <= 0xA80A) || (c >= 0xA80C && c <= 0xA824) || (c == 0xA827) || (c >= 0xA830 && c <= 0xA837) || (c >= 0xA840 && c <= 0xA873) || (c >= 0xA880 && c <= 0xA8C3) || (c >= 0xA8CE && c <= 0xA8D9) || (c >= 0xA8F2 && c <= 0xA8FB) || (c >= 0xA900 && c <= 0xA925) || (c >= 0xA92E && c <= 0xA946) || (c >= 0xA952 && c <= 0xA953) || (c >= 0xA95F && c <= 0xA97C) || (c >= 0xA983 && c <= 0xA9B2) || (c >= 0xA9B4 && c <= 0xA9B5) || (c >= 0xA9BA && c <= 0xA9BB) || (c >= 0xA9BD && c <= 0xA9CD) || (c >= 0xA9CF && c <= 0xA9D9) || (c >= 0xA9DE && c <= 0xA9DF) || (c >= 0xAA00 && c <= 0xAA28) || (c >= 0xAA2F && c <= 0xAA30) || (c >= 0xAA33 && c <= 0xAA34) || (c >= 0xAA40 && c <= 0xAA42) || (c >= 0xAA44 && c <= 0xAA4B) || (c == 0xAA4D) || (c >= 0xAA50 && c <= 0xAA59) || (c >= 0xAA5C && c <= 0xAA7B) || (c >= 0xAA80 && c <= 0xAAAF) || (c == 0xAAB1) || (c >= 0xAAB5 && c <= 0xAAB6) || (c >= 0xAAB9 && c <= 0xAABD) || (c == 0xAAC0) || (c == 0xAAC2) || (c >= 0xAADB && c <= 0xAAEB) || (c >= 0xAAEE && c <= 0xAAF5) || (c >= 0xAB01 && c <= 0xAB06) || (c >= 0xAB09 && c <= 0xAB0E) || (c >= 0xAB11 && c <= 0xAB16) || (c >= 0xAB20 && c <= 0xAB26) || (c >= 0xAB28 && c <= 0xAB2E) || (c >= 0xABC0 && c <= 0xABE4) || (c >= 0xABE6 && c <= 0xABE7) || (c >= 0xABE9 && c <= 0xABEC) || (c >= 0xABF0 && c <= 0xABF9) || (c == 0xAC00) || (c == 0xD7A3) || (c >= 0xD7B0 && c <= 0xD7C6) || (c >= 0xD7CB && c <= 0xD7FB) || (c == 0xD800) || (c >= 0xDB7F && c <= 0xDB80) || (c >= 0xDBFF && c <= 0xDC00) || (c >= 0xDFFF && c <= 0xE000) || (c >= 0xF8FF && c <= 0xFA6D) || (c >= 0xFA70 && c <= 0xFAD9) || (c >= 0xFB00 && c <= 0xFB06) || (c >= 0xFB13 && c <= 0xFB17) || (c >= 0xFF21 && c <= 0xFF3A) || (c >= 0xFF41 && c <= 0xFF5A) || (c >= 0xFF66 && c <= 0xFFBE) || (c >= 0xFFC2 && c <= 0xFFC7) || (c >= 0xFFCA && c <= 0xFFCF) || (c >= 0xFFD2 && c <= 0xFFD7) || (c >= 0xFFDA && c <= 0xFFDC) || (c >= 0x10000 && c <= 0x1000B) || (c >= 0x1000D && c <= 0x10026) || (c >= 0x10028 && c <= 0x1003A) || (c >= 0x1003C && c <= 0x1003D) || (c >= 0x1003F && c <= 0x1004D) || (c >= 0x10050 && c <= 0x1005D) || (c >= 0x10080 && c <= 0x100FA) || (c == 0x10100) || (c == 0x10102) || (c >= 0x10107 && c <= 0x10133) || (c >= 0x10137 && c <= 0x1013F) || (c >= 0x101D0 && c <= 0x101FC) || (c >= 0x10280 && c <= 0x1029C) || (c >= 0x102A0 && c <= 0x102D0) || (c >= 0x10300 && c <= 0x1031E) || (c >= 0x10320 && c <= 0x10323) || (c >= 0x10330 && c <= 0x1034A) || (c >= 0x10380 && c <= 0x1039D) || (c >= 0x1039F && c <= 0x103C3) || (c >= 0x103C8 && c <= 0x103D5) || (c >= 0x10400 && c <= 0x1049D) || (c >= 0x104A0 && c <= 0x104A9) || (c == 0x11000) || (c >= 0x11002 && c <= 0x11037) || (c >= 0x11047 && c <= 0x1104D) || (c >= 0x11066 && c <= 0x1106F) || (c >= 0x11082 && c <= 0x110B2) || (c >= 0x110B7 && c <= 0x110B8) || (c >= 0x110BB && c <= 0x110C1) || (c >= 0x110D0 && c <= 0x110E8) || (c >= 0x110F0 && c <= 0x110F9) || (c >= 0x11103 && c <= 0x11126) || (c == 0x1112C) || (c >= 0x11136 && c <= 0x11143) || (c >= 0x11182 && c <= 0x111B5) || (c >= 0x111BF && c <= 0x111C8) || (c >= 0x111D0 && c <= 0x111D9) || (c >= 0x11680 && c <= 0x116AA) || (c == 0x116AC) || (c >= 0x116AE && c <= 0x116AF) || (c == 0x116B6) || (c >= 0x116C0 && c <= 0x116C9) || (c >= 0x12000 && c <= 0x1236E) || (c >= 0x12400 && c <= 0x12462) || (c >= 0x12470 && c <= 0x12473) || (c >= 0x13000 && c <= 0x1342E) || (c >= 0x16800 && c <= 0x16A38) || (c >= 0x16F00 && c <= 0x16F44) || (c >= 0x16F50 && c <= 0x16F7E) || (c >= 0x16F93 && c <= 0x16F9F) || (c >= 0x1B000 && c <= 0x1B001) || (c >= 0x1D000 && c <= 0x1D0F5) || (c >= 0x1D100 && c <= 0x1D126) || (c >= 0x1D129 && c <= 0x1D166) || (c >= 0x1D16A && c <= 0x1D172) || (c >= 0x1D183 && c <= 0x1D184) || (c >= 0x1D18C && c <= 0x1D1A9) || (c >= 0x1D1AE && c <= 0x1D1DD) || (c >= 0x1D360 && c <= 0x1D371) || (c >= 0x1D400 && c <= 0x1D454) || (c >= 0x1D456 && c <= 0x1D49C) || (c >= 0x1D49E && c <= 0x1D49F) || (c == 0x1D4A2) || (c >= 0x1D4A5 && c <= 0x1D4A6) || (c >= 0x1D4A9 && c <= 0x1D4AC) || (c >= 0x1D4AE && c <= 0x1D4B9) || (c == 0x1D4BB) || (c >= 0x1D4BD && c <= 0x1D4C3) || (c >= 0x1D4C5 && c <= 0x1D505) || (c >= 0x1D507 && c <= 0x1D50A) || (c >= 0x1D50D && c <= 0x1D514) || (c >= 0x1D516 && c <= 0x1D51C) || (c >= 0x1D51E && c <= 0x1D539) || (c >= 0x1D53B && c <= 0x1D53E) || (c >= 0x1D540 && c <= 0x1D544) || (c == 0x1D546) || (c >= 0x1D54A && c <= 0x1D550) || (c >= 0x1D552 && c <= 0x1D6A5) || (c >= 0x1D6A8 && c <= 0x1D6DA) || (c >= 0x1D6DC && c <= 0x1D714) || (c >= 0x1D716 && c <= 0x1D74E) || (c >= 0x1D750 && c <= 0x1D788) || (c >= 0x1D78A && c <= 0x1D7C2) || (c >= 0x1D7C4 && c <= 0x1D7CB) || (c >= 0x1F110 && c <= 0x1F12E) || (c >= 0x1F130 && c <= 0x1F169) || (c >= 0x1F170 && c <= 0x1F19A) || (c >= 0x1F1E6 && c <= 0x1F202) || (c >= 0x1F210 && c <= 0x1F23A) || (c >= 0x1F240 && c <= 0x1F248) || (c >= 0x1F250 && c <= 0x1F251) || (c == 0x20000) || (c == 0x2A6D6) || (c == 0x2A700) || (c == 0x2B734) || (c == 0x2B740) || (c == 0x2B81D) || (c >= 0x2F800 && c <= 0x2FA1D) || (c == 0xF0000) || (c == 0xFFFFD) || (c == 0x100000) || (c == 0x10FFFD);
44 | }
45 |
46 | - (JVTextDirection)getBaseDirection
47 | {
48 | // Decode string into UTF32.
49 | NSData *utf32data = [self dataUsingEncoding:NSUTF32StringEncoding];
50 | // NSUTF32StringEncoding has the platform's byte-order, which should
51 | // be the same as UTF32Char's.
52 | UTF32Char *utf32chars = (UTF32Char *)[utf32data bytes];
53 |
54 | for (NSUInteger i = 0; i < self.length; i++) {
55 | // UTF32 is a fixed-length encoding, so utf32chars[i] will
56 | // always give us the i'th character.
57 | if (isCodePointStrongRTL(utf32chars[i]))
58 | return JVTextDirectionRightToLeft;
59 | if (isCodePointStrongLTR(utf32chars[i]))
60 | return JVTextDirectionLeftToRight;
61 | }
62 | return JVTextDirectionNeutral;
63 | }
64 |
65 | @end
--------------------------------------------------------------------------------
/JVFloatLabeledTextField.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 4306C37419531E7000CC0A4C /* NSString+TextDirectionality.m in Sources */ = {isa = PBXBuildFile; fileRef = 4306C37319531E7000CC0A4C /* NSString+TextDirectionality.m */; };
11 | 639EABFA1B0B5F79001DD7B5 /* JVFloatLabeledTextField.h in Headers */ = {isa = PBXBuildFile; fileRef = 7FF4DB92180B865F008527BD /* JVFloatLabeledTextField.h */; settings = {ATTRIBUTES = (Public, ); }; };
12 | 639EABFB1B0B5F79001DD7B5 /* JVFloatLabeledTextView.h in Headers */ = {isa = PBXBuildFile; fileRef = 7F9AB495183B2EBF00694AB0 /* JVFloatLabeledTextView.h */; settings = {ATTRIBUTES = (Public, ); }; };
13 | 639EABFC1B0B5F79001DD7B5 /* NSString+TextDirectionality.h in Headers */ = {isa = PBXBuildFile; fileRef = 4306C37219531E7000CC0A4C /* NSString+TextDirectionality.h */; };
14 | 639EABFD1B0B5F83001DD7B5 /* JVFloatLabeledTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FF4DB93180B865F008527BD /* JVFloatLabeledTextField.m */; };
15 | 639EABFE1B0B5F83001DD7B5 /* JVFloatLabeledTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F9AB496183B2EBF00694AB0 /* JVFloatLabeledTextView.m */; };
16 | 639EABFF1B0B5F83001DD7B5 /* NSString+TextDirectionality.m in Sources */ = {isa = PBXBuildFile; fileRef = 4306C37319531E7000CC0A4C /* NSString+TextDirectionality.m */; };
17 | 639EAC011B0B6013001DD7B5 /* JVFloatLabeledText.h in Headers */ = {isa = PBXBuildFile; fileRef = 639EABF41B0B5EC6001DD7B5 /* JVFloatLabeledText.h */; settings = {ATTRIBUTES = (Public, ); }; };
18 | 7F394935199DE5E10069C867 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7F394934199DE5E10069C867 /* XCTest.framework */; };
19 | 7F394936199DE5E10069C867 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7F50335917FA7B0A0026FB7F /* Foundation.framework */; };
20 | 7F394937199DE5E10069C867 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7F50335D17FA7B0A0026FB7F /* UIKit.framework */; };
21 | 7F39493D199DE5E10069C867 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7F39493B199DE5E10069C867 /* InfoPlist.strings */; };
22 | 7F39493F199DE5E10069C867 /* JVFloatLabeledTextFieldTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F39493E199DE5E10069C867 /* JVFloatLabeledTextFieldTests.m */; };
23 | 7F394949199DE8B20069C867 /* JVFloatLabeledTextViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F394948199DE8B20069C867 /* JVFloatLabeledTextViewTests.m */; };
24 | 7F50335A17FA7B0A0026FB7F /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7F50335917FA7B0A0026FB7F /* Foundation.framework */; };
25 | 7F50335E17FA7B0A0026FB7F /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7F50335D17FA7B0A0026FB7F /* UIKit.framework */; };
26 | 7F50336617FA7B0A0026FB7F /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F50336517FA7B0A0026FB7F /* main.m */; };
27 | 7F50336A17FA7B0A0026FB7F /* JVAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F50336917FA7B0A0026FB7F /* JVAppDelegate.m */; };
28 | 7F50338E17FA7B8C0026FB7F /* JVFloatLabeledTextFieldViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F50338D17FA7B8C0026FB7F /* JVFloatLabeledTextFieldViewController.m */; };
29 | 7F9020231809A39B00B43AD5 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7F9020201809A39B00B43AD5 /* Default-568h@2x.png */; };
30 | 7F9020241809A39B00B43AD5 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 7F9020211809A39B00B43AD5 /* Default.png */; };
31 | 7F9020251809A39B00B43AD5 /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7F9020221809A39B00B43AD5 /* Default@2x.png */; };
32 | 7F9AB497183B2EBF00694AB0 /* JVFloatLabeledTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 7F9AB496183B2EBF00694AB0 /* JVFloatLabeledTextView.m */; };
33 | 7FE3F0E41CB0598B00202683 /* JVFloatLabeledTextFieldXIBViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FE3F0E21CB0598B00202683 /* JVFloatLabeledTextFieldXIBViewController.m */; };
34 | 7FE3F0E51CB0598B00202683 /* JVFloatLabeledTextFieldXIBViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7FE3F0E31CB0598B00202683 /* JVFloatLabeledTextFieldXIBViewController.xib */; };
35 | 7FF4DB94180B865F008527BD /* JVFloatLabeledTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 7FF4DB93180B865F008527BD /* JVFloatLabeledTextField.m */; };
36 | /* End PBXBuildFile section */
37 |
38 | /* Begin PBXContainerItemProxy section */
39 | 7F394941199DE5E10069C867 /* PBXContainerItemProxy */ = {
40 | isa = PBXContainerItemProxy;
41 | containerPortal = 7F50334E17FA7B0A0026FB7F /* Project object */;
42 | proxyType = 1;
43 | remoteGlobalIDString = 7F50335517FA7B0A0026FB7F;
44 | remoteInfo = JVFloatLabeledTextField;
45 | };
46 | /* End PBXContainerItemProxy section */
47 |
48 | /* Begin PBXCopyFilesBuildPhase section */
49 | 639EABCD1B0B5D6C001DD7B5 /* Embed Frameworks */ = {
50 | isa = PBXCopyFilesBuildPhase;
51 | buildActionMask = 2147483647;
52 | dstPath = "";
53 | dstSubfolderSpec = 10;
54 | files = (
55 | );
56 | name = "Embed Frameworks";
57 | runOnlyForDeploymentPostprocessing = 0;
58 | };
59 | /* End PBXCopyFilesBuildPhase section */
60 |
61 | /* Begin PBXFileReference section */
62 | 4306C37219531E7000CC0A4C /* NSString+TextDirectionality.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+TextDirectionality.h"; sourceTree = ""; };
63 | 4306C37319531E7000CC0A4C /* NSString+TextDirectionality.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+TextDirectionality.m"; sourceTree = ""; };
64 | 639EABD51B0B5E6F001DD7B5 /* JVFloatLabeledText.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = JVFloatLabeledText.framework; sourceTree = BUILT_PRODUCTS_DIR; };
65 | 639EABF41B0B5EC6001DD7B5 /* JVFloatLabeledText.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JVFloatLabeledText.h; sourceTree = ""; };
66 | 639EABF51B0B5EC6001DD7B5 /* JVFloatLabeledText-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "JVFloatLabeledText-Info.plist"; sourceTree = ""; };
67 | 7F394933199DE5E10069C867 /* JVFloatLabeledTextFieldTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = JVFloatLabeledTextFieldTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
68 | 7F394934199DE5E10069C867 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
69 | 7F39493A199DE5E10069C867 /* JVFloatLabeledTextFieldTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "JVFloatLabeledTextFieldTests-Info.plist"; sourceTree = ""; };
70 | 7F39493C199DE5E10069C867 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
71 | 7F39493E199DE5E10069C867 /* JVFloatLabeledTextFieldTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = JVFloatLabeledTextFieldTests.m; sourceTree = ""; };
72 | 7F394940199DE5E10069C867 /* JVFloatLabeledTextFieldTests-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "JVFloatLabeledTextFieldTests-Prefix.pch"; sourceTree = ""; };
73 | 7F394948199DE8B20069C867 /* JVFloatLabeledTextViewTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JVFloatLabeledTextViewTests.m; sourceTree = ""; };
74 | 7F50335617FA7B0A0026FB7F /* JVFloatLabeledTextField.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = JVFloatLabeledTextField.app; sourceTree = BUILT_PRODUCTS_DIR; };
75 | 7F50335917FA7B0A0026FB7F /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
76 | 7F50335D17FA7B0A0026FB7F /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
77 | 7F50336117FA7B0A0026FB7F /* JVFloatLabeledTextField-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "JVFloatLabeledTextField-Info.plist"; sourceTree = ""; };
78 | 7F50336517FA7B0A0026FB7F /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
79 | 7F50336717FA7B0A0026FB7F /* JVFloatLabeledTextField-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "JVFloatLabeledTextField-Prefix.pch"; sourceTree = ""; };
80 | 7F50336817FA7B0A0026FB7F /* JVAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JVAppDelegate.h; sourceTree = ""; };
81 | 7F50336917FA7B0A0026FB7F /* JVAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = JVAppDelegate.m; sourceTree = ""; };
82 | 7F50338C17FA7B8C0026FB7F /* JVFloatLabeledTextFieldViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JVFloatLabeledTextFieldViewController.h; sourceTree = ""; };
83 | 7F50338D17FA7B8C0026FB7F /* JVFloatLabeledTextFieldViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JVFloatLabeledTextFieldViewController.m; sourceTree = ""; };
84 | 7F83A3911A6E088B00C6CAA2 /* JVFloatLabeledTextField.podspec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = JVFloatLabeledTextField.podspec; sourceTree = ""; };
85 | 7F83A3921A6E088B00C6CAA2 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = ""; };
86 | 7F83A3931A6E088B00C6CAA2 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; };
87 | 7F9020201809A39B00B43AD5 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default-568h@2x.png"; path = "images/Default-568h@2x.png"; sourceTree = ""; };
88 | 7F9020211809A39B00B43AD5 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Default.png; path = images/Default.png; sourceTree = ""; };
89 | 7F9020221809A39B00B43AD5 /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default@2x.png"; path = "images/Default@2x.png"; sourceTree = ""; };
90 | 7F9AB495183B2EBF00694AB0 /* JVFloatLabeledTextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JVFloatLabeledTextView.h; sourceTree = ""; };
91 | 7F9AB496183B2EBF00694AB0 /* JVFloatLabeledTextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JVFloatLabeledTextView.m; sourceTree = ""; };
92 | 7FE3F0E11CB0598B00202683 /* JVFloatLabeledTextFieldXIBViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JVFloatLabeledTextFieldXIBViewController.h; sourceTree = ""; };
93 | 7FE3F0E21CB0598B00202683 /* JVFloatLabeledTextFieldXIBViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JVFloatLabeledTextFieldXIBViewController.m; sourceTree = ""; };
94 | 7FE3F0E31CB0598B00202683 /* JVFloatLabeledTextFieldXIBViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = JVFloatLabeledTextFieldXIBViewController.xib; sourceTree = ""; };
95 | 7FF4DB92180B865F008527BD /* JVFloatLabeledTextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JVFloatLabeledTextField.h; sourceTree = ""; };
96 | 7FF4DB93180B865F008527BD /* JVFloatLabeledTextField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JVFloatLabeledTextField.m; sourceTree = ""; };
97 | /* End PBXFileReference section */
98 |
99 | /* Begin PBXFrameworksBuildPhase section */
100 | 639EABD11B0B5E6F001DD7B5 /* Frameworks */ = {
101 | isa = PBXFrameworksBuildPhase;
102 | buildActionMask = 2147483647;
103 | files = (
104 | );
105 | runOnlyForDeploymentPostprocessing = 0;
106 | };
107 | 7F394930199DE5E10069C867 /* Frameworks */ = {
108 | isa = PBXFrameworksBuildPhase;
109 | buildActionMask = 2147483647;
110 | files = (
111 | 7F394935199DE5E10069C867 /* XCTest.framework in Frameworks */,
112 | 7F394937199DE5E10069C867 /* UIKit.framework in Frameworks */,
113 | 7F394936199DE5E10069C867 /* Foundation.framework in Frameworks */,
114 | );
115 | runOnlyForDeploymentPostprocessing = 0;
116 | };
117 | 7F50335317FA7B0A0026FB7F /* Frameworks */ = {
118 | isa = PBXFrameworksBuildPhase;
119 | buildActionMask = 2147483647;
120 | files = (
121 | 7F50335E17FA7B0A0026FB7F /* UIKit.framework in Frameworks */,
122 | 7F50335A17FA7B0A0026FB7F /* Foundation.framework in Frameworks */,
123 | );
124 | runOnlyForDeploymentPostprocessing = 0;
125 | };
126 | /* End PBXFrameworksBuildPhase section */
127 |
128 | /* Begin PBXGroup section */
129 | 7F394938199DE5E10069C867 /* JVFloatLabeledTextFieldTests */ = {
130 | isa = PBXGroup;
131 | children = (
132 | 7F39493E199DE5E10069C867 /* JVFloatLabeledTextFieldTests.m */,
133 | 7F394948199DE8B20069C867 /* JVFloatLabeledTextViewTests.m */,
134 | 7F394939199DE5E10069C867 /* Supporting Files */,
135 | );
136 | path = JVFloatLabeledTextFieldTests;
137 | sourceTree = "";
138 | };
139 | 7F394939199DE5E10069C867 /* Supporting Files */ = {
140 | isa = PBXGroup;
141 | children = (
142 | 7F39493A199DE5E10069C867 /* JVFloatLabeledTextFieldTests-Info.plist */,
143 | 7F39493B199DE5E10069C867 /* InfoPlist.strings */,
144 | 7F394940199DE5E10069C867 /* JVFloatLabeledTextFieldTests-Prefix.pch */,
145 | );
146 | name = "Supporting Files";
147 | sourceTree = "";
148 | };
149 | 7F50334D17FA7B0A0026FB7F = {
150 | isa = PBXGroup;
151 | children = (
152 | 7F83A3911A6E088B00C6CAA2 /* JVFloatLabeledTextField.podspec */,
153 | 7F83A3921A6E088B00C6CAA2 /* LICENSE */,
154 | 7F83A3931A6E088B00C6CAA2 /* README.md */,
155 | 7F50335F17FA7B0A0026FB7F /* JVFloatLabeledTextField */,
156 | 7F394938199DE5E10069C867 /* JVFloatLabeledTextFieldTests */,
157 | 7F50335817FA7B0A0026FB7F /* Frameworks */,
158 | 7F50335717FA7B0A0026FB7F /* Products */,
159 | );
160 | sourceTree = "";
161 | };
162 | 7F50335717FA7B0A0026FB7F /* Products */ = {
163 | isa = PBXGroup;
164 | children = (
165 | 7F50335617FA7B0A0026FB7F /* JVFloatLabeledTextField.app */,
166 | 7F394933199DE5E10069C867 /* JVFloatLabeledTextFieldTests.xctest */,
167 | 639EABD51B0B5E6F001DD7B5 /* JVFloatLabeledText.framework */,
168 | );
169 | name = Products;
170 | sourceTree = "";
171 | };
172 | 7F50335817FA7B0A0026FB7F /* Frameworks */ = {
173 | isa = PBXGroup;
174 | children = (
175 | 7F50335917FA7B0A0026FB7F /* Foundation.framework */,
176 | 7F50335D17FA7B0A0026FB7F /* UIKit.framework */,
177 | 7F394934199DE5E10069C867 /* XCTest.framework */,
178 | );
179 | name = Frameworks;
180 | sourceTree = "";
181 | };
182 | 7F50335F17FA7B0A0026FB7F /* JVFloatLabeledTextField */ = {
183 | isa = PBXGroup;
184 | children = (
185 | 7F50336817FA7B0A0026FB7F /* JVAppDelegate.h */,
186 | 7F50336917FA7B0A0026FB7F /* JVAppDelegate.m */,
187 | 7FF4DB91180B865F008527BD /* JVFloatLabeledTextField */,
188 | 7F50338C17FA7B8C0026FB7F /* JVFloatLabeledTextFieldViewController.h */,
189 | 7F50338D17FA7B8C0026FB7F /* JVFloatLabeledTextFieldViewController.m */,
190 | 7FE3F0E11CB0598B00202683 /* JVFloatLabeledTextFieldXIBViewController.h */,
191 | 7FE3F0E21CB0598B00202683 /* JVFloatLabeledTextFieldXIBViewController.m */,
192 | 7FE3F0E31CB0598B00202683 /* JVFloatLabeledTextFieldXIBViewController.xib */,
193 | 7F50336017FA7B0A0026FB7F /* Supporting Files */,
194 | );
195 | path = JVFloatLabeledTextField;
196 | sourceTree = "";
197 | };
198 | 7F50336017FA7B0A0026FB7F /* Supporting Files */ = {
199 | isa = PBXGroup;
200 | children = (
201 | 639EABF41B0B5EC6001DD7B5 /* JVFloatLabeledText.h */,
202 | 639EABF51B0B5EC6001DD7B5 /* JVFloatLabeledText-Info.plist */,
203 | 7F90201F1809A2BF00B43AD5 /* images */,
204 | 7F50336117FA7B0A0026FB7F /* JVFloatLabeledTextField-Info.plist */,
205 | 7F50336717FA7B0A0026FB7F /* JVFloatLabeledTextField-Prefix.pch */,
206 | 7F50336517FA7B0A0026FB7F /* main.m */,
207 | );
208 | name = "Supporting Files";
209 | sourceTree = "";
210 | };
211 | 7F90201F1809A2BF00B43AD5 /* images */ = {
212 | isa = PBXGroup;
213 | children = (
214 | 7F9020201809A39B00B43AD5 /* Default-568h@2x.png */,
215 | 7F9020211809A39B00B43AD5 /* Default.png */,
216 | 7F9020221809A39B00B43AD5 /* Default@2x.png */,
217 | );
218 | name = images;
219 | sourceTree = "";
220 | };
221 | 7FF4DB91180B865F008527BD /* JVFloatLabeledTextField */ = {
222 | isa = PBXGroup;
223 | children = (
224 | 7FF4DB92180B865F008527BD /* JVFloatLabeledTextField.h */,
225 | 7FF4DB93180B865F008527BD /* JVFloatLabeledTextField.m */,
226 | 7F9AB495183B2EBF00694AB0 /* JVFloatLabeledTextView.h */,
227 | 7F9AB496183B2EBF00694AB0 /* JVFloatLabeledTextView.m */,
228 | 4306C37219531E7000CC0A4C /* NSString+TextDirectionality.h */,
229 | 4306C37319531E7000CC0A4C /* NSString+TextDirectionality.m */,
230 | );
231 | path = JVFloatLabeledTextField;
232 | sourceTree = "";
233 | };
234 | /* End PBXGroup section */
235 |
236 | /* Begin PBXHeadersBuildPhase section */
237 | 639EABD21B0B5E6F001DD7B5 /* Headers */ = {
238 | isa = PBXHeadersBuildPhase;
239 | buildActionMask = 2147483647;
240 | files = (
241 | 639EAC011B0B6013001DD7B5 /* JVFloatLabeledText.h in Headers */,
242 | 639EABFA1B0B5F79001DD7B5 /* JVFloatLabeledTextField.h in Headers */,
243 | 639EABFB1B0B5F79001DD7B5 /* JVFloatLabeledTextView.h in Headers */,
244 | 639EABFC1B0B5F79001DD7B5 /* NSString+TextDirectionality.h in Headers */,
245 | );
246 | runOnlyForDeploymentPostprocessing = 0;
247 | };
248 | /* End PBXHeadersBuildPhase section */
249 |
250 | /* Begin PBXNativeTarget section */
251 | 639EABD41B0B5E6F001DD7B5 /* JVFloatLabeledText */ = {
252 | isa = PBXNativeTarget;
253 | buildConfigurationList = 639EABEE1B0B5E6F001DD7B5 /* Build configuration list for PBXNativeTarget "JVFloatLabeledText" */;
254 | buildPhases = (
255 | 639EABD01B0B5E6F001DD7B5 /* Sources */,
256 | 639EABD11B0B5E6F001DD7B5 /* Frameworks */,
257 | 639EABD21B0B5E6F001DD7B5 /* Headers */,
258 | 639EABD31B0B5E6F001DD7B5 /* Resources */,
259 | );
260 | buildRules = (
261 | );
262 | dependencies = (
263 | );
264 | name = JVFloatLabeledText;
265 | productName = Framework;
266 | productReference = 639EABD51B0B5E6F001DD7B5 /* JVFloatLabeledText.framework */;
267 | productType = "com.apple.product-type.framework";
268 | };
269 | 7F394932199DE5E10069C867 /* JVFloatLabeledTextFieldTests */ = {
270 | isa = PBXNativeTarget;
271 | buildConfigurationList = 7F394943199DE5E10069C867 /* Build configuration list for PBXNativeTarget "JVFloatLabeledTextFieldTests" */;
272 | buildPhases = (
273 | 7F39492F199DE5E10069C867 /* Sources */,
274 | 7F394930199DE5E10069C867 /* Frameworks */,
275 | 7F394931199DE5E10069C867 /* Resources */,
276 | );
277 | buildRules = (
278 | );
279 | dependencies = (
280 | 7F394942199DE5E10069C867 /* PBXTargetDependency */,
281 | );
282 | name = JVFloatLabeledTextFieldTests;
283 | productName = JVFloatLabeledTextFieldTests;
284 | productReference = 7F394933199DE5E10069C867 /* JVFloatLabeledTextFieldTests.xctest */;
285 | productType = "com.apple.product-type.bundle.unit-test";
286 | };
287 | 7F50335517FA7B0A0026FB7F /* JVFloatLabeledTextField */ = {
288 | isa = PBXNativeTarget;
289 | buildConfigurationList = 7F50338217FA7B0A0026FB7F /* Build configuration list for PBXNativeTarget "JVFloatLabeledTextField" */;
290 | buildPhases = (
291 | 7F50335217FA7B0A0026FB7F /* Sources */,
292 | 7F50335317FA7B0A0026FB7F /* Frameworks */,
293 | 7F50335417FA7B0A0026FB7F /* Resources */,
294 | 639EABCD1B0B5D6C001DD7B5 /* Embed Frameworks */,
295 | );
296 | buildRules = (
297 | );
298 | dependencies = (
299 | );
300 | name = JVFloatLabeledTextField;
301 | productName = JVFloatLabeledField;
302 | productReference = 7F50335617FA7B0A0026FB7F /* JVFloatLabeledTextField.app */;
303 | productType = "com.apple.product-type.application";
304 | };
305 | /* End PBXNativeTarget section */
306 |
307 | /* Begin PBXProject section */
308 | 7F50334E17FA7B0A0026FB7F /* Project object */ = {
309 | isa = PBXProject;
310 | attributes = {
311 | CLASSPREFIX = JV;
312 | LastUpgradeCheck = 0900;
313 | ORGANIZATIONNAME = "Jared Verdi";
314 | TargetAttributes = {
315 | 639EABD41B0B5E6F001DD7B5 = {
316 | CreatedOnToolsVersion = 6.3.1;
317 | };
318 | 7F394932199DE5E10069C867 = {
319 | TestTargetID = 7F50335517FA7B0A0026FB7F;
320 | };
321 | };
322 | };
323 | buildConfigurationList = 7F50335117FA7B0A0026FB7F /* Build configuration list for PBXProject "JVFloatLabeledTextField" */;
324 | compatibilityVersion = "Xcode 3.2";
325 | developmentRegion = English;
326 | hasScannedForEncodings = 0;
327 | knownRegions = (
328 | English,
329 | en,
330 | ar,
331 | );
332 | mainGroup = 7F50334D17FA7B0A0026FB7F;
333 | productRefGroup = 7F50335717FA7B0A0026FB7F /* Products */;
334 | projectDirPath = "";
335 | projectRoot = "";
336 | targets = (
337 | 7F50335517FA7B0A0026FB7F /* JVFloatLabeledTextField */,
338 | 7F394932199DE5E10069C867 /* JVFloatLabeledTextFieldTests */,
339 | 639EABD41B0B5E6F001DD7B5 /* JVFloatLabeledText */,
340 | );
341 | };
342 | /* End PBXProject section */
343 |
344 | /* Begin PBXResourcesBuildPhase section */
345 | 639EABD31B0B5E6F001DD7B5 /* Resources */ = {
346 | isa = PBXResourcesBuildPhase;
347 | buildActionMask = 2147483647;
348 | files = (
349 | );
350 | runOnlyForDeploymentPostprocessing = 0;
351 | };
352 | 7F394931199DE5E10069C867 /* Resources */ = {
353 | isa = PBXResourcesBuildPhase;
354 | buildActionMask = 2147483647;
355 | files = (
356 | 7F39493D199DE5E10069C867 /* InfoPlist.strings in Resources */,
357 | );
358 | runOnlyForDeploymentPostprocessing = 0;
359 | };
360 | 7F50335417FA7B0A0026FB7F /* Resources */ = {
361 | isa = PBXResourcesBuildPhase;
362 | buildActionMask = 2147483647;
363 | files = (
364 | 7F9020251809A39B00B43AD5 /* Default@2x.png in Resources */,
365 | 7FE3F0E51CB0598B00202683 /* JVFloatLabeledTextFieldXIBViewController.xib in Resources */,
366 | 7F9020231809A39B00B43AD5 /* Default-568h@2x.png in Resources */,
367 | 7F9020241809A39B00B43AD5 /* Default.png in Resources */,
368 | );
369 | runOnlyForDeploymentPostprocessing = 0;
370 | };
371 | /* End PBXResourcesBuildPhase section */
372 |
373 | /* Begin PBXSourcesBuildPhase section */
374 | 639EABD01B0B5E6F001DD7B5 /* Sources */ = {
375 | isa = PBXSourcesBuildPhase;
376 | buildActionMask = 2147483647;
377 | files = (
378 | 639EABFD1B0B5F83001DD7B5 /* JVFloatLabeledTextField.m in Sources */,
379 | 639EABFE1B0B5F83001DD7B5 /* JVFloatLabeledTextView.m in Sources */,
380 | 639EABFF1B0B5F83001DD7B5 /* NSString+TextDirectionality.m in Sources */,
381 | );
382 | runOnlyForDeploymentPostprocessing = 0;
383 | };
384 | 7F39492F199DE5E10069C867 /* Sources */ = {
385 | isa = PBXSourcesBuildPhase;
386 | buildActionMask = 2147483647;
387 | files = (
388 | 7F394949199DE8B20069C867 /* JVFloatLabeledTextViewTests.m in Sources */,
389 | 7F39493F199DE5E10069C867 /* JVFloatLabeledTextFieldTests.m in Sources */,
390 | );
391 | runOnlyForDeploymentPostprocessing = 0;
392 | };
393 | 7F50335217FA7B0A0026FB7F /* Sources */ = {
394 | isa = PBXSourcesBuildPhase;
395 | buildActionMask = 2147483647;
396 | files = (
397 | 7FF4DB94180B865F008527BD /* JVFloatLabeledTextField.m in Sources */,
398 | 7F50338E17FA7B8C0026FB7F /* JVFloatLabeledTextFieldViewController.m in Sources */,
399 | 4306C37419531E7000CC0A4C /* NSString+TextDirectionality.m in Sources */,
400 | 7F50336A17FA7B0A0026FB7F /* JVAppDelegate.m in Sources */,
401 | 7F50336617FA7B0A0026FB7F /* main.m in Sources */,
402 | 7FE3F0E41CB0598B00202683 /* JVFloatLabeledTextFieldXIBViewController.m in Sources */,
403 | 7F9AB497183B2EBF00694AB0 /* JVFloatLabeledTextView.m in Sources */,
404 | );
405 | runOnlyForDeploymentPostprocessing = 0;
406 | };
407 | /* End PBXSourcesBuildPhase section */
408 |
409 | /* Begin PBXTargetDependency section */
410 | 7F394942199DE5E10069C867 /* PBXTargetDependency */ = {
411 | isa = PBXTargetDependency;
412 | target = 7F50335517FA7B0A0026FB7F /* JVFloatLabeledTextField */;
413 | targetProxy = 7F394941199DE5E10069C867 /* PBXContainerItemProxy */;
414 | };
415 | /* End PBXTargetDependency section */
416 |
417 | /* Begin PBXVariantGroup section */
418 | 7F39493B199DE5E10069C867 /* InfoPlist.strings */ = {
419 | isa = PBXVariantGroup;
420 | children = (
421 | 7F39493C199DE5E10069C867 /* en */,
422 | );
423 | name = InfoPlist.strings;
424 | sourceTree = "";
425 | };
426 | /* End PBXVariantGroup section */
427 |
428 | /* Begin XCBuildConfiguration section */
429 | 639EABEF1B0B5E6F001DD7B5 /* Debug */ = {
430 | isa = XCBuildConfiguration;
431 | buildSettings = {
432 | APPLICATION_EXTENSION_API_ONLY = YES;
433 | CLANG_WARN_UNREACHABLE_CODE = YES;
434 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
435 | CURRENT_PROJECT_VERSION = 1;
436 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
437 | DEFINES_MODULE = YES;
438 | DYLIB_COMPATIBILITY_VERSION = 1;
439 | DYLIB_CURRENT_VERSION = 1;
440 | DYLIB_INSTALL_NAME_BASE = "@rpath";
441 | ENABLE_STRICT_OBJC_MSGSEND = YES;
442 | GCC_NO_COMMON_BLOCKS = YES;
443 | GCC_PREPROCESSOR_DEFINITIONS = (
444 | "DEBUG=1",
445 | "$(inherited)",
446 | );
447 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
448 | INFOPLIST_FILE = "JVFloatLabeledTextField/JVFloatLabeledText-Info.plist";
449 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
450 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
451 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
452 | MTL_ENABLE_DEBUG_INFO = YES;
453 | PRODUCT_BUNDLE_IDENTIFIER = "com.jaredverdi.$(PRODUCT_NAME:rfc1034identifier)";
454 | PRODUCT_NAME = JVFloatLabeledText;
455 | SKIP_INSTALL = YES;
456 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
457 | TARGETED_DEVICE_FAMILY = "1,2";
458 | VERSIONING_SYSTEM = "apple-generic";
459 | VERSION_INFO_PREFIX = "";
460 | };
461 | name = Debug;
462 | };
463 | 639EABF01B0B5E6F001DD7B5 /* Release */ = {
464 | isa = XCBuildConfiguration;
465 | buildSettings = {
466 | APPLICATION_EXTENSION_API_ONLY = YES;
467 | CLANG_WARN_UNREACHABLE_CODE = YES;
468 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
469 | COPY_PHASE_STRIP = NO;
470 | CURRENT_PROJECT_VERSION = 1;
471 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
472 | DEFINES_MODULE = YES;
473 | DYLIB_COMPATIBILITY_VERSION = 1;
474 | DYLIB_CURRENT_VERSION = 1;
475 | DYLIB_INSTALL_NAME_BASE = "@rpath";
476 | ENABLE_STRICT_OBJC_MSGSEND = YES;
477 | GCC_NO_COMMON_BLOCKS = YES;
478 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
479 | INFOPLIST_FILE = "JVFloatLabeledTextField/JVFloatLabeledText-Info.plist";
480 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
481 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
482 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
483 | MTL_ENABLE_DEBUG_INFO = NO;
484 | PRODUCT_BUNDLE_IDENTIFIER = "com.jaredverdi.$(PRODUCT_NAME:rfc1034identifier)";
485 | PRODUCT_NAME = JVFloatLabeledText;
486 | SKIP_INSTALL = YES;
487 | TARGETED_DEVICE_FAMILY = "1,2";
488 | VERSIONING_SYSTEM = "apple-generic";
489 | VERSION_INFO_PREFIX = "";
490 | };
491 | name = Release;
492 | };
493 | 7F394944199DE5E10069C867 /* Debug */ = {
494 | isa = XCBuildConfiguration;
495 | buildSettings = {
496 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/JVFloatLabeledTextField.app/JVFloatLabeledTextField";
497 | FRAMEWORK_SEARCH_PATHS = (
498 | "$(SDKROOT)/Developer/Library/Frameworks",
499 | "$(inherited)",
500 | "$(DEVELOPER_FRAMEWORKS_DIR)",
501 | );
502 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
503 | GCC_PREFIX_HEADER = "JVFloatLabeledTextFieldTests/JVFloatLabeledTextFieldTests-Prefix.pch";
504 | GCC_PREPROCESSOR_DEFINITIONS = (
505 | "DEBUG=1",
506 | "$(inherited)",
507 | );
508 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
509 | INFOPLIST_FILE = "JVFloatLabeledTextFieldTests/JVFloatLabeledTextFieldTests-Info.plist";
510 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
511 | PRODUCT_BUNDLE_IDENTIFIER = "com.jaredverdi.${PRODUCT_NAME:rfc1034identifier}";
512 | PRODUCT_NAME = "$(TARGET_NAME)";
513 | TEST_HOST = "$(BUNDLE_LOADER)";
514 | WRAPPER_EXTENSION = xctest;
515 | };
516 | name = Debug;
517 | };
518 | 7F394945199DE5E10069C867 /* Release */ = {
519 | isa = XCBuildConfiguration;
520 | buildSettings = {
521 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/JVFloatLabeledTextField.app/JVFloatLabeledTextField";
522 | FRAMEWORK_SEARCH_PATHS = (
523 | "$(SDKROOT)/Developer/Library/Frameworks",
524 | "$(inherited)",
525 | "$(DEVELOPER_FRAMEWORKS_DIR)",
526 | );
527 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
528 | GCC_PREFIX_HEADER = "JVFloatLabeledTextFieldTests/JVFloatLabeledTextFieldTests-Prefix.pch";
529 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
530 | INFOPLIST_FILE = "JVFloatLabeledTextFieldTests/JVFloatLabeledTextFieldTests-Info.plist";
531 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
532 | PRODUCT_BUNDLE_IDENTIFIER = "com.jaredverdi.${PRODUCT_NAME:rfc1034identifier}";
533 | PRODUCT_NAME = "$(TARGET_NAME)";
534 | TEST_HOST = "$(BUNDLE_LOADER)";
535 | WRAPPER_EXTENSION = xctest;
536 | };
537 | name = Release;
538 | };
539 | 7F50338017FA7B0A0026FB7F /* Debug */ = {
540 | isa = XCBuildConfiguration;
541 | buildSettings = {
542 | ALWAYS_SEARCH_USER_PATHS = NO;
543 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
544 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
545 | CLANG_CXX_LIBRARY = "libc++";
546 | CLANG_ENABLE_MODULES = YES;
547 | CLANG_ENABLE_OBJC_ARC = YES;
548 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
549 | CLANG_WARN_BOOL_CONVERSION = YES;
550 | CLANG_WARN_COMMA = YES;
551 | CLANG_WARN_CONSTANT_CONVERSION = YES;
552 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
553 | CLANG_WARN_EMPTY_BODY = YES;
554 | CLANG_WARN_ENUM_CONVERSION = YES;
555 | CLANG_WARN_INFINITE_RECURSION = YES;
556 | CLANG_WARN_INT_CONVERSION = YES;
557 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
558 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
559 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
560 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
561 | CLANG_WARN_STRICT_PROTOTYPES = YES;
562 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
563 | CLANG_WARN_UNREACHABLE_CODE = YES;
564 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
565 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
566 | COPY_PHASE_STRIP = NO;
567 | ENABLE_STRICT_OBJC_MSGSEND = YES;
568 | ENABLE_TESTABILITY = YES;
569 | GCC_C_LANGUAGE_STANDARD = gnu99;
570 | GCC_DYNAMIC_NO_PIC = NO;
571 | GCC_NO_COMMON_BLOCKS = YES;
572 | GCC_OPTIMIZATION_LEVEL = 0;
573 | GCC_PREPROCESSOR_DEFINITIONS = (
574 | "DEBUG=1",
575 | "$(inherited)",
576 | );
577 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
578 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
579 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
580 | GCC_WARN_UNDECLARED_SELECTOR = YES;
581 | GCC_WARN_UNINITIALIZED_AUTOS = YES;
582 | GCC_WARN_UNUSED_FUNCTION = YES;
583 | GCC_WARN_UNUSED_VARIABLE = YES;
584 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
585 | ONLY_ACTIVE_ARCH = YES;
586 | SDKROOT = iphoneos;
587 | };
588 | name = Debug;
589 | };
590 | 7F50338117FA7B0A0026FB7F /* Release */ = {
591 | isa = XCBuildConfiguration;
592 | buildSettings = {
593 | ALWAYS_SEARCH_USER_PATHS = NO;
594 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
595 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
596 | CLANG_CXX_LIBRARY = "libc++";
597 | CLANG_ENABLE_MODULES = YES;
598 | CLANG_ENABLE_OBJC_ARC = YES;
599 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
600 | CLANG_WARN_BOOL_CONVERSION = YES;
601 | CLANG_WARN_COMMA = YES;
602 | CLANG_WARN_CONSTANT_CONVERSION = YES;
603 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
604 | CLANG_WARN_EMPTY_BODY = YES;
605 | CLANG_WARN_ENUM_CONVERSION = YES;
606 | CLANG_WARN_INFINITE_RECURSION = YES;
607 | CLANG_WARN_INT_CONVERSION = YES;
608 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
609 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
610 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
611 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
612 | CLANG_WARN_STRICT_PROTOTYPES = YES;
613 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
614 | CLANG_WARN_UNREACHABLE_CODE = YES;
615 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
616 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
617 | COPY_PHASE_STRIP = YES;
618 | ENABLE_NS_ASSERTIONS = NO;
619 | ENABLE_STRICT_OBJC_MSGSEND = YES;
620 | GCC_C_LANGUAGE_STANDARD = gnu99;
621 | GCC_NO_COMMON_BLOCKS = YES;
622 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
623 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
624 | GCC_WARN_UNDECLARED_SELECTOR = YES;
625 | GCC_WARN_UNINITIALIZED_AUTOS = YES;
626 | GCC_WARN_UNUSED_FUNCTION = YES;
627 | GCC_WARN_UNUSED_VARIABLE = YES;
628 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
629 | SDKROOT = iphoneos;
630 | VALIDATE_PRODUCT = YES;
631 | };
632 | name = Release;
633 | };
634 | 7F50338317FA7B0A0026FB7F /* Debug */ = {
635 | isa = XCBuildConfiguration;
636 | buildSettings = {
637 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
638 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
639 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
640 | GCC_PREFIX_HEADER = "JVFloatLabeledTextField/JVFloatLabeledTextField-Prefix.pch";
641 | INFOPLIST_FILE = "JVFloatLabeledTextField/JVFloatLabeledTextField-Info.plist";
642 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
643 | PRODUCT_BUNDLE_IDENTIFIER = "com.jaredverdi.${PRODUCT_NAME:rfc1034identifier}";
644 | PRODUCT_NAME = JVFloatLabeledTextField;
645 | WRAPPER_EXTENSION = app;
646 | };
647 | name = Debug;
648 | };
649 | 7F50338417FA7B0A0026FB7F /* Release */ = {
650 | isa = XCBuildConfiguration;
651 | buildSettings = {
652 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
653 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
654 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
655 | GCC_PREFIX_HEADER = "JVFloatLabeledTextField/JVFloatLabeledTextField-Prefix.pch";
656 | INFOPLIST_FILE = "JVFloatLabeledTextField/JVFloatLabeledTextField-Info.plist";
657 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
658 | PRODUCT_BUNDLE_IDENTIFIER = "com.jaredverdi.${PRODUCT_NAME:rfc1034identifier}";
659 | PRODUCT_NAME = JVFloatLabeledTextField;
660 | WRAPPER_EXTENSION = app;
661 | };
662 | name = Release;
663 | };
664 | /* End XCBuildConfiguration section */
665 |
666 | /* Begin XCConfigurationList section */
667 | 639EABEE1B0B5E6F001DD7B5 /* Build configuration list for PBXNativeTarget "JVFloatLabeledText" */ = {
668 | isa = XCConfigurationList;
669 | buildConfigurations = (
670 | 639EABEF1B0B5E6F001DD7B5 /* Debug */,
671 | 639EABF01B0B5E6F001DD7B5 /* Release */,
672 | );
673 | defaultConfigurationIsVisible = 0;
674 | defaultConfigurationName = Release;
675 | };
676 | 7F394943199DE5E10069C867 /* Build configuration list for PBXNativeTarget "JVFloatLabeledTextFieldTests" */ = {
677 | isa = XCConfigurationList;
678 | buildConfigurations = (
679 | 7F394944199DE5E10069C867 /* Debug */,
680 | 7F394945199DE5E10069C867 /* Release */,
681 | );
682 | defaultConfigurationIsVisible = 0;
683 | defaultConfigurationName = Release;
684 | };
685 | 7F50335117FA7B0A0026FB7F /* Build configuration list for PBXProject "JVFloatLabeledTextField" */ = {
686 | isa = XCConfigurationList;
687 | buildConfigurations = (
688 | 7F50338017FA7B0A0026FB7F /* Debug */,
689 | 7F50338117FA7B0A0026FB7F /* Release */,
690 | );
691 | defaultConfigurationIsVisible = 0;
692 | defaultConfigurationName = Release;
693 | };
694 | 7F50338217FA7B0A0026FB7F /* Build configuration list for PBXNativeTarget "JVFloatLabeledTextField" */ = {
695 | isa = XCConfigurationList;
696 | buildConfigurations = (
697 | 7F50338317FA7B0A0026FB7F /* Debug */,
698 | 7F50338417FA7B0A0026FB7F /* Release */,
699 | );
700 | defaultConfigurationIsVisible = 0;
701 | defaultConfigurationName = Release;
702 | };
703 | /* End XCConfigurationList section */
704 | };
705 | rootObject = 7F50334E17FA7B0A0026FB7F /* Project object */;
706 | }
707 |
--------------------------------------------------------------------------------