├── Captures
├── Kyo.gif
├── Sae.gif
├── Akira.gif
├── Hideo.gif
├── Hoshi.gif
├── Isao.gif
├── Jiro.gif
├── Kaede.gif
├── Kuro.gif
├── Ruri.gif
├── Yoko.gif
├── Chisato.gif
├── Haruki.gif
├── Kohana.gif
├── Madoka.gif
├── Manami.gif
├── Minoru.gif
├── Nariko.gif
└── Yoshiko.gif
├── CCTextFieldEffects
├── pencil.png
├── Info.plist
├── YokoTextField.h
├── KaedeTextField.h
├── HideoTextField.h
├── KohanaTextField.h
├── KuroTextField.h
├── AkiraTextField.h
├── MadokaTextField.h
├── JiroTextField.h
├── HarukiTextField.h
├── MinoruTextField.h
├── IsaoTextField.h
├── KyoTextField.h
├── ManamiTextField.h
├── NarikoTextField.h
├── SaeTextField.h
├── HoshiTextField.h
├── ChisatoTextField.h
├── RuriTextField.h
├── CCTextField.h
├── YoshikoTextField.h
├── CCTextFieldEffects.h
├── PulsingHaloLayer.h
├── CCTextField.m
├── PulsingHaloLayer.m
├── HideoTextField.m
├── KohanaTextField.m
├── AkiraTextField.m
├── KaedeTextField.m
├── HarukiTextField.m
├── ChisatoTextField.m
├── SaeTextField.m
├── MinoruTextField.m
├── KyoTextField.m
├── JiroTextField.m
├── IsaoTextField.m
├── NarikoTextField.m
├── YoshikoTextField.m
├── MadokaTextField.m
├── RuriTextField.m
├── ManamiTextField.m
├── HoshiTextField.m
├── KuroTextField.m
└── YokoTextField.m
├── CCTextFieldEffectsDemo
├── mail.png
├── user.png
├── ViewController.h
├── AppDelegate.h
├── main.m
├── DetailViewController.h
├── Assets.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
├── Info.plist
├── effects.json
├── AppDelegate.m
├── ViewController.m
├── Base.lproj
│ └── Main.storyboard
└── DetailViewController.m
├── CCTextFieldEffects.xcodeproj
├── project.xcworkspace
│ └── contents.xcworkspacedata
└── xcshareddata
│ └── xcschemes
│ └── CCTextFieldEffects.xcscheme
├── CCTextFieldEffects.podspec
├── .gitignore
└── Licence
/Captures/Kyo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cokile/CCTextFieldEffects/HEAD/Captures/Kyo.gif
--------------------------------------------------------------------------------
/Captures/Sae.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cokile/CCTextFieldEffects/HEAD/Captures/Sae.gif
--------------------------------------------------------------------------------
/Captures/Akira.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cokile/CCTextFieldEffects/HEAD/Captures/Akira.gif
--------------------------------------------------------------------------------
/Captures/Hideo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cokile/CCTextFieldEffects/HEAD/Captures/Hideo.gif
--------------------------------------------------------------------------------
/Captures/Hoshi.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cokile/CCTextFieldEffects/HEAD/Captures/Hoshi.gif
--------------------------------------------------------------------------------
/Captures/Isao.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cokile/CCTextFieldEffects/HEAD/Captures/Isao.gif
--------------------------------------------------------------------------------
/Captures/Jiro.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cokile/CCTextFieldEffects/HEAD/Captures/Jiro.gif
--------------------------------------------------------------------------------
/Captures/Kaede.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cokile/CCTextFieldEffects/HEAD/Captures/Kaede.gif
--------------------------------------------------------------------------------
/Captures/Kuro.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cokile/CCTextFieldEffects/HEAD/Captures/Kuro.gif
--------------------------------------------------------------------------------
/Captures/Ruri.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cokile/CCTextFieldEffects/HEAD/Captures/Ruri.gif
--------------------------------------------------------------------------------
/Captures/Yoko.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cokile/CCTextFieldEffects/HEAD/Captures/Yoko.gif
--------------------------------------------------------------------------------
/Captures/Chisato.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cokile/CCTextFieldEffects/HEAD/Captures/Chisato.gif
--------------------------------------------------------------------------------
/Captures/Haruki.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cokile/CCTextFieldEffects/HEAD/Captures/Haruki.gif
--------------------------------------------------------------------------------
/Captures/Kohana.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cokile/CCTextFieldEffects/HEAD/Captures/Kohana.gif
--------------------------------------------------------------------------------
/Captures/Madoka.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cokile/CCTextFieldEffects/HEAD/Captures/Madoka.gif
--------------------------------------------------------------------------------
/Captures/Manami.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cokile/CCTextFieldEffects/HEAD/Captures/Manami.gif
--------------------------------------------------------------------------------
/Captures/Minoru.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cokile/CCTextFieldEffects/HEAD/Captures/Minoru.gif
--------------------------------------------------------------------------------
/Captures/Nariko.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cokile/CCTextFieldEffects/HEAD/Captures/Nariko.gif
--------------------------------------------------------------------------------
/Captures/Yoshiko.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cokile/CCTextFieldEffects/HEAD/Captures/Yoshiko.gif
--------------------------------------------------------------------------------
/CCTextFieldEffects/pencil.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cokile/CCTextFieldEffects/HEAD/CCTextFieldEffects/pencil.png
--------------------------------------------------------------------------------
/CCTextFieldEffectsDemo/mail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cokile/CCTextFieldEffects/HEAD/CCTextFieldEffectsDemo/mail.png
--------------------------------------------------------------------------------
/CCTextFieldEffectsDemo/user.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Cokile/CCTextFieldEffects/HEAD/CCTextFieldEffectsDemo/user.png
--------------------------------------------------------------------------------
/CCTextFieldEffects.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/CCTextFieldEffectsDemo/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/25/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : UITableViewController
12 |
13 | @end
14 |
15 |
--------------------------------------------------------------------------------
/CCTextFieldEffectsDemo/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/25/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 |
16 | @end
17 |
18 |
--------------------------------------------------------------------------------
/CCTextFieldEffectsDemo/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/25/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | @autoreleasepool {
14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/CCTextFieldEffectsDemo/DetailViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // DetailViewController.h
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/25/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface DetailViewController : UIViewController
12 |
13 | @property (nonatomic) CGFloat red;
14 | @property (nonatomic) CGFloat green;
15 | @property (nonatomic) CGFloat blue;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/CCTextFieldEffects.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |spec|
2 | spec.name = 'CCTextFieldEffects'
3 | spec.platform = :ios
4 | spec.version = '0.1.3'
5 | spec.license = { :type => 'MIT' }
6 | spec.homepage = 'https://github.com/Cokile/CCTextFieldEffects'
7 | spec.authors = { 'Cokile' => 'kelvintgx@gmail.com' }
8 | spec.summary = 'A simple replacement for UITextField.'
9 | spec.source = { :git => 'https://github.com/Cokile/CCTextFieldEffects.git', :tag => 'v0.1.3'}
10 | spec.source_files = 'CCTextFieldEffects/*.{h,m}'
11 | spec.resources = 'CCTextFieldEffects/*.png'
12 | spec.requires_arc = true
13 | end
14 |
--------------------------------------------------------------------------------
/CCTextFieldEffectsDemo/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | }
33 | ],
34 | "info" : {
35 | "version" : 1,
36 | "author" : "xcode"
37 | }
38 | }
--------------------------------------------------------------------------------
/CCTextFieldEffects/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 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## Build generated
6 | build/
7 | DerivedData
8 |
9 | ## Various settings
10 | *.pbxuser
11 | !default.pbxuser
12 | *.mode1v3
13 | !default.mode1v3
14 | *.mode2v3
15 | !default.mode2v3
16 | *.perspectivev3
17 | !default.perspectivev3
18 | xcuserdata
19 |
20 | ## Other
21 | *.xccheckout
22 | *.moved-aside
23 | *.xcuserstate
24 | *.xcscmblueprint
25 |
26 | ## Obj-C/Swift specific
27 | *.hmap
28 | *.ipa
29 |
30 | # CocoaPods
31 | #
32 | # We recommend against adding the Pods directory to your .gitignore. However
33 | # you should judge for yourself, the pros and cons are mentioned at:
34 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
35 | #
36 | Pods/
37 | # Carthage
38 | #
39 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
40 | # Carthage/Checkouts
41 |
42 | Carthage/Build
43 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/YokoTextField.h:
--------------------------------------------------------------------------------
1 | //
2 | // YokoTextField.h
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/26/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import "CCTextField.h"
10 |
11 | @interface YokoTextField : CCTextField
12 |
13 | #pragma mark - Public properties
14 | /**
15 | * The color of the placeholder text.
16 | *
17 | * This property applies a color to the complete placeholder string. The default value for this property is a shallow gray color.
18 | */
19 | @property (strong, nonatomic) UIColor *placeholderColor;
20 |
21 | /**
22 | * The view’s foreground color.
23 | *
24 | * The default value for this property is a black color.
25 | */
26 | @property (strong, nonatomic) UIColor *foregroundColor;
27 |
28 | /**
29 | * The scale of the placeholder font.
30 | *
31 | * This property determines the size of the placeholder label relative to the font size of the text field.
32 | */
33 | @property (nonatomic) CGFloat placeholderFontScale;
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/KaedeTextField.h:
--------------------------------------------------------------------------------
1 | //
2 | // KaedeTextField.h
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/26/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import "CCTextField.h"
10 |
11 | @interface KaedeTextField : CCTextField
12 |
13 | #pragma mark - Public properties
14 |
15 | /**
16 | * The color of the placeholder text.
17 | *
18 | * This property applies a color to the complete placeholder string. The default value for this property is a dark gray color.
19 | */
20 | @property (strong, nonatomic) UIColor *placeholderColor;
21 |
22 | /**
23 | * The view’s foreground color.
24 | *
25 | * The default value for this property is a shallow gray color.
26 | */
27 | @property (strong, nonatomic) UIColor *foregroundColor;
28 |
29 | /**
30 | * The scale of the placeholder font.
31 | *
32 | * This property determines the size of the placeholder label relative to the font size of the text field.
33 | */
34 | @property (nonatomic) CGFloat placeholderFontScale;
35 |
36 | @end
37 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/HideoTextField.h:
--------------------------------------------------------------------------------
1 | //
2 | // HideoTextField.h
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/27/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import "CCTextField.h"
10 |
11 | @interface HideoTextField : CCTextField
12 |
13 | #pragma mark - Public properties
14 |
15 | /**
16 | * The color of the image container color.
17 | *
18 | * This property applies a color to the background of the image container. The default value for this property is a purple color.
19 | */
20 | @property (strong, nonatomic) UIColor *imageContainerColor;
21 |
22 | /**
23 | * The image of the image container view.
24 | *
25 | * This property applies a image to the image container.
26 | */
27 | @property (strong, nonatomic) UIImage *image;
28 |
29 | /**
30 | * The scale of the image.
31 | *
32 | * This property determines the size of the image relative to the original size when animated. The default value for this properties is 0.7
33 | */
34 | @property (nonatomic) CGFloat imageScale;
35 |
36 | @end
37 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/KohanaTextField.h:
--------------------------------------------------------------------------------
1 | //
2 | // KohanaTextField.h
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 7/1/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import "CCTextField.h"
10 |
11 | @interface KohanaTextField : CCTextField
12 |
13 | #pragma mark - Public properties
14 | /**
15 | * The color of the placeholder text.
16 | *
17 | * This property applies a color to the complete placeholder string. The default value for this property is a gray color.
18 | */
19 | @property (strong, nonatomic) UIColor *placeholderColor;
20 |
21 | /**
22 | * The image of the comtrol.
23 | *
24 | * This property applies a image to the control. The color of the image is determined by placeholderColor.
25 | */
26 | @property (strong, nonatomic) UIImage *image;
27 |
28 | /**
29 | * The scale of the placeholder font.
30 | *
31 | * This property determines the size of the placeholder label relative to the font size of the text field.
32 | */
33 | @property (nonatomic) CGFloat placeholderFontScale;
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/KuroTextField.h:
--------------------------------------------------------------------------------
1 | //
2 | // KuroTextField.h
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/29/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import "CCTextField.h"
10 |
11 | @interface KuroTextField : CCTextField
12 |
13 | #pragma mark - Public properties
14 | /**
15 | * The color of the border.
16 | *
17 | * This property applies a color to the bonuds of the border. The default value for this property is a gray color.
18 | */
19 | @property (strong, nonatomic) UIColor *borderColor;
20 |
21 | /**
22 | * The color of the placeholder text.
23 | *
24 | * This property applies a color to the complete placeholder string. The default value for this property is a pink color.
25 | */
26 | @property (strong, nonatomic) UIColor *placeholderColor;
27 |
28 | /**
29 | * The scale of the placeholder font.
30 | *
31 | * This property determines the size of the placeholder label relative to the font size of the text field.
32 | */
33 | @property (nonatomic) CGFloat placeholderFontScale;
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/AkiraTextField.h:
--------------------------------------------------------------------------------
1 | //
2 | // AkiraTextField.h
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/25/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import "CCTextField.h"
10 |
11 | @interface AkiraTextField : CCTextField
12 |
13 | #pragma mark - Public properties
14 | /**
15 | * The color of the border.
16 | *
17 | * This property applies a color to the bounds of the control. The default value for this property is a grey color.
18 | */
19 | @property (strong, nonatomic) UIColor *borderColor;
20 |
21 | /**
22 | * The color of the placeholder text.
23 | *
24 | * This property applies a color to the complete placeholder string. The default value for this property is a orange color.
25 | */
26 | @property (strong, nonatomic) UIColor *placeholderColor;
27 |
28 | /**
29 | * The scale of the placeholder font.
30 | *
31 | * This property determines the size of the placeholder label relative to the font size of the text field.
32 | */
33 | @property (nonatomic) CGFloat placeholderFontScale;
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/MadokaTextField.h:
--------------------------------------------------------------------------------
1 | //
2 | // MadokaTextField.h
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/26/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import "CCTextField.h"
10 |
11 | @interface MadokaTextField : CCTextField
12 |
13 | #pragma mark - Public properties
14 | /**
15 | * The color of the placeholder text.
16 | *
17 | * This property applies a color to the complete placeholder string. The default value for this property is a purple color.
18 | */
19 | @property (strong, nonatomic) UIColor *placeholderColor;
20 |
21 | /**
22 | * The color of the border.
23 | *
24 | * This property applies a color to the lower edge of the control. The default value for this property is a purple color.
25 | */
26 | @property (strong, nonatomic) UIColor *borderColor;
27 |
28 | /**
29 | * The scale of the placeholder font.
30 | *
31 | * This property determines the size of the placeholder label relative to the font size of the text field.
32 | */
33 | @property (nonatomic) CGFloat placeholderFontScale;
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/JiroTextField.h:
--------------------------------------------------------------------------------
1 | //
2 | // JiroTextField.h
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/26/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import "CCTextField.h"
10 |
11 | @interface JiroTextField : CCTextField
12 |
13 | #pragma mark - Public properties
14 | /**
15 | * The color of the border.
16 | *
17 | * This property applies a color to the lower edge of the control. The default value for this property is a shadow blue color.
18 | */
19 | @property (strong, nonatomic) UIColor *borderColor;
20 |
21 | /**
22 | * The color of the placeholder text.
23 | *
24 | * This property applies a color to the complete placeholder string. The default value for this property is a shadow blue color.
25 | */
26 | @property (strong, nonatomic) UIColor *placeholderColor;
27 |
28 | /**
29 | * The scale of the placeholder font.
30 | *
31 | * This property determines the size of the placeholder label relative to the font size of the text field.
32 | */
33 | @property (nonatomic) CGFloat placeholderFontScale;
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/HarukiTextField.h:
--------------------------------------------------------------------------------
1 | //
2 | // HarukiTextField.h
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/28/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import "CCTextField.h"
10 |
11 | @interface HarukiTextField : CCTextField
12 |
13 | #pragma mark - Public properties
14 |
15 | /**
16 | * The color of the border.
17 | *
18 | * This property applies a color to the upper and lower borders of the control. The default value for this property is a dark gray color.
19 | */
20 | @property (strong, nonatomic) UIColor *borderColor;
21 |
22 | /**
23 | * The color of the placeholder text.
24 | *
25 | * This property applies a color to the complete placeholder string. The default value for this property is a dark gray color.
26 | */
27 | @property (strong, nonatomic) UIColor *placeholderColor;
28 |
29 | /**
30 | * The scale of the placeholder font.
31 | *
32 | * This property determines the size of the placeholder label relative to the font size of the text field.
33 | */
34 | @property (nonatomic) CGFloat placeholderFontScale;
35 |
36 | @end
37 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/MinoruTextField.h:
--------------------------------------------------------------------------------
1 | //
2 | // MinoruTextField.h
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/28/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import "CCTextField.h"
10 |
11 | @interface MinoruTextField : CCTextField
12 |
13 | #pragma mark - Public properties
14 | /**
15 | * The color of the placeholder text.
16 | *
17 | * This property applies a color to the complete placeholder string. The default value for this property is a dark gray color.
18 | */
19 | @property (strong, nonatomic) UIColor *placeholderColor;
20 |
21 | /**
22 | * The color of the border color when active.
23 | *
24 | * This property applies a color to the border. The default value for this property is a shallow red color.
25 | */
26 | @property (strong, nonatomic) UIColor *borderColor;
27 |
28 | @property (strong, nonatomic) UIColor *backgroundColor;
29 |
30 | /**
31 | * The scale of the placeholder font.
32 | *
33 | * This property determines the size of the placeholder label relative to the font size of the text field.
34 | */
35 | @property (nonatomic) CGFloat placeholderFontScale;
36 |
37 | @end
38 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/IsaoTextField.h:
--------------------------------------------------------------------------------
1 | //
2 | // IsaoTextField.h
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/25/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import "CCTextField.h"
10 |
11 | @interface IsaoTextField : CCTextField
12 |
13 | #pragma mark - Public properties
14 | /**
15 | * The color of the border when it has no content.
16 | *
17 | * This property applies a color to the lower edge of the control. The default value for this property is a white color. This value is also applied to the placeholder color.
18 | */
19 | @property (strong, nonatomic) UIColor *inactiveColor;
20 |
21 | /**
22 | * The color of the border when it has content.
23 | *
24 | * This property applies a color to the lower edge of the control. The default value for this property is a shallow red color.
25 | */
26 | @property (strong, nonatomic) UIColor *activeColor;
27 |
28 | /**
29 | * The scale of the placeholder font.
30 | *
31 | * This property determines the size of the placeholder label relative to the font size of the text field.
32 | */
33 | @property (nonatomic) CGFloat placeholderFontScale;
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/KyoTextField.h:
--------------------------------------------------------------------------------
1 | //
2 | // KyoTextField.h
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/28/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import "CCTextField.h"
10 |
11 | @interface KyoTextField : CCTextField
12 |
13 | #pragma mark - Public properties
14 | /**
15 | * The color of the placeholder text.
16 | *
17 | * This property applies a color to the complete placeholder string. The default value for this property is a dark gray color.
18 | */
19 | @property (strong, nonatomic) UIColor *placeholderColor;
20 |
21 | /**
22 | * The color of the overlay.
23 | *
24 | * This property applies a color to the complete placeholder string. The default value for this property is a transparent transparent purple color.
25 | */
26 | @property (strong, nonatomic) UIColor *overlayColor;
27 |
28 | @property (strong, nonatomic) UIColor *backgroundColor;
29 |
30 | /**
31 | * The scale of the placeholder font.
32 | *
33 | * This property determines the size of the placeholder label relative to the font size of the text field.
34 | */
35 | @property (nonatomic) CGFloat placeholderFontScale;
36 |
37 | @end
38 |
--------------------------------------------------------------------------------
/Licence:
--------------------------------------------------------------------------------
1 |
2 | Copyright (c) 2016 Runqiu Xu.
3 | This code is distributed under the terms and conditions of the MIT license.
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 the
7 | Software without restriction, including without limitation the rights to use, copy,
8 | modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
9 | and to permit persons to whom the Software is furnished to do so, subject to the
10 | 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 IMPLIED,
16 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
17 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
18 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
19 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
20 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/CCTextFieldEffectsDemo/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 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/ManamiTextField.h:
--------------------------------------------------------------------------------
1 | //
2 | // ManamiTextField.h
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/30/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import "CCTextField.h"
10 |
11 | @interface ManamiTextField : CCTextField
12 |
13 | #pragma mark - Public properties
14 | /**
15 | * The color of the placeholder text.
16 | *
17 | * This property applies a color to the complete placeholder string. The default value for this property is a gray color.
18 | */
19 | @property (strong, nonatomic) UIColor *placeholderColor;
20 |
21 | /**
22 | * The color of the border.
23 | *
24 | * This property applies a color to the lower edge of the control. The default value for this property is a gray color.
25 | */
26 | @property (strong, nonatomic) UIColor *borderColor;
27 |
28 | /**
29 | * The color of the background.
30 | *
31 | * This property applies a color to the background of the text area. The default value for this property is a gray color.
32 | */
33 | @property (strong, nonatomic) UIColor *backgroundColor;
34 |
35 | /**
36 | * The scale of the placeholder font.
37 | *
38 | * This property determines the size of the placeholder label relative to the font size of the text field.
39 | */
40 | @property (nonatomic) CGFloat placeholderFontScale;
41 |
42 | @end
43 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/NarikoTextField.h:
--------------------------------------------------------------------------------
1 | //
2 | // NarikoTextField.h
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/30/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import "CCTextField.h"
10 |
11 | @interface NarikoTextField : CCTextField
12 |
13 | #pragma mark - Public properties
14 | /**
15 | * The color of the placeholder text.
16 | *
17 | * This property applies a color to the complete placeholder string. The default value for this property is a gray color.
18 | */
19 | @property (strong, nonatomic) UIColor *placeholderColor;
20 |
21 | /**
22 | * The color of the border.
23 | *
24 | * This property applies a color to the lower edge of the control. The default value for this property is a gray color.
25 | */
26 | @property (strong, nonatomic) UIColor *borderColor;
27 |
28 | /**
29 | * The color of the background.
30 | *
31 | * This property applies a color to the background of the text area. The default value for this property is a white color.
32 | */
33 | @property (strong, nonatomic) UIColor *backgroundColor;
34 |
35 | /**
36 | * The scale of the placeholder font.
37 | *
38 | * This property determines the size of the placeholder label relative to the font size of the text field.
39 | */
40 | @property (nonatomic) CGFloat placeholderFontScale;
41 |
42 | @end
43 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/SaeTextField.h:
--------------------------------------------------------------------------------
1 | //
2 | // SaeTextField.h
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 7/1/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import "CCTextField.h"
10 |
11 | @interface SaeTextField : CCTextField
12 |
13 | #pragma mark - Public properties
14 | /**
15 | * The color of the border.
16 | *
17 | * This property applies a color to the lower border of the control. The default value for this property is a white color.
18 | */
19 | @property (strong, nonatomic) UIColor *borderColor;
20 |
21 | /**
22 | * The image of the control.
23 | *
24 | * This property applies a image to the right-down of the control, the color of the image is determined by borderColor. The default value for this property is a pencil.
25 | */
26 | @property (strong, nonatomic) UIImage *image;
27 |
28 | /**
29 | * The color of the placeholder text.
30 | *
31 | * This property applies a color to the complete placeholder string. The default value for this property is a transparent black color.
32 | */
33 | @property (strong, nonatomic) UIColor *placeholderColor;
34 |
35 | /**
36 | * The scale of the placeholder font.
37 | *
38 | * This property determines the size of the placeholder label relative to the font size of the text field.
39 | */
40 | @property (nonatomic) CGFloat placeholderFontScale;
41 |
42 | @end
43 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/HoshiTextField.h:
--------------------------------------------------------------------------------
1 | //
2 | // HoshiTextField.h
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/25/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import "CCTextField.h"
10 |
11 | @interface HoshiTextField : CCTextField
12 |
13 | #pragma mark - Public methods
14 | /**
15 | * The color of the border when it has no content.
16 | *
17 | * his property applies a color to the lower edge of the control. The default value for this property is a gray color.
18 | */
19 | @property (strong, nonatomic) UIColor *borderInactiveColor;
20 |
21 | /**
22 | * The color of the border when it has content.
23 | *
24 | * This property applies a color to the lower edge of the control. The default value for this property is a dark gray color.
25 | */
26 | @property (strong, nonatomic) UIColor *borderActiveColor;
27 |
28 | /**
29 | * The color of the placeholder text.
30 | *
31 | * This property applies a color to the complete placeholder string. The default value for this property is a gray color.
32 | */
33 | @property (strong, nonatomic) UIColor *placeholderColor;
34 |
35 | /**
36 | * The scale of the placeholder font.
37 | *
38 | * This property determines the size of the placeholder label relative to the font size of the text field.
39 | */
40 | @property(nonatomic) CGFloat placeholderFontScale;
41 |
42 | @end
43 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/ChisatoTextField.h:
--------------------------------------------------------------------------------
1 | //
2 | // ChisatoTextField.h
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/29/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import "CCTextField.h"
10 |
11 | @interface ChisatoTextField : CCTextField
12 |
13 | #pragma mark - Public properties
14 | /**
15 | * The color of the border.
16 | *
17 | * This property applies a color to the bounds of the control. The default value for this property is a grey color.
18 | */
19 | @property (strong, nonatomic) UIColor *borderColor;
20 |
21 | /**
22 | * The color of the placeholder text.
23 | *
24 | * This property applies a color to the complete placeholder string. The default value for this property is a gray color.
25 | */
26 | @property (strong, nonatomic) UIColor *placeholderColor;
27 |
28 | /**
29 | * The color of the active border and placeholder.
30 | *
31 | * This property applies a color to the bounds of the control and placeholder when the text is not empty or focused. The default value for this property is a pink color.
32 | */
33 | @property (strong, nonatomic) UIColor *activeColor;
34 |
35 | /**
36 | * The scale of the placeholder font.
37 | *
38 | * This property determines the size of the placeholder label relative to the font size of the text field.
39 | */
40 | @property (nonatomic) CGFloat placeholderFontScale;
41 |
42 | @end
43 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/RuriTextField.h:
--------------------------------------------------------------------------------
1 | //
2 | // RuriTextField.h
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/29/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import "CCTextField.h"
10 |
11 | @interface RuriTextField : CCTextField
12 |
13 | #pragma mark - Public properties
14 | /**
15 | * The color of the placeholder text.
16 | *
17 | * This property applies a color to the complete placeholder string. The default value for this property is a purple color.
18 | */
19 | @property (strong, nonatomic) UIColor *placeholderColor;
20 |
21 | /**
22 | * The color of the border.
23 | *
24 | * This property applies a color to the lower edge of the control. The default value for this property is a shallow green color.
25 | */
26 | @property (strong, nonatomic) UIColor *borderColor;
27 |
28 | /**
29 | * The color of the active border and placeholder.
30 | *
31 | * This property applies a color to the lower edge of the control and placeholder when the text is not empty or focused. The default value for this property is a shallow green color.
32 | */
33 | @property (strong, nonatomic) UIColor *activeColor;
34 |
35 | /**
36 | * The scale of the placeholder font.
37 | *
38 | * This property determines the size of the placeholder label relative to the font size of the text field.
39 | */
40 | @property (nonatomic) CGFloat placeholderFontScale;
41 |
42 |
43 | @end
44 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/CCTextField.h:
--------------------------------------------------------------------------------
1 | //
2 | // CCTextField.h
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/25/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | /**
12 | * Closure executed when an animation has been completed
13 | *
14 | * @param type The type of animatino a TextFieldEffect can perform.
15 | */
16 | typedef void(^AnimationCompletionHandler)(void);
17 |
18 | @interface CCTextField : UITextField
19 |
20 | #pragma mark - Public properties
21 | /**
22 | * UIColor that indicates the cursorColor.
23 | */
24 | @property (strong, nonatomic) UIColor *cursorColor;
25 |
26 | /**
27 | * UILabel that holds all the placeholder information.
28 | */
29 | @property (strong, nonatomic) UILabel *placeholderLabel;
30 |
31 | /**
32 | * Block executed when the animation for obtaining focus has been completed.
33 | */
34 | @property (copy, nonatomic) AnimationCompletionHandler didBeginEditingHandler;
35 |
36 | /**
37 | * Block executed when the animation for losing focus has been completed.
38 | */
39 | @property (copy, nonatomic) AnimationCompletionHandler didEndEditingHandler;
40 |
41 | #pragma mark - Public methods
42 | /**
43 | * Creates all the animations that are used to leave the textfield in the "entering text" state.
44 | */
45 | - (void)animateViewsForTextEntry;
46 |
47 | /**
48 | * Creates all the animations that are used to leave the textfield in the "display input text" state.
49 | */
50 | - (void)animateViewsForTextDisplay;
51 |
52 | - (void)updateViewsForBoundsChange:(CGRect)bounds;
53 |
54 | @end
55 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/YoshikoTextField.h:
--------------------------------------------------------------------------------
1 | //
2 | // YoshikoTextField.h
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/26/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import "CCTextField.h"
10 |
11 | @interface YoshikoTextField : CCTextField
12 |
13 | #pragma mark - Public properties
14 | /**
15 | * The color of the border when it has content.
16 | *
17 | * This property applies a color to the edges of the control. The default value for this property is a green color.
18 | */
19 | @property (strong, nonatomic) UIColor *activeBorderColor;
20 |
21 | /**
22 | * The color of the border when it has no content.
23 | *
24 | * This property applies a color to the edges of the control. The default value for this property is a clear color.
25 | */
26 | @property (strong, nonatomic) UIColor *inactiveBorderColor;
27 |
28 | /**
29 | * The color of the input's background when it has content. When it's not focused it reverts to the color of the `inactiveBorderColor` The default value for this property is a white color.
30 | */
31 | @property (strong, nonatomic) UIColor *activeBackgroundColor;
32 |
33 | /**
34 | * The color of the placeholder text.
35 | *
36 | * This property applies a color to the complete placeholder string. The default value for this property is a dark gray color.
37 | */
38 | @property (strong, nonatomic) UIColor *placeholderColor;
39 |
40 | /**
41 | * The scale of the placeholder font.
42 | *
43 | * This property determines the size of the placeholder label relative to the font size of the text field.
44 | */
45 | @property (nonatomic) CGFloat placeholderFontScale;
46 |
47 | @end
48 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/CCTextFieldEffects.h:
--------------------------------------------------------------------------------
1 | //
2 | // CCTextFieldEffects.h
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 7/2/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for CCTextFieldEffects.
12 | FOUNDATION_EXPORT double CCTextFieldEffectsVersionNumber;
13 |
14 | //! Project version string for CCTextFieldEffects.
15 | FOUNDATION_EXPORT const unsigned char CCTextFieldEffectsVersionString[];
16 |
17 | // In this header, you should import all the public headers of your framework using statements like #import
18 |
19 | #import
20 | #import
21 | #import
22 | #import
23 | #import
24 | #import
25 | #import
26 | #import
27 | #import
28 | #import
29 | #import
30 | #import
31 | #import
32 | #import
33 | #import
34 | #import
35 | #import
36 | #import
37 | #import
38 | #import
39 |
40 | #import
41 |
--------------------------------------------------------------------------------
/CCTextFieldEffectsDemo/effects.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "backgroundColor": [47, 50, 56],
4 | "title":"Akira",
5 | },
6 |
7 | {
8 | "backgroundColor": [249, 247, 246],
9 | "title":"Hoshi",
10 | },
11 |
12 | {
13 | "backgroundColor": [61, 68, 68],
14 | "title":"Isao",
15 | },
16 |
17 | {
18 | "backgroundColor": [208, 214, 214],
19 | "title":"Jiro",
20 | },
21 |
22 | {
23 | "backgroundColor": [249, 247, 246],
24 | "title":"Kaede",
25 | },
26 |
27 | {
28 | "backgroundColor": [47, 50, 56],
29 | "title":"Madoka",
30 | },
31 |
32 | {
33 | "backgroundColor": [223, 102, 89],
34 | "title":"Yoko",
35 | },
36 |
37 | {
38 | "backgroundColor": [249, 247, 246],
39 | "title":"Yoshiko",
40 | },
41 |
42 | {
43 | "backgroundColor": [249, 247, 246],
44 | "title":"Hideo",
45 | },
46 |
47 | {
48 | "backgroundColor": [240, 239, 238],
49 | "title":"Haruki",
50 | },
51 |
52 | {
53 | "backgroundColor": [249, 247, 246],
54 | "title":"Minoru",
55 | },
56 |
57 | {
58 | "backgroundColor": [232, 232, 232],
59 | "title":"Kyo",
60 | },
61 |
62 | {
63 | "backgroundColor": [47, 50, 56],
64 | "title":"Kuro",
65 | },
66 |
67 | {
68 | "backgroundColor": [47, 50, 56],
69 | "title":"Ruri",
70 | },
71 |
72 | {
73 | "backgroundColor": [47, 50, 56],
74 | "title":"Chisato",
75 | },
76 |
77 | {
78 | "backgroundColor": [232, 232, 232],
79 | "title":"Manami",
80 | },
81 |
82 | {
83 | "backgroundColor": [208, 214, 214],
84 | "title":"Nariko",
85 | },
86 |
87 | {
88 | "backgroundColor": [135, 129, 189],
89 | "title":"Sae",
90 | },
91 |
92 | {
93 | "backgroundColor": [232, 232, 232],
94 | "title":"Kohana",
95 | },
96 | ]
97 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/PulsingHaloLayer.h:
--------------------------------------------------------------------------------
1 | //
2 | // PulsingHaloLayer.h
3 | // https://github.com/shu223/PulsingHalo
4 | //
5 | // Created by shuichi on 12/5/13.
6 | // Copyright (c) 2013 Shuichi Tsutsumi. All rights reserved.
7 | //
8 | // Inspired by https://github.com/samvermette/SVPulsingAnnotationView
9 |
10 |
11 | #import
12 | #import
13 |
14 |
15 | @interface PulsingHaloLayer : CALayer
16 |
17 | /**
18 | * The default value of this property is @c 60pt.
19 | */
20 | @property (nonatomic, assign) CGFloat radius;
21 |
22 | /**
23 | * The default value of this property is @c 0.0.
24 | */
25 | @property (nonatomic, assign) CGFloat fromValueForRadius;
26 |
27 | /**
28 | * The default value of this property is @c 0.45.
29 | */
30 | @property (nonatomic, assign) CGFloat fromValueForAlpha;
31 |
32 | /**
33 | * The value of this property should be ranging from @c 0 to @c 1 (exclusive).
34 | *
35 | * The default value of this property is @c 0.2.
36 | */
37 | @property (nonatomic, assign) CGFloat keyTimeForHalfOpacity;
38 |
39 | /**
40 | * The animation duration in seconds.
41 | *
42 | * The default value of this property is @c 3.
43 | */
44 | @property (nonatomic, assign) NSTimeInterval animationDuration;
45 |
46 | /**
47 | * The animation interval in seconds.
48 | *
49 | * The default value of this property is @c 0.
50 | */
51 | @property (nonatomic, assign) NSTimeInterval pulseInterval;
52 |
53 | /**
54 | * The default value of this property is @c INFINITY.
55 | */
56 | @property (nonatomic, assign) float repeatCount;
57 |
58 | /**
59 | * The default value of this property is @c YES.
60 | */
61 | @property (nonatomic, assign) BOOL useTimingFunction;
62 |
63 | - (id)initWithRepeatCount:(float)repeatCount;
64 | -(void)startAnimation;
65 | -(void)stopAnimation;
66 | @end
67 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/CCTextField.m:
--------------------------------------------------------------------------------
1 | //
2 | // CCTextField.m
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/25/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import "CCTextField.h"
10 |
11 | @implementation CCTextField
12 |
13 | #pragma mark - Custom accessorys
14 | - (void)setCursorColor:(UIColor *)cursorColor {
15 | _cursorColor = cursorColor;
16 |
17 | self.tintColor = cursorColor;
18 | }
19 |
20 | #pragma mark - Lifecycle
21 | - (instancetype)initWithFrame:(CGRect)frame {
22 | self = [super initWithFrame:frame];
23 |
24 | if (self) {
25 | self.font = [UIFont boldSystemFontOfSize:self.font.pointSize];
26 | }
27 |
28 | return self;
29 | }
30 |
31 | - (instancetype) initWithCoder:(NSCoder *)aDecoder {
32 | if ((self = [super initWithCoder:aDecoder])) {
33 | self.font = [UIFont boldSystemFontOfSize:self.font.pointSize];
34 | }
35 | return self;
36 | }
37 |
38 | - (void)dealloc {
39 | [[NSNotificationCenter defaultCenter] removeObserver:self];
40 | }
41 |
42 | #pragma mark - Public methods
43 | - (void)animateViewsForTextEntry {
44 | NSAssert(NO, @"%@ must be overridden", NSStringFromSelector(_cmd));
45 | }
46 |
47 | - (void)animateViewsForTextDisplay {
48 | NSAssert(NO, @"%@ must be overridden", NSStringFromSelector(_cmd));
49 | }
50 |
51 | - (void)updateViewsForBoundsChange:(CGRect)bounds {
52 | NSAssert(NO, @"%@ must be overridden", NSStringFromSelector(_cmd));
53 | }
54 |
55 | #pragma mark - Overridden methods
56 | - (void)drawPlaceholderInRect:(CGRect)rect {
57 | // Don't draw any placeholders.
58 | }
59 |
60 | - (void)willMoveToSuperview:(UIView *)newSuperview {
61 | if (newSuperview != nil) {
62 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(animateViewsForTextEntry) name:UITextFieldTextDidBeginEditingNotification object:self];
63 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(animateViewsForTextDisplay) name:UITextFieldTextDidEndEditingNotification object:self];
64 | }
65 | }
66 |
67 | @end
68 |
--------------------------------------------------------------------------------
/CCTextFieldEffectsDemo/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/25/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | @interface AppDelegate ()
12 |
13 | @end
14 |
15 | @implementation AppDelegate
16 |
17 |
18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
19 | // Override point for customization after application launch.
20 | return YES;
21 | }
22 |
23 | - (void)applicationWillResignActive:(UIApplication *)application {
24 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
25 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
26 | }
27 |
28 | - (void)applicationDidEnterBackground:(UIApplication *)application {
29 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
31 | }
32 |
33 | - (void)applicationWillEnterForeground:(UIApplication *)application {
34 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
35 | }
36 |
37 | - (void)applicationDidBecomeActive:(UIApplication *)application {
38 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
39 | }
40 |
41 | - (void)applicationWillTerminate:(UIApplication *)application {
42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
43 | }
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/CCTextFieldEffectsDemo/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/25/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 | #import "DetailViewController.h"
11 |
12 | @interface ViewController ()
13 |
14 | @property (copy, nonatomic) NSMutableArray *effects;
15 |
16 | @end
17 |
18 | @implementation ViewController
19 |
20 | - (void)viewDidLoad {
21 | [super viewDidLoad];
22 | // Do any additional setup after loading the view, typically from a nib.
23 |
24 | NSString *jsonPath = [[NSBundle mainBundle] pathForResource:@"effects" ofType:@"json"];
25 | NSData *jsonData = [NSData dataWithContentsOfFile:jsonPath];
26 | NSError *error;
27 | self.effects = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&error];
28 | self.tableView.backgroundColor = [UIColor colorWithRed:0.9765 green:0.9686 blue:0.9647 alpha:1.0];
29 | }
30 |
31 | #pragma mark - UITableViewDataSource
32 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
33 | return 1;
34 | }
35 |
36 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
37 | return [self.effects count];
38 | }
39 |
40 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
41 | UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"Cell"];
42 | cell.textLabel.text = [[self.effects objectAtIndex:indexPath.row] objectForKey:@"title"];
43 |
44 | return cell;
45 | }
46 |
47 | #pragma mark - UITableViewDelegate
48 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
49 | [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
50 |
51 | DetailViewController *DVC =[[DetailViewController alloc] init];
52 | DVC.title = [[self.effects objectAtIndex:indexPath.row] objectForKey:@"title"];
53 | DVC.red = [[[[self.effects objectAtIndex:indexPath.row] objectForKey:@"backgroundColor"] objectAtIndex:0] floatValue];
54 | DVC.green = [[[[self.effects objectAtIndex:indexPath.row] objectForKey:@"backgroundColor"] objectAtIndex:1] floatValue];
55 | DVC.blue = [[[[self.effects objectAtIndex:indexPath.row] objectForKey:@"backgroundColor"] objectAtIndex:2] floatValue];
56 |
57 | [self.navigationController pushViewController:DVC animated:YES];
58 | }
59 |
60 | @end
61 |
--------------------------------------------------------------------------------
/CCTextFieldEffects.xcodeproj/xcshareddata/xcschemes/CCTextFieldEffects.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
34 |
35 |
45 |
46 |
52 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
70 |
71 |
72 |
73 |
75 |
76 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/PulsingHaloLayer.m:
--------------------------------------------------------------------------------
1 | //
2 | // PulsingHaloLayer.m
3 | // https://github.com/shu223/PulsingHalo
4 | //
5 | // Created by shuichi on 12/5/13.
6 | // Copyright (c) 2013 Shuichi Tsutsumi. All rights reserved.
7 | //
8 | // Inspired by https://github.com/samvermette/SVPulsingAnnotationView
9 |
10 |
11 | #import "PulsingHaloLayer.h"
12 |
13 |
14 | @interface PulsingHaloLayer ()
15 | @property (nonatomic, strong) CAAnimationGroup *animationGroup;
16 | @end
17 |
18 |
19 | @implementation PulsingHaloLayer
20 | @dynamic repeatCount;
21 |
22 | - (id)initWithRepeatCount:(float) repeatCount
23 | {
24 | self = [super init];
25 | if (self) {
26 | self.contentsScale = [UIScreen mainScreen].scale;
27 | self.opacity = 0;
28 |
29 | // default
30 | self.radius = 60;
31 | self.fromValueForRadius = 0.0;
32 | self.fromValueForAlpha = 0.45;
33 | self.keyTimeForHalfOpacity = 0.2;
34 | self.animationDuration = 1.0;
35 | self.pulseInterval = 0;
36 | self.repeatCount = 1;
37 | self.backgroundColor = [[UIColor colorWithRed:0.000 green:0.478 blue:1.000 alpha:1] CGColor];
38 | self.useTimingFunction = YES;
39 |
40 | // dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
41 | //
42 | //
43 | //
44 | // if(self.pulseInterval != INFINITY) {
45 | //
46 | // dispatch_async(dispatch_get_main_queue(), ^(void) {
47 | //
48 | // [self addAnimation:self.animationGroup forKey:@"pulse"];
49 | // });
50 | // }
51 | // });
52 | }
53 | return self;
54 |
55 | }
56 |
57 | - (id)init {
58 | return [self initWithRepeatCount:INFINITY];
59 | }
60 |
61 | - (void)setRadius:(CGFloat)radius {
62 |
63 | // _radius = radius;
64 | //
65 | // CGPoint tempPos = self.position;
66 | //
67 | // CGFloat diameter = self.radius * 2;
68 | //
69 | // self.bounds = CGRectMake(0, 0, diameter, diameter);
70 | // self.cornerRadius =0;
71 | // self.position = tempPos;
72 | }
73 |
74 | - (void)setupAnimationGroup {
75 |
76 | self.animationGroup = [CAAnimationGroup animation];
77 | self.animationGroup.duration = self.animationDuration + self.pulseInterval;
78 | self.animationGroup.repeatCount = self.repeatCount;
79 | self.animationGroup.removedOnCompletion = NO;
80 | if (self.useTimingFunction) {
81 | CAMediaTimingFunction *defaultCurve = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault];
82 | self.animationGroup.timingFunction = defaultCurve;
83 | }
84 |
85 | CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale.xy"];
86 | scaleAnimation.fromValue = @(1);
87 | scaleAnimation.toValue = @5.5;
88 | scaleAnimation.duration = self.animationDuration;
89 |
90 | CAKeyframeAnimation *opacityAnimation = [CAKeyframeAnimation animationWithKeyPath:@"opacity"];
91 | opacityAnimation.duration = self.animationDuration;
92 | opacityAnimation.values = @[@(self.fromValueForAlpha), @0.6, @0];
93 | opacityAnimation.keyTimes = @[@0, @(self.keyTimeForHalfOpacity), @1];
94 | opacityAnimation.removedOnCompletion = NO;
95 |
96 | NSArray *animations = @[scaleAnimation, opacityAnimation];
97 |
98 | self.animationGroup.animations = animations;
99 | self.animationGroup.delegate = self;
100 | }
101 |
102 |
103 | -(void)startAnimation{
104 | [self setupAnimationGroup];
105 | [self addAnimation:self.animationGroup forKey:@"pulse"];
106 | }
107 |
108 | -(void)stopAnimation{
109 | [self removeAllAnimations];
110 | }
111 |
112 | // =============================================================================
113 | #pragma mark - CAAnimation Delegate
114 |
115 | //- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
116 | //
117 | // if (flag) {
118 | // [self removeAllAnimations];
119 | // [self removeFromSuperlayer];
120 | // }
121 | //}
122 |
123 | @end
124 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/HideoTextField.m:
--------------------------------------------------------------------------------
1 | //
2 | // HideoTextField.m
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/27/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import "HideoTextField.h"
10 |
11 | @interface HideoTextField ()
12 |
13 | @property (strong, nonatomic) UIView *imageContainerView;
14 | @property (strong, nonatomic) UIImageView *imageView;
15 |
16 | @end
17 |
18 | @implementation HideoTextField
19 |
20 | #pragma mark - Constants
21 | static CGPoint const textFieldInsets = {6 ,0};
22 |
23 | #pragma mark - Custom accessorys
24 | - (void)setImageContainerColor:(UIColor *)imageContainerColor {
25 | _imageContainerColor = imageContainerColor;
26 |
27 | self.imageContainerView.backgroundColor = imageContainerColor;
28 | }
29 |
30 | - (void)setImage:(UIImage *)image {
31 | _image = image;
32 |
33 | self.imageView.image = image;
34 | }
35 |
36 | #pragma mark - Lifecycle
37 | - (instancetype)initWithFrame:(CGRect)frame {
38 | self = [super initWithFrame:frame];
39 |
40 | if (self) {
41 | [self commonInit];
42 | }
43 |
44 | return self;
45 | }
46 |
47 | - (instancetype) initWithCoder:(NSCoder *)aDecoder {
48 | self = [super initWithCoder:aDecoder];
49 |
50 | if (self) {
51 | [self commonInit];
52 | }
53 | return self;
54 | }
55 |
56 | - (void) commonInit {
57 | self.imageContainerView = [[UIView alloc] init];
58 | self.imageView = [[UIImageView alloc] init];
59 |
60 | self.imageContainerColor = [UIColor colorWithRed:0.5373 green:0.6157 blue:0.8549 alpha:1.0];
61 | self.imageView.backgroundColor = [UIColor clearColor];
62 | self.backgroundColor = [UIColor whiteColor];
63 | self.cursorColor = [UIColor colorWithRed:0.6667 green:0.6667 blue:0.6667 alpha:1.0];
64 | self.textColor = self.cursorColor;
65 |
66 | self.imageScale = 0.7;
67 | }
68 |
69 | #pragma mark - Overridden methods
70 | - (void)drawRect:(CGRect)rect {
71 | self.imageContainerView.frame = CGRectMake(0, 0, CGRectGetHeight(rect), CGRectGetHeight(rect));
72 | [self addSubview:self.imageContainerView];
73 |
74 | self.imageView.frame = CGRectMake(0, 0, CGRectGetWidth(self.imageContainerView.frame)/3, CGRectGetHeight(self.imageContainerView.frame)/3);
75 | self.imageView.center = self.imageContainerView.center;
76 | [self.imageContainerView addSubview:self.imageView];
77 | }
78 |
79 | - (CGRect)editingRectForBounds:(CGRect)bounds {
80 | CGRect frame = CGRectMake(CGRectGetWidth(self.imageContainerView.frame), 0, CGRectGetWidth(bounds)-CGRectGetWidth(self.imageContainerView.frame), CGRectGetHeight(bounds));
81 |
82 | return CGRectInset(frame, textFieldInsets.x, textFieldInsets.y);
83 | }
84 |
85 | - (CGRect)textRectForBounds:(CGRect)bounds {
86 | CGRect frame = CGRectMake(CGRectGetWidth(self.imageContainerView.frame), 0, CGRectGetWidth(bounds)-CGRectGetWidth(self.imageContainerView.frame), CGRectGetHeight(bounds));
87 |
88 | return CGRectInset(frame, textFieldInsets.x, textFieldInsets.y);
89 | }
90 |
91 | - (void)animateViewsForTextEntry {
92 | if ([self isFirstResponder] && self.text.length == 0) {
93 | // Prevent cursor display in front of the container view when animating.
94 | [self bringSubviewToFront:self.imageContainerView];
95 |
96 | [UIView animateWithDuration:0.27 animations:^{
97 | self.imageContainerView.frame = CGRectMake(0, 0, CGRectGetWidth(self.imageContainerView.frame)*0.67, CGRectGetHeight(self.imageContainerView.frame));
98 | self.imageView.transform = CGAffineTransformMakeScale(self.imageScale, self.imageScale);
99 | self.imageView.center = self.imageContainerView.center;
100 | } completion:^(BOOL finished) {
101 | if (self.didBeginEditingHandler != nil) {
102 | self.didBeginEditingHandler();
103 | }
104 | }];
105 | }
106 | }
107 |
108 | - (void)animateViewsForTextDisplay {
109 | if (self.text.length == 0) {
110 | [UIView animateWithDuration:0.27 animations:^{
111 | self.imageContainerView.frame = CGRectMake(0, 0, CGRectGetHeight(self.frame), CGRectGetHeight(self.imageContainerView.frame));
112 | self.imageView.transform = CGAffineTransformIdentity;
113 | self.imageView.center = self.imageContainerView.center;
114 | } completion:^(BOOL finished) {
115 | if (self.didEndEditingHandler != nil) {
116 | self.didEndEditingHandler();
117 | }
118 | }];
119 | }
120 | }
121 |
122 | #pragma mark - Private methods
123 |
124 | @end
125 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/KohanaTextField.m:
--------------------------------------------------------------------------------
1 | //
2 | // KohanaTextField.m
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 7/1/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import "KohanaTextField.h"
10 |
11 | @interface KohanaTextField ()
12 |
13 | @property (strong, nonatomic) UIImageView *imageView;
14 |
15 | @end
16 |
17 | @implementation KohanaTextField
18 |
19 | #pragma mark - Constants
20 | static CGPoint const placeholderInsets = {0, 0};
21 | static CGPoint const textFieldInsets = {6, 0};
22 |
23 | #pragma mark - Custom accessorys
24 | - (void)setPlaceholderColor:(UIColor *)placeholderColor {
25 | _placeholderColor = placeholderColor;
26 |
27 | self.placeholderLabel.textColor = placeholderColor;
28 | [self.imageView setTintColor:placeholderColor];
29 | }
30 |
31 | - (void)setImage:(UIImage *)image {
32 | _image = image;
33 |
34 | self.imageView.image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
35 | }
36 |
37 | - (void)setPlaceholderFontScale:(CGFloat)placeholderFontScale {
38 | _placeholderFontScale = placeholderFontScale;
39 |
40 | self.placeholderLabel.font = [self placeholderFontFromFont:self.font];
41 | }
42 |
43 | - (void)setPlaceholder:(NSString *)placeholder {
44 | [super setPlaceholder:placeholder];
45 |
46 | self.placeholderLabel.text = placeholder;
47 | }
48 |
49 | #pragma mark - Lifecycle
50 | - (instancetype)initWithFrame:(CGRect)frame {
51 | self = [super initWithFrame:frame];
52 |
53 | if (self) {
54 | [self commonInit];
55 | }
56 |
57 | return self;
58 | }
59 |
60 | - (instancetype) initWithCoder:(NSCoder *)aDecoder {
61 | self = [super initWithCoder:aDecoder];
62 |
63 | if (self) {
64 | [self commonInit];
65 | }
66 | return self;
67 | }
68 |
69 | - (void) commonInit {
70 | self.placeholderLabel = [[UILabel alloc] init];
71 | self.imageView = [[UIImageView alloc] init];
72 |
73 | self.placeholderColor = [UIColor colorWithRed:0.8235 green:0.8235 blue:0.8235 alpha:1];
74 | self.cursorColor = [UIColor colorWithRed:0.4157 green:0.4745 blue:0.5373 alpha:1];
75 | self.textColor = self.cursorColor;
76 | self.backgroundColor = [UIColor whiteColor];
77 |
78 | self.placeholderFontScale = 0.8;
79 | }
80 |
81 | #pragma mark - Overridden methods
82 | - (void)drawRect:(CGRect)rect {
83 | CGFloat length = CGRectGetHeight(rect);
84 |
85 | self.imageView.frame = CGRectInset(CGRectMake(-length, 0, length, length), length*0.25, length*0.25);
86 | self.imageView.transform = CGAffineTransformMakeScale(0.7, 0.7);
87 | [self addSubview:self.imageView];
88 |
89 | CGRect frame = CGRectMake(0, 0, CGRectGetWidth(rect), length);;
90 | self.placeholderLabel.frame = CGRectInset(frame, length*0.3, placeholderInsets.y);
91 | [self addSubview:self.placeholderLabel];
92 | }
93 |
94 |
95 | - (CGRect)textRectForBounds:(CGRect)bounds {
96 | CGFloat length = CGRectGetHeight(self.bounds);
97 |
98 | CGRect rect = CGRectOffset(bounds, length+textFieldInsets.x, 0);
99 | return CGRectMake(rect.origin.x, rect.origin.y, CGRectGetWidth(rect)-2*textFieldInsets.x-length, CGRectGetHeight(rect));
100 | }
101 |
102 | - (CGRect)editingRectForBounds:(CGRect)bounds {
103 | CGFloat length = CGRectGetHeight(self.bounds);
104 |
105 | CGRect rect = CGRectOffset(bounds, length+textFieldInsets.x, 0);
106 | return CGRectMake(rect.origin.x, rect.origin.y, CGRectGetWidth(rect)-2*textFieldInsets.x-length, CGRectGetHeight(rect));
107 | }
108 |
109 | - (void)animateViewsForTextEntry {
110 | if (self.text.length == 0) {
111 | [UIView animateWithDuration:0.25 animations:^{
112 | CGFloat length = CGRectGetHeight(self.bounds);
113 |
114 | self.imageView.frame = CGRectOffset(self.imageView.frame, length, 0);
115 | self.placeholderLabel.frame = CGRectOffset(self.placeholderLabel.frame, length, 0);
116 | self.placeholderLabel.alpha = 0;
117 | } completion:^(BOOL finished) {
118 |
119 | }];
120 | }
121 | }
122 |
123 | - (void)animateViewsForTextDisplay {
124 | if (self.text.length == 0) {
125 | [UIView animateWithDuration:0.24 animations:^{
126 | CGFloat length = CGRectGetHeight(self.bounds);
127 |
128 | self.imageView.frame = CGRectOffset(self.imageView.frame, -length, 0);
129 | self.placeholderLabel.frame = CGRectOffset(self.placeholderLabel.frame, -length, 0);
130 | self.placeholderLabel.alpha = 1;
131 | } completion:^(BOOL finished) {
132 |
133 | }];
134 | }
135 | }
136 |
137 | #pragma mark - Private methods
138 | - (UIFont *)placeholderFontFromFont:(UIFont *)font {
139 | UIFont *smallerFont = [UIFont fontWithName:font.fontName size:font.pointSize*self.placeholderFontScale];
140 |
141 | return smallerFont;
142 | }
143 |
144 | @end
145 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/AkiraTextField.m:
--------------------------------------------------------------------------------
1 | //
2 | // AkiraTextField.m
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/25/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import "AkiraTextField.h"
10 |
11 | @interface AkiraTextField ()
12 |
13 | @property (strong, nonatomic) CALayer *borderLayer;
14 | @property (nonatomic) CGFloat placeholderHeight;
15 |
16 | @end
17 |
18 | @implementation AkiraTextField
19 |
20 | #pragma mark - Constants
21 | static CGFloat const activeSize = 1.2;
22 | static CGFloat const inactiveSize = 2.5;
23 | static CGPoint const textFieldInsets = {6, 0};
24 | static CGPoint const placeHolderInsets = {6, 0};
25 |
26 | #pragma mark - Custom accessorys
27 | - (void)setBorderColor:(UIColor *)borderColor {
28 | _borderColor = borderColor;
29 |
30 | [self updateBorder];
31 | }
32 |
33 | - (void)setPlaceholderColor:(UIColor *)placeholderColor {
34 | _placeholderColor = placeholderColor;
35 |
36 | [self updatePlaceholder];
37 | }
38 |
39 | - (void)setPlaceholderFontScale:(CGFloat)placeholderFontScale {
40 | _placeholderFontScale = placeholderFontScale;
41 |
42 | [self updatePlaceholder];
43 | }
44 |
45 | - (void)setPlaceholder:(NSString *)placeholder {
46 | [super setPlaceholder:placeholder];
47 |
48 | [self updatePlaceholder];
49 | }
50 |
51 | - (void)setBounds:(CGRect)bounds {
52 | [super setBounds:bounds];
53 |
54 | [self updateBorder];
55 | }
56 |
57 | - (CGFloat)placeholderHeight {
58 | return placeHolderInsets.y + [self placeholderFontFromFont:self.font].lineHeight;
59 | }
60 |
61 | #pragma mark - Lifecycle
62 | - (instancetype)initWithFrame:(CGRect)frame {
63 | self = [super initWithFrame:frame];
64 |
65 | if (self) {
66 | [self commonInit];
67 | }
68 |
69 | return self;
70 | }
71 |
72 | - (instancetype) initWithCoder:(NSCoder *)aDecoder {
73 | self = [super initWithCoder:aDecoder];
74 |
75 | if (self) {
76 | [self commonInit];
77 | }
78 | return self;
79 | }
80 |
81 | - (void) commonInit {
82 | self.borderLayer = [[CALayer alloc] init];
83 | self.placeholderLabel = [[UILabel alloc] init];
84 |
85 | self.borderColor = [UIColor colorWithRed:0.4118 green:0.4157 blue:0.4314 alpha:1.0];
86 | self.placeholderColor = [UIColor colorWithRed:0.8 green:0.3765 blue:0.3333 alpha:1.0];
87 | self.cursorColor = self.borderColor;
88 | self.textColor = [UIColor colorWithRed:0.6667 green:0.6667 blue:0.6667 alpha:1.0];
89 |
90 | self.placeholderFontScale = 0.7;
91 | }
92 |
93 | #pragma mark - Overridden methods
94 | - (void)drawRect:(CGRect)rect {
95 | [self updateBorder];
96 | [self updatePlaceholder];
97 |
98 | [self addSubview:self.placeholderLabel];
99 | [self.layer addSublayer:self.borderLayer];
100 | }
101 |
102 | - (CGRect)placeholderRectForBounds:(CGRect)bounds {
103 | if ([self isFirstResponder] || self.text.length!=0) {
104 | return CGRectMake(placeHolderInsets.x, placeHolderInsets.y, bounds.size.width, self.placeholderHeight);
105 | } else {
106 | return [self textRectForBounds:bounds];
107 | }
108 | }
109 |
110 | - (CGRect)editingRectForBounds:(CGRect)bounds {
111 | return [self textRectForBounds:bounds];
112 | }
113 |
114 | - (CGRect)textRectForBounds:(CGRect)bounds {
115 | return CGRectOffset(bounds, textFieldInsets.x, textFieldInsets.y+self.placeholderHeight/2);
116 | }
117 |
118 | - (void)animateViewsForTextEntry {
119 | [UIView animateWithDuration:0.35 animations:^{
120 | [self updateBorder];
121 | [self updatePlaceholder];
122 | } completion:^(BOOL finished) {
123 | if (self.didBeginEditingHandler != nil) {
124 | self.didBeginEditingHandler();
125 | }
126 | }];
127 | }
128 |
129 | - (void)animateViewsForTextDisplay {
130 | [UIView animateWithDuration:0.35 animations:^{
131 | [self updateBorder];
132 | [self updatePlaceholder];
133 | } completion:^(BOOL finished) {
134 | if (self.didEndEditingHandler != nil) {
135 | self.didEndEditingHandler();
136 | }
137 | }];
138 | }
139 |
140 | #pragma mark - Private methods
141 | - (void)updateBorder {
142 | self.borderLayer.frame = [self rectForBounds:self.bounds];
143 | self.borderLayer.borderWidth = ([self isFirstResponder] || self.text.length!=0)?activeSize:inactiveSize;
144 | self.borderLayer.borderColor = self.borderColor.CGColor;
145 | }
146 |
147 | - (void)updatePlaceholder {
148 | self.placeholderLabel.frame = [self placeholderRectForBounds:self.bounds];
149 | self.placeholderLabel.text = self.placeholder;
150 | self.placeholderLabel.font = [self placeholderFontFromFont:self.font];
151 | self.placeholderLabel.textColor = self.placeholderColor;
152 | }
153 |
154 | - (UIFont *)placeholderFontFromFont:(UIFont *)font {
155 | UIFont *smallerFont = [UIFont fontWithName:font.fontName size:font.pointSize*self.placeholderFontScale];
156 |
157 | return smallerFont;
158 | }
159 |
160 | - (CGRect)rectForBounds:(CGRect)bounds {
161 | return CGRectMake(bounds.origin.x, bounds.origin.y+self.placeholderHeight, bounds.size.width, bounds.size.height-self.placeholderHeight);
162 | }
163 |
164 | @end
165 |
--------------------------------------------------------------------------------
/CCTextFieldEffectsDemo/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
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 |
69 |
70 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/KaedeTextField.m:
--------------------------------------------------------------------------------
1 | //
2 | // KaedeTextField.m
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/26/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import "KaedeTextfield.h"
10 |
11 | @interface KaedeTextField ()
12 |
13 | @property (strong, nonatomic) UIView *foregroundView;
14 |
15 | @end
16 |
17 | @implementation KaedeTextField
18 |
19 | #pragma mark - Constants
20 | static CGPoint const textFieldInsets = {10, 0};
21 | static CGPoint const placeholderInsets = {10, 5};
22 |
23 | #pragma mark - Custom accessorys
24 | - (void)setPlaceholderColor:(UIColor *)placeholderColor {
25 | _placeholderColor = placeholderColor;
26 |
27 | [self updatePlaceholder];
28 | }
29 |
30 | - (void)setForegroundColor:(UIColor *)foregroundColor {
31 | _foregroundColor = foregroundColor;
32 |
33 | [self updateForegroundColor];
34 | }
35 |
36 | - (void)setPlaceholderFontScale:(CGFloat)placeholderFontScale {
37 | _placeholderFontScale = placeholderFontScale;
38 |
39 | [self updatePlaceholder];
40 | }
41 |
42 | - (void)setPlaceholder:(NSString *)placeholder {
43 | [super setPlaceholder:placeholder];
44 |
45 | [self updatePlaceholder];
46 | }
47 |
48 | - (void)setBounds:(CGRect)bounds {
49 | [super setBounds:bounds];
50 |
51 | [self drawRect:bounds];
52 | }
53 |
54 | #pragma mark - Lifecycle
55 | - (instancetype)initWithFrame:(CGRect)frame {
56 | self = [super initWithFrame:frame];
57 |
58 | if (self) {
59 | [self commonInit];
60 | }
61 |
62 | return self;
63 | }
64 |
65 | - (instancetype) initWithCoder:(NSCoder *)aDecoder {
66 | self = [super initWithCoder:aDecoder];
67 |
68 | if (self) {
69 | [self commonInit];
70 | }
71 | return self;
72 | }
73 |
74 | - (void) commonInit {
75 | self.foregroundView = [[UIView alloc] init];
76 | self.placeholderLabel = [[UILabel alloc] init];
77 |
78 | self.placeholderColor = [UIColor colorWithRed:0.4157 green:0.4745 blue:0.5373 alpha:1.0];
79 | self.foregroundColor = [UIColor colorWithRed:0.9373 green:0.9333 blue:0.9333 alpha:1.0];
80 | self.cursorColor = [UIColor colorWithRed:0.6157 green:0.6706 blue:0.7294 alpha:1.0];
81 | self.textColor = self.cursorColor;
82 | self.backgroundColor = [UIColor whiteColor];
83 |
84 | self.placeholderFontScale = 0.8;
85 | }
86 |
87 | #pragma mark - Overridden methos
88 | - (void)drawRect:(CGRect)rect {
89 | CGRect frame = CGRectMake(0, 0, CGRectGetWidth(rect), CGRectGetHeight(rect));
90 |
91 | self.foregroundView.frame = frame;
92 | self.foregroundView.userInteractionEnabled = NO;
93 | self.placeholderLabel.frame = CGRectInset(frame, placeholderInsets.x, placeholderInsets.y);
94 | self.placeholderLabel.font = [self placeholderFontFromFont:self.font];
95 |
96 | [self updateForegroundColor];
97 | [self updatePlaceholder];
98 |
99 | if (self.text.length!=0 || [self isFirstResponder]) {
100 | [self animateViewsForTextEntry];
101 | }
102 |
103 | [self addSubview:self.foregroundView];
104 | [self addSubview:self.placeholderLabel];
105 | }
106 |
107 | - (CGRect)editingRectForBounds:(CGRect)bounds {
108 | CGRect frame = CGRectMake(bounds.origin.x, bounds.origin.y, CGRectGetWidth(bounds)*0.6, CGRectGetHeight(bounds));
109 |
110 | return CGRectInset(frame, textFieldInsets.x, textFieldInsets.y);
111 | }
112 |
113 | - (CGRect)textRectForBounds:(CGRect)bounds {
114 | CGRect frame = CGRectMake(bounds.origin.x, bounds.origin.y, CGRectGetWidth(bounds)*0.6, CGRectGetHeight(bounds));
115 |
116 | return CGRectInset(frame, textFieldInsets.x, textFieldInsets.y);
117 | }
118 |
119 | - (void)animateViewsForTextEntry {
120 | [UIView animateWithDuration:0.16 animations:^{
121 | self.placeholderLabel.frame = CGRectMake(CGRectGetWidth(self.frame)*0.7, placeholderInsets.y, CGRectGetWidth(self.placeholderLabel.frame), CGRectGetHeight(self.placeholderLabel.frame));
122 | }];
123 |
124 | [UIView animateWithDuration:0.22 animations:^{
125 | self.foregroundView.frame = CGRectMake(CGRectGetWidth(self.frame)*0.65, 0, CGRectGetWidth(self.foregroundView.frame), CGRectGetHeight(self.foregroundView.frame));
126 | } completion:^(BOOL finished) {
127 | if (self.didBeginEditingHandler != nil) {
128 | self.didBeginEditingHandler();
129 | }
130 | }];
131 | }
132 |
133 | - (void)animateViewsForTextDisplay {
134 | if (self.text.length == 0) {
135 | [UIView animateWithDuration:0.3 animations:^{
136 | self.placeholderLabel.frame = CGRectMake(placeholderInsets.x, placeholderInsets.y, CGRectGetWidth(self.placeholderLabel.frame), CGRectGetHeight(self.placeholderLabel.frame));
137 | }];
138 |
139 | [UIView animateWithDuration:0.3 animations:^{
140 | self.foregroundView.frame = CGRectMake(0, 0, CGRectGetWidth(self.foregroundView.frame), CGRectGetHeight(self.foregroundView.frame));
141 | } completion:^(BOOL finished) {
142 | if (self.didEndEditingHandler != nil) {
143 | self.didEndEditingHandler();
144 | }
145 | }];
146 | }
147 | }
148 |
149 | #pragma mark - Private methos
150 | - (void)updatePlaceholder {
151 | self.placeholderLabel.text = self.placeholder;
152 | self.placeholderLabel.textColor = self.placeholderColor;
153 | }
154 |
155 | - (void)updateForegroundColor {
156 | self.foregroundView.backgroundColor = self.foregroundColor;
157 | }
158 |
159 | - (UIFont *)placeholderFontFromFont:(UIFont *)font {
160 | UIFont *smallerFont = [UIFont fontWithName:font.fontName size:font.pointSize*self.placeholderFontScale];
161 |
162 | return smallerFont;
163 | }
164 |
165 | @end
166 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/HarukiTextField.m:
--------------------------------------------------------------------------------
1 | //
2 | // HarukiTextField.m
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/28/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import "HarukiTextField.h"
10 |
11 | @interface HarukiTextField ()
12 |
13 | @property (strong, nonatomic) CALayer *upperLayer;
14 | @property (strong, nonatomic) CALayer *lowerLayer;
15 | @property (nonatomic) CGFloat placeholderHeight;
16 |
17 | @end
18 |
19 | @implementation HarukiTextField
20 |
21 | #pragma mark - Constants
22 | static CGFloat const borderSize = 3;
23 | static CGFloat const borderMoveDistance = 8;
24 | static CGPoint const textFieldInsets = {8, 0};
25 | static CGPoint const placeHolderInsets = {8, 0};
26 |
27 | #pragma mark - Custom accessorys
28 | - (void)setBorderColor:(UIColor *)borderColor {
29 | _borderColor = borderColor;
30 |
31 | self.upperLayer.borderColor = borderColor.CGColor;
32 | self.lowerLayer.borderColor = borderColor.CGColor;
33 | }
34 |
35 | - (void)setPlaceholderColor:(UIColor *)placeholderColor {
36 | _placeholderColor = placeholderColor;
37 |
38 | self.placeholderLabel.textColor = placeholderColor;
39 | }
40 |
41 | - (void)setPlaceholderFontScale:(CGFloat)placeholderFontScale {
42 | _placeholderFontScale = placeholderFontScale;
43 |
44 | self.placeholderLabel.font = [self placeholderFontFromFont:self.font];
45 | }
46 |
47 | - (void)setPlaceholder:(NSString *)placeholder {
48 | [super setPlaceholder:placeholder];
49 |
50 | self.placeholderLabel.text = placeholder;
51 | }
52 |
53 | - (CGFloat)placeholderHeight {
54 | return placeHolderInsets.y + [self placeholderFontFromFont:self.font].lineHeight;
55 | }
56 |
57 | #pragma mark - Liftcycle
58 | - (instancetype)initWithFrame:(CGRect)frame {
59 | self = [super initWithFrame:frame];
60 |
61 | if (self) {
62 | [self commonInit];
63 | }
64 |
65 | return self;
66 | }
67 |
68 | - (instancetype) initWithCoder:(NSCoder *)aDecoder {
69 | self = [super initWithCoder:aDecoder];
70 |
71 | if (self) {
72 | [self commonInit];
73 | }
74 | return self;
75 | }
76 |
77 | - (void) commonInit {
78 | self.upperLayer = [[CALayer alloc] init];
79 | self.upperLayer.borderWidth = borderSize;
80 |
81 | self.lowerLayer = [[CALayer alloc] init];
82 | self.lowerLayer.borderWidth = borderSize;
83 |
84 | self.placeholderLabel = [[UILabel alloc] init];
85 |
86 | self.borderColor = [UIColor colorWithRed:0.4147 green:0.4745 blue:0.5373 alpha:1];
87 | self.placeholderColor = self.borderColor;
88 | self.cursorColor = [UIColor colorWithRed:0.6863 green:0.7098 blue:0.7333 alpha:1];
89 | self.textColor = self.cursorColor;
90 |
91 | self.placeholderFontScale = 0.75;
92 | }
93 |
94 | #pragma mark - Overridden methods
95 | - (void)drawRect:(CGRect)rect {
96 | self.upperLayer.frame = CGRectMake(0, self.placeholderHeight+borderMoveDistance, CGRectGetWidth(self.bounds), borderSize);
97 | [self.layer addSublayer:self.upperLayer];
98 |
99 | self.lowerLayer.frame = CGRectMake(0, CGRectGetHeight(self.bounds)-borderSize-borderMoveDistance, CGRectGetWidth(self.bounds), borderSize);
100 | [self.layer addSublayer:self.lowerLayer];
101 |
102 | self.placeholderLabel.frame = [self placeholderRectForBounds:self.bounds];
103 | [self addSubview:self.placeholderLabel];
104 | }
105 |
106 | - (CGRect)placeholderRectForBounds:(CGRect)bounds {
107 | if ([self isFirstResponder] || self.text.length!=0) {
108 | return CGRectMake(placeHolderInsets.x, placeHolderInsets.y, bounds.size.width, self.placeholderHeight);
109 | } else {
110 | return [self textRectForBounds:bounds];
111 | }
112 | }
113 |
114 | - (CGRect)editingRectForBounds:(CGRect)bounds {
115 | return [self textRectForBounds:bounds];
116 | }
117 |
118 | - (CGRect)textRectForBounds:(CGRect)bounds {
119 | return CGRectOffset(bounds, textFieldInsets.x, textFieldInsets.y+self.placeholderHeight/2);
120 | }
121 |
122 | - (void)animateViewsForTextEntry {
123 | if (self.text.length == 0) {
124 | // Hide the cursor when the animating
125 | UIColor *originalCursorColor = self.cursorColor;
126 | self.cursorColor = [UIColor clearColor];
127 |
128 | [UIView animateWithDuration:0.35 animations:^{
129 | self.upperLayer.frame = CGRectMake(0, self.placeholderHeight*1.1, CGRectGetWidth(self.bounds), borderSize);
130 | self.lowerLayer.frame = CGRectMake(0, CGRectGetHeight(self.bounds)-borderSize, CGRectGetWidth(self.bounds), borderSize);
131 | self.placeholderLabel.frame = [self placeholderRectForBounds:self.bounds];
132 | } completion:^(BOOL finished) {
133 | self.cursorColor = originalCursorColor;
134 |
135 | if (self.didBeginEditingHandler != nil) {
136 | self.didBeginEditingHandler();
137 | }
138 | }];
139 | }
140 | }
141 |
142 | - (void)animateViewsForTextDisplay {
143 | if (self.text.length == 0) {
144 | [UIView animateWithDuration:0.35 animations:^{
145 | self.upperLayer.frame = CGRectMake(0, self.placeholderHeight+borderMoveDistance, CGRectGetWidth(self.bounds), borderSize);
146 | self.lowerLayer.frame = CGRectMake(0, CGRectGetHeight(self.bounds)-borderSize-borderMoveDistance, CGRectGetWidth(self.bounds), borderSize);
147 | self.placeholderLabel.frame = [self placeholderRectForBounds:self.bounds];
148 | } completion:^(BOOL finished) {
149 | if (self.didEndEditingHandler != nil) {
150 | self.didEndEditingHandler();
151 | }
152 | }];
153 | }
154 | }
155 |
156 | #pragma mark - Private methods
157 | - (UIFont *)placeholderFontFromFont:(UIFont *)font {
158 | UIFont *smallerFont = [UIFont fontWithName:font.fontName size:font.pointSize*self.placeholderFontScale];
159 |
160 | return smallerFont;
161 | }
162 |
163 | @end
164 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/ChisatoTextField.m:
--------------------------------------------------------------------------------
1 | //
2 | // ChisatoTextField.m
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/29/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import "ChisatoTextField.h"
10 |
11 | @interface ChisatoTextField ()
12 |
13 | @property (strong, nonatomic) CALayer *borderLayer;
14 | @property (nonatomic) CGFloat placeholderHeight;
15 |
16 | @end
17 |
18 | @implementation ChisatoTextField
19 |
20 | #pragma mark - Constants
21 | static CGFloat const borderSize = 2.5;
22 | static CGPoint const textFieldInsets = {8, 0};
23 | static CGPoint const placeHolderInsets = {8, 0};
24 |
25 | #pragma mark - Custom accessorys
26 | - (void)setBorderColor:(UIColor *)borderColor {
27 | _borderColor = borderColor;
28 |
29 | [self updateBorder];
30 | }
31 |
32 | - (void)setPlaceholderColor:(UIColor *)placeholderColor {
33 | _placeholderColor = placeholderColor;
34 |
35 | [self updatePlaceholder];
36 | }
37 |
38 | - (void)setPlaceholderFontScale:(CGFloat)placeholderFontScale {
39 | _placeholderFontScale = placeholderFontScale;
40 |
41 | [self updatePlaceholder];
42 | }
43 |
44 | - (void)setPlaceholder:(NSString *)placeholder {
45 | [super setPlaceholder:placeholder];
46 |
47 | [self updatePlaceholder];
48 | }
49 |
50 | - (void)setBounds:(CGRect)bounds {
51 | [super setBounds:bounds];
52 |
53 | [self updateBorder];
54 | }
55 |
56 | - (CGFloat)placeholderHeight {
57 | return placeHolderInsets.y + [self placeholderFontFromFont:self.font].lineHeight;
58 | }
59 |
60 | #pragma mark - Lifecycle
61 | - (instancetype)initWithFrame:(CGRect)frame {
62 | self = [super initWithFrame:frame];
63 |
64 | if (self) {
65 | [self commonInit];
66 | }
67 |
68 | return self;
69 | }
70 |
71 | - (instancetype) initWithCoder:(NSCoder *)aDecoder {
72 | self = [super initWithCoder:aDecoder];
73 |
74 | if (self) {
75 | [self commonInit];
76 | }
77 | return self;
78 | }
79 |
80 | - (void) commonInit {
81 | self.borderLayer = [[CALayer alloc] init];
82 | self.placeholderLabel = [[UILabel alloc] init];
83 |
84 | self.borderColor = [UIColor colorWithRed:0.7098 green:0.7098 blue:0.7098 alpha:1.0];
85 | self.placeholderColor = self.borderColor;
86 | self.cursorColor = self.borderColor;
87 | self.textColor = self.borderColor;
88 | self.activeColor = [UIColor colorWithRed:0.8549 green:0.3922 blue:0.5176 alpha:1];
89 |
90 | self.placeholderFontScale = 0.8;
91 | }
92 |
93 | #pragma mark - Overridden methods
94 | - (void)drawRect:(CGRect)rect {
95 | [self updateBorder];
96 | [self updatePlaceholder];
97 |
98 | [self addSubview:self.placeholderLabel];
99 | [self.layer addSublayer:self.borderLayer];
100 | }
101 |
102 | - (CGRect)placeholderRectForBounds:(CGRect)bounds {
103 | if ([self isFirstResponder] || self.text.length!=0) {
104 | return CGRectMake(placeHolderInsets.x, placeHolderInsets.y, bounds.size.width, self.placeholderHeight);
105 | } else {
106 | return [self textRectForBounds:bounds];
107 | }
108 | }
109 |
110 | - (CGRect)editingRectForBounds:(CGRect)bounds {
111 | return [self textRectForBounds:bounds];
112 | }
113 |
114 | - (CGRect)textRectForBounds:(CGRect)bounds {
115 | return CGRectOffset(bounds, textFieldInsets.x, textFieldInsets.y+self.placeholderHeight/2);
116 | }
117 |
118 | - (void)animateViewsForTextEntry {
119 | if (self.text.length == 0) {
120 | [UIView animateWithDuration:0.1 animations:^{
121 | self.placeholderLabel.frame = CGRectOffset(self.placeholderLabel.frame, 0, self.placeholderHeight*2);
122 | self.borderLayer.borderColor = self.activeColor.CGColor;
123 | } completion:^(BOOL finished) {
124 | self.placeholderLabel.alpha = 0;
125 | self.placeholderLabel.frame = CGRectOffset([self placeholderRectForBounds:self.bounds], 0, -self.placeholderHeight*2);
126 | [UIView animateWithDuration:0.15 animations:^{
127 | self.placeholderLabel.textColor = self.activeColor;
128 | self.placeholderLabel.alpha = 1;
129 | self.placeholderLabel.frame = [self placeholderRectForBounds:self.bounds];
130 | } completion:^(BOOL finished) {
131 | if (self.didBeginEditingHandler != nil) {
132 | self.didBeginEditingHandler();
133 | }
134 | }];
135 | }];
136 | }
137 | }
138 |
139 | - (void)animateViewsForTextDisplay {
140 | if (self.text.length == 0) {
141 | [UIView animateWithDuration:0.15 animations:^{
142 | self.borderLayer.borderColor = self.borderColor.CGColor;
143 | self.placeholderLabel.alpha = 0;
144 | } completion:^(BOOL finished) {
145 | self.placeholderLabel.textColor = self.placeholderColor;
146 | self.placeholderLabel.frame = [self placeholderRectForBounds:self.bounds];
147 | self.placeholderLabel.alpha = 1;
148 | if (self.didEndEditingHandler != nil) {
149 | self.didEndEditingHandler();
150 | }
151 | }];
152 | }
153 | }
154 |
155 | #pragma mark - Private methods
156 | - (void)updateBorder {
157 | self.borderLayer.frame = [self rectForBounds:self.bounds];
158 | self.borderLayer.borderWidth = borderSize;
159 | self.borderLayer.borderColor = self.borderColor.CGColor;
160 | }
161 |
162 | - (void)updatePlaceholder {
163 | self.placeholderLabel.frame = [self placeholderRectForBounds:self.bounds];
164 | self.placeholderLabel.text = self.placeholder;
165 | self.placeholderLabel.font = [self placeholderFontFromFont:self.font];
166 | self.placeholderLabel.textColor = self.placeholderColor;
167 | }
168 |
169 | - (UIFont *)placeholderFontFromFont:(UIFont *)font {
170 | UIFont *smallerFont = [UIFont fontWithName:font.fontName size:font.pointSize*self.placeholderFontScale];
171 |
172 | return smallerFont;
173 | }
174 |
175 | - (CGRect)rectForBounds:(CGRect)bounds {
176 | return CGRectMake(bounds.origin.x, bounds.origin.y+self.placeholderHeight, bounds.size.width, bounds.size.height-self.placeholderHeight);
177 | }
178 |
179 | @end
180 |
181 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/SaeTextField.m:
--------------------------------------------------------------------------------
1 | //
2 | // SaeTextField.m
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 7/1/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import "SaeTextField.h"
10 |
11 | @interface SaeTextField ()
12 |
13 | @property (strong, nonatomic) UIImageView *imageView;
14 | @property (strong, nonatomic) UIView *borderView;
15 |
16 | @end
17 |
18 | @implementation SaeTextField
19 |
20 | #pragma mark - Constants
21 | static CGFloat const borderTickness = 2;
22 | static CGPoint const textFieldInset = {0, 6};
23 | static CGPoint const placeholderInset = {0, 6};
24 |
25 | #pragma mark - Custom accessorys
26 | - (void)setBorderColor:(UIColor *)borderColor {
27 | _borderColor = borderColor;
28 |
29 | self.borderView.backgroundColor = borderColor;
30 | [self.imageView setTintColor:borderColor];
31 | }
32 |
33 | - (void)setImage:(UIImage *)image {
34 | _image = image;
35 |
36 | self.imageView.image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
37 | }
38 |
39 | - (void)setPlaceholderColor:(UIColor *)placeholderColor {
40 | _placeholderColor = placeholderColor;
41 |
42 | self.placeholderLabel.textColor = placeholderColor;
43 | }
44 |
45 | - (void)setPlaceholderFontScale:(CGFloat)placeholderFontScale {
46 | _placeholderFontScale = placeholderFontScale;
47 |
48 | self.placeholderLabel.font = [self placeholderFontFromFont:self.font];
49 | }
50 |
51 | - (void)setPlaceholder:(NSString *)placeholder {
52 | [super setPlaceholder:placeholder];
53 |
54 | self.placeholderLabel.text = placeholder;
55 | }
56 |
57 | #pragma mark - Lifecycle
58 | - (instancetype)initWithFrame:(CGRect)frame {
59 | self = [super initWithFrame:frame];
60 |
61 | if (self) {
62 | [self commonInit];
63 | }
64 |
65 | return self;
66 | }
67 |
68 | - (instancetype) initWithCoder:(NSCoder *)aDecoder {
69 | self = [super initWithCoder:aDecoder];
70 |
71 | if (self) {
72 | [self commonInit];
73 | }
74 | return self;
75 | }
76 |
77 | - (void) commonInit {
78 | self.imageView = [[UIImageView alloc] init];
79 | self.borderView = [[UIView alloc] init];
80 | self.placeholderLabel = [[UILabel alloc] init];
81 |
82 | self.borderColor = [UIColor colorWithRed:1 green:1 blue:1 alpha:1];
83 | self.placeholderColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.4];
84 | self.cursorColor = self.borderColor;
85 | self.textColor = self.cursorColor;
86 |
87 | self.image = [UIImage imageNamed:@"pencil.png"];
88 |
89 | self.placeholderFontScale = 0.8;
90 | }
91 |
92 | #pragma mark - Overridden methods
93 | - (void)drawRect:(CGRect)rect {
94 | CGFloat length = self.placeholderLabel.font.lineHeight;
95 |
96 | self.borderView.frame = CGRectMake(CGRectGetWidth(rect), CGRectGetHeight(rect)-borderTickness, CGRectGetWidth(rect), borderTickness);
97 | [self addSubview:self.borderView];
98 |
99 | self.imageView.frame = CGRectMake(CGRectGetWidth(rect)-length, CGRectGetHeight(rect)-length-borderTickness, length, length);
100 | [self addSubview:self.imageView];
101 |
102 | self.placeholderLabel.frame = CGRectMake(placeholderInset.x, CGRectGetHeight(rect)-self.placeholderLabel.font.lineHeight-placeholderInset.y-borderTickness, CGRectGetWidth(rect)-length, self.placeholderLabel.font.lineHeight+placeholderInset.y);
103 | [self addSubview:self.placeholderLabel];
104 | }
105 |
106 | - (CGRect)editingRectForBounds:(CGRect)bounds {
107 | CGRect newBounds = CGRectMake(0, self.placeholderLabel.font.lineHeight+placeholderInset.y, CGRectGetWidth(bounds), CGRectGetHeight(bounds)-self.placeholderLabel.font.lineHeight-placeholderInset.y-borderTickness);
108 |
109 | return CGRectInset(newBounds, textFieldInset.x, textFieldInset.y);
110 | }
111 |
112 | - (CGRect)textRectForBounds:(CGRect)bounds {
113 | CGRect newBounds = CGRectMake(0, self.placeholderLabel.font.lineHeight+placeholderInset.y, CGRectGetWidth(bounds), CGRectGetHeight(bounds)-self.placeholderLabel.font.lineHeight-placeholderInset.y-borderTickness);
114 |
115 | return CGRectInset(newBounds, textFieldInset.x, textFieldInset.y);
116 | }
117 |
118 | - (void)animateViewsForTextEntry {
119 | if (self.text.length == 0) {
120 | self.imageView.layer.transform = CATransform3DMakeRotation(M_PI, 0, 1, 0);
121 |
122 | [UIView animateWithDuration:0.35 animations:^{
123 | self.placeholderLabel.layer.transform = CATransform3DMakeTranslation(0, -CGRectGetHeight([self textRectForBounds:self.bounds])-placeholderInset.y, 0);
124 |
125 | self.borderView.frame = CGRectOffset(self.borderView.frame, -CGRectGetWidth(self.bounds), 0);
126 | self.imageView.frame = CGRectOffset(self.imageView.frame, -CGRectGetWidth(self.bounds), 0);
127 | } completion:^(BOOL finished) {
128 | if (self.didBeginEditingHandler != nil) {
129 | self.didBeginEditingHandler();
130 | }
131 | }];
132 | }
133 | }
134 |
135 | - (void)animateViewsForTextDisplay {
136 | if (self.text.length == 0) {
137 | [UIView animateWithDuration:0.35 animations:^{
138 | self.borderView.frame = CGRectOffset(self.borderView.frame, CGRectGetWidth(self.bounds), 0);
139 |
140 | CGFloat length = self.placeholderLabel.font.lineHeight;
141 | self.imageView.frame = CGRectMake(CGRectGetWidth(self.bounds)-length, CGRectGetHeight(self.bounds)-length, length, length);
142 |
143 | self.placeholderLabel.layer.transform = CATransform3DIdentity;
144 | } completion:^(BOOL finished) {
145 | [UIView animateWithDuration:0.2 animations:^{
146 | self.imageView.layer.transform = CATransform3DIdentity;
147 | } completion:^(BOOL finished) {
148 | if (self.didEndEditingHandler != nil) {
149 | self.didEndEditingHandler();
150 | }
151 | }];
152 | }];
153 | }
154 | }
155 |
156 | #pragma mark - Private methods
157 | - (UIFont *)placeholderFontFromFont:(UIFont *)font {
158 | UIFont *smallerFont = [UIFont fontWithName:font.fontName size:font.pointSize*self.placeholderFontScale];
159 |
160 | return smallerFont;
161 | }
162 |
163 | @end
164 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/MinoruTextField.m:
--------------------------------------------------------------------------------
1 | //
2 | // MinoruTextField.m
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/28/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import "MinoruTextField.h"
10 | #import "PulsingHaloLayer.h"
11 |
12 | @interface MinoruTextField ()
13 |
14 | @property (strong, nonatomic) CALayer *borderLayer;
15 | @property (strong, nonatomic) UIColor *backgroundLayerColor;
16 | @property (strong, nonatomic) PulsingHaloLayer *halo;
17 |
18 | @end
19 |
20 | @implementation MinoruTextField
21 |
22 | #pragma mark - Constants
23 | static CGFloat const borderThickness = 2;
24 | static CGPoint const placeholderInsets = {6, 6};
25 | static CGPoint const textFieldInsets = {14, 6};
26 | static CGPoint const shadowInsets = {7, 8};
27 |
28 | #pragma mark - Custom accessorys
29 | - (void)setPlaceholderColor:(UIColor *)placeholderColor {
30 | _placeholderColor = placeholderColor;
31 |
32 | [self updatePlaceholder];
33 | }
34 |
35 | - (void)setBorderColor:(UIColor *)borderColor {
36 | _borderColor = borderColor;
37 |
38 | self.borderLayer.borderColor = borderColor.CGColor;
39 | self.halo.backgroundColor = borderColor.CGColor;
40 | }
41 |
42 | - (void)setBackgroundColor:(UIColor *)backgroundColor {
43 | self.backgroundLayerColor = backgroundColor;
44 | }
45 |
46 | - (UIColor *)backgroundColor {
47 | return self.backgroundLayerColor;
48 | }
49 |
50 | - (void)setPlaceholderFontScale:(CGFloat)placeholderFontScale {
51 | _placeholderFontScale = placeholderFontScale;
52 |
53 | [self updatePlaceholder];
54 | }
55 |
56 | - (void)setPlaceholder:(NSString *)placeholder {
57 | [super setPlaceholder:placeholder];
58 |
59 | [self updatePlaceholder];
60 | }
61 |
62 | - (void)setBounds:(CGRect)bounds {
63 | [super setBounds:bounds];
64 |
65 | [self updateBorder];
66 | [self updatePlaceholder];
67 | }
68 |
69 | #pragma mark - Lifecycle
70 | - (instancetype)initWithFrame:(CGRect)frame {
71 | self = [super initWithFrame:frame];
72 |
73 | if (self) {
74 | [self commonInit];
75 | }
76 |
77 | return self;
78 | }
79 |
80 | - (instancetype) initWithCoder:(NSCoder *)aDecoder {
81 | self = [super initWithCoder:aDecoder];
82 |
83 | if (self) {
84 | [self commonInit];
85 | }
86 | return self;
87 | }
88 |
89 | - (void) commonInit {
90 | self.borderLayer = [[CALayer alloc] init];
91 | self.placeholderLabel = [[UILabel alloc] init];
92 |
93 | self.placeholderColor = [UIColor colorWithRed:0.4157 green:0.4745 blue:0.5373 alpha:1];
94 | self.backgroundColor = [UIColor whiteColor];
95 | self.borderColor = [UIColor colorWithRed:0.9255 green:0.6353 blue:0.6078 alpha:1];
96 | self.cursorColor = [UIColor colorWithRed:0.9255 green:0.6353 blue:0.6078 alpha:1];
97 | self.textColor = self.cursorColor;
98 |
99 | self.halo = [PulsingHaloLayer layer];
100 | self.halo.repeatCount = 1;
101 | self.halo.animationDuration = 0.4;
102 | self.halo.radius = 0;
103 | self.halo.backgroundColor = self.borderColor.CGColor;
104 | [self.layer addSublayer:self.halo];
105 |
106 | self.placeholderFontScale = 0.65;
107 | }
108 |
109 | #pragma mark - Overridden methods
110 | - (void)drawRect:(CGRect)rect {
111 | CGRect frame = CGRectMake(0, 0, CGRectGetWidth(rect), CGRectGetHeight(rect));
112 |
113 | self.placeholderLabel.frame = CGRectInset(frame, placeholderInsets.x, placeholderInsets.y);
114 | self.placeholderLabel.font = [self placeholderFontFromFont:self.font];
115 |
116 | [self updateBorder];
117 | [self updatePlaceholder];
118 |
119 | [self.layer addSublayer:self.borderLayer];
120 | [self addSubview:self.placeholderLabel];
121 | }
122 |
123 | - (void) layoutSubviews {
124 | [super layoutSubviews];
125 |
126 | self.halo.radius = CGRectGetHeight(self.bounds);
127 | }
128 |
129 | - (CGRect)editingRectForBounds:(CGRect)bounds {
130 | CGRect newBounds = [self rectForBorderBounds:bounds];
131 |
132 | return CGRectInset(newBounds, textFieldInsets.x, 0);
133 | }
134 |
135 | - (CGRect)textRectForBounds:(CGRect)bounds {
136 | CGRect newBounds = [self rectForBorderBounds:bounds];
137 |
138 | return CGRectInset(newBounds, textFieldInsets.x, 0);
139 | }
140 |
141 | - (void)animateViewsForTextEntry {
142 | [UIView animateWithDuration:0.35 animations:^{
143 | self.borderLayer.borderWidth = borderThickness;
144 | self.borderLayer.borderColor = self.borderColor.CGColor;
145 |
146 | self.halo.frame = self.borderLayer.frame;
147 | [self.halo startAnimation];
148 | } completion:^(BOOL finished) {
149 | if (self.didBeginEditingHandler != nil) {
150 | self.didBeginEditingHandler();
151 | }
152 | }];
153 | }
154 |
155 | - (void)animateViewsForTextDisplay {
156 | [UIView animateWithDuration:0.35 animations:^{
157 | self.borderLayer.borderWidth = 0;
158 | } completion:^(BOOL finished) {
159 | if (self.didEndEditingHandler != nil) {
160 | self.didEndEditingHandler();
161 | }
162 | }];
163 | }
164 |
165 | #pragma mark - Private methods
166 | - (void)updateBorder {
167 | self.borderLayer.frame = [self rectForBorderBounds:self.frame];
168 | self.borderLayer.backgroundColor = self.backgroundColor.CGColor;
169 | }
170 |
171 | - (void)updatePlaceholder {
172 | self.placeholderLabel.text = self.placeholder;
173 | self.placeholderLabel.textColor = self.placeholderColor;
174 | [self.placeholderLabel sizeToFit];
175 | [self layoutPlaceholderInTextRect];
176 |
177 | if ([self isFirstResponder]) {
178 | [self animateViewsForTextEntry];
179 | }
180 | }
181 |
182 | - (UIFont *)placeholderFontFromFont:(UIFont *)font {
183 | return [UIFont fontWithName:font.fontName size:font.pointSize*self.placeholderFontScale];
184 | }
185 |
186 | - (CGRect)rectForBorderBounds:(CGRect)bounds {
187 | return CGRectMake(shadowInsets.x, shadowInsets.y, CGRectGetWidth(bounds)-shadowInsets.x*2, CGRectGetHeight(bounds)-self.font.lineHeight-placeholderInsets.y);
188 | }
189 |
190 | - (void)layoutPlaceholderInTextRect {
191 | self.placeholderLabel.frame = CGRectMake(placeholderInsets.x+shadowInsets.x, CGRectGetHeight(self.bounds)-CGRectGetHeight(self.placeholderLabel.frame), CGRectGetWidth(self.placeholderLabel.frame), CGRectGetHeight(self.placeholderLabel.frame));
192 | }
193 |
194 | @end
195 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/KyoTextField.m:
--------------------------------------------------------------------------------
1 | //
2 | // KyoTextField.m
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/28/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import "KyoTextField.h"
10 |
11 | @interface KyoTextField ()
12 |
13 | @property (strong, nonatomic) CALayer *borderLayer;
14 | @property (strong, nonatomic) UIColor *backgroundLayerColor;
15 | @property (strong, nonatomic) UIView *overlayView;
16 | @property (nonatomic) NSUInteger index;
17 |
18 | @end
19 |
20 | @implementation KyoTextField
21 |
22 | #pragma mark - Constants
23 | static CGPoint const placeholderInsets = {1, 3};
24 | static CGPoint const textFieldInsets = {1, 6};
25 |
26 | #pragma mark - Custom accessorys
27 | - (void)setPlaceholderColor:(UIColor *)placeholderColor {
28 | _placeholderColor = placeholderColor;
29 |
30 | [self updatePlaceholder];
31 | }
32 |
33 | - (void)setBackgroundColor:(UIColor *)backgroundColor {
34 | self.backgroundLayerColor = backgroundColor;
35 | }
36 |
37 | - (UIColor *)backgroundColor {
38 | return self.backgroundLayerColor;
39 | }
40 |
41 | - (void)setPlaceholderFontScale:(CGFloat)placeholderFontScale {
42 | _placeholderFontScale = placeholderFontScale;
43 |
44 | [self updatePlaceholder];
45 | }
46 |
47 | - (void)setPlaceholder:(NSString *)placeholder {
48 | [super setPlaceholder:placeholder];
49 |
50 | [self updatePlaceholder];
51 | }
52 |
53 | - (void)setBounds:(CGRect)bounds {
54 | [super setBounds:bounds];
55 |
56 | [self updateBorder];
57 | [self updatePlaceholder];
58 | }
59 |
60 | #pragma mark - Lifecycle
61 | - (instancetype)initWithFrame:(CGRect)frame {
62 | self = [super initWithFrame:frame];
63 |
64 | if (self) {
65 | [self commonInit];
66 | }
67 |
68 | return self;
69 | }
70 |
71 | - (instancetype) initWithCoder:(NSCoder *)aDecoder {
72 | self = [super initWithCoder:aDecoder];
73 |
74 | if (self) {
75 | [self commonInit];
76 | }
77 | return self;
78 | }
79 |
80 | - (void) commonInit {
81 | self.overlayView = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
82 | self.borderLayer = [[CALayer alloc] init];
83 | self.placeholderLabel = [[UILabel alloc] init];
84 |
85 | self.placeholderColor = [UIColor colorWithRed:0.4157 green:0.4745 blue:0.5373 alpha:1];
86 | self.overlayColor = [UIColor colorWithRed:0.2392 green:0.3451 blue:0.8235 alpha:0.6];
87 | self.backgroundColor = [UIColor whiteColor];
88 | self.cursorColor = [UIColor colorWithRed:0.3255 green:0.3647 blue:0.5725 alpha:1];
89 | self.textColor = self.cursorColor;
90 |
91 | self.placeholderFontScale = 0.85;
92 | }
93 |
94 | #pragma mark - Overridden methods
95 | - (void)drawRect:(CGRect)rect {
96 | CGRect frame = CGRectMake(0, 0, CGRectGetWidth(rect), CGRectGetHeight(rect));
97 |
98 | self.placeholderLabel.frame = CGRectInset(frame, placeholderInsets.x, placeholderInsets.y);
99 | self.placeholderLabel.font = [self placeholderFontFromFont:self.font];
100 |
101 | [self updateBorder];
102 | [self updatePlaceholder];
103 |
104 | [self.layer addSublayer:self.borderLayer];
105 | [self addSubview:self.placeholderLabel];
106 | }
107 |
108 | - (CGRect)editingRectForBounds:(CGRect)bounds {
109 | CGRect newBounds = [self rectForBorderBounds:bounds];
110 |
111 | return CGRectInset(newBounds, textFieldInsets.x+self.borderLayer.cornerRadius, 0);
112 | }
113 |
114 | - (CGRect)textRectForBounds:(CGRect)bounds {
115 | CGRect newBounds = [self rectForBorderBounds:bounds];
116 |
117 | return CGRectInset(newBounds, textFieldInsets.x+self.borderLayer.cornerRadius, 0);
118 | }
119 |
120 | - (void)animateViewsForTextEntry {
121 | if (self.superview != nil) {
122 | self.index = [self.superview.subviews indexOfObject:self];
123 | self.overlayView.backgroundColor = self.overlayColor;
124 | self.overlayView.alpha = 0;
125 |
126 | [UIView animateWithDuration:0.35 animations:^{
127 | self.overlayView.alpha = [self alphaForColor:self.overlayColor];
128 | [self.superview addSubview:self.overlayView];
129 | [self.superview bringSubviewToFront:self];
130 | self.placeholderLabel.textColor = self.backgroundColor;
131 | } completion:^(BOOL finished) {
132 | if (self.didBeginEditingHandler != nil) {
133 | self.didBeginEditingHandler();
134 | }
135 | }];
136 | }
137 | }
138 |
139 | - (void)animateViewsForTextDisplay {
140 | if (self.superview) {
141 | [UIView animateWithDuration:0.35 animations:^{
142 | self.overlayView.alpha = 0;
143 | self.placeholderLabel.textColor = self.placeholderColor;
144 | } completion:^(BOOL finished) {
145 | [self.overlayView removeFromSuperview];
146 | [self.superview insertSubview:self atIndex:self.index];
147 | if (self.didEndEditingHandler != nil) {
148 | self.didEndEditingHandler();
149 | }
150 | }];
151 | }
152 | }
153 |
154 | #pragma mark - Private methods
155 | - (void)updateBorder {
156 | self.borderLayer.frame = [self rectForBorderBounds:self.frame];
157 | self.borderLayer.cornerRadius = CGRectGetHeight(self.borderLayer.frame)/2;
158 | self.borderLayer.backgroundColor = self.backgroundColor.CGColor;
159 | }
160 |
161 | - (void)updatePlaceholder {
162 | self.placeholderLabel.text = self.placeholder;
163 | self.placeholderLabel.textColor = self.placeholderColor;
164 | [self.placeholderLabel sizeToFit];
165 | [self layoutPlaceholderInTextRect];
166 |
167 | if ([self isFirstResponder]) {
168 | [self animateViewsForTextEntry];
169 | }
170 | }
171 |
172 | - (UIFont *)placeholderFontFromFont:(UIFont *)font {
173 | return [UIFont fontWithName:font.fontName size:font.pointSize*self.placeholderFontScale];
174 | }
175 |
176 | - (CGRect)rectForBorderBounds:(CGRect)bounds {
177 | return CGRectMake(0, 0, CGRectGetWidth(bounds), CGRectGetHeight(bounds)-self.font.lineHeight-placeholderInsets.y);
178 | }
179 |
180 | - (void)layoutPlaceholderInTextRect {
181 | self.placeholderLabel.frame = CGRectMake(placeholderInsets.x+self.borderLayer.cornerRadius, CGRectGetHeight(self.bounds)-CGRectGetHeight(self.placeholderLabel.frame), CGRectGetWidth(self.placeholderLabel.frame), CGRectGetHeight(self.placeholderLabel.frame));
182 | }
183 |
184 | - (CGFloat)alphaForColor:(UIColor *)color {
185 | CGFloat alpha;
186 | CGFloat red;
187 | CGFloat green;
188 | CGFloat blue;
189 |
190 | if ([color getRed:&red green:&green blue:&blue alpha:&alpha]) {
191 | return alpha;
192 | } else {
193 | return 1;
194 | }
195 | }
196 |
197 | @end
198 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/JiroTextField.m:
--------------------------------------------------------------------------------
1 | //
2 | // JiroTextField.m
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/26/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import "JiroTextField.h"
10 |
11 | @interface JiroTextField ()
12 |
13 | @property (strong, nonatomic) CALayer *borderLayer;
14 |
15 | @end
16 |
17 | @implementation JiroTextField
18 |
19 | #pragma mark - Constant
20 | static CGFloat const borderThickness = 2;
21 | static CGPoint const textFieldInsets = {8, 12};
22 | static CGPoint const placeholderInsets = {8, 8};
23 |
24 | #pragma mark - Custom accessorys
25 | - (void)setBorderColor:(UIColor *)borderColor {
26 | _borderColor = borderColor;
27 |
28 | [self updateBorder];
29 | }
30 |
31 | - (void)setPlaceholderColor:(UIColor *)placeholderColor {
32 | _placeholderColor = placeholderColor;
33 |
34 | [self updatePlaceholder];
35 | }
36 |
37 | - (void)setPlaceholderFontScale:(CGFloat)placeholderFontScale {
38 | _placeholderFontScale = placeholderFontScale;
39 |
40 | [self updatePlaceholder];
41 | }
42 |
43 | - (void)setPlaceholder:(NSString *)placeholder {
44 | [super setPlaceholder:placeholder];
45 |
46 | [self updatePlaceholder];
47 | }
48 |
49 | - (void)setBounds:(CGRect)bounds {
50 | [super setBounds:bounds];
51 |
52 | [self updateBorder];
53 | [self updatePlaceholder];
54 | }
55 |
56 | #pragma mark - Lifecycle
57 | - (instancetype)initWithFrame:(CGRect)frame {
58 | self = [super initWithFrame:frame];
59 |
60 | if (self) {
61 | [self commonInit];
62 | }
63 |
64 | return self;
65 | }
66 |
67 | - (instancetype) initWithCoder:(NSCoder *)aDecoder {
68 | self = [super initWithCoder:aDecoder];
69 |
70 | if (self) {
71 | [self commonInit];
72 | }
73 | return self;
74 | }
75 |
76 | - (void) commonInit {
77 | self.borderLayer = [[CALayer alloc] init];
78 | self.placeholderLabel = [[UILabel alloc] init];
79 |
80 | self.borderColor = [UIColor colorWithRed:0.4157 green:0.4745 blue:0.5373 alpha:1.0];
81 | self.placeholderColor = self.borderColor;
82 | self.cursorColor = [UIColor colorWithRed:0.8275 green:0.8862 blue:0.8862 alpha:1.0];
83 | self.textColor = self.cursorColor;
84 |
85 | self.placeholderFontScale = 0.65;
86 | }
87 |
88 | #pragma mark - Overridden methods
89 | - (void)drawRect:(CGRect)rect {
90 | CGRect frame = CGRectMake(0, 0, CGRectGetWidth(rect), CGRectGetHeight(rect));
91 | self.placeholderLabel.frame = CGRectInset(frame, placeholderInsets.x, placeholderInsets.y);
92 | self.placeholderLabel.font = [self placeholderFontFromFont:self.font];
93 |
94 | [self updateBorder];
95 | [self updatePlaceholder];
96 |
97 | [self.layer addSublayer:self.borderLayer];
98 | [self addSubview:self.placeholderLabel];
99 | }
100 |
101 | - (CGRect)editingRectForBounds:(CGRect)bounds {
102 | return CGRectOffset(bounds, textFieldInsets.x, textFieldInsets.y);
103 | }
104 |
105 | - (CGRect)textRectForBounds:(CGRect)bounds {
106 | return CGRectOffset(bounds, textFieldInsets.x, textFieldInsets.y);
107 | }
108 |
109 | - (void)animateViewsForTextEntry {
110 | self.borderLayer.frame= CGRectMake(0, self.font.lineHeight, CGRectGetWidth(self.borderLayer.frame), CGRectGetHeight(self.borderLayer.frame));
111 |
112 | [UIView animateWithDuration:0.2 delay:0.3 usingSpringWithDamping:0.8 initialSpringVelocity:1 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
113 | self.placeholderLabel.frame = CGRectMake(placeholderInsets.x, self.borderLayer.frame.origin.y-self.placeholderLabel.bounds.size.height, CGRectGetWidth(self.placeholderLabel.frame), CGRectGetHeight(self.placeholderLabel.frame));
114 | self.borderLayer.frame = [self rectForBorderThickness:borderThickness isFilled:YES];
115 | } completion:^(BOOL finished) {
116 | if (self.didBeginEditingHandler != nil) {
117 | self.didBeginEditingHandler();
118 | }
119 | }];
120 | }
121 |
122 | - (void)animateViewsForTextDisplay {
123 | if (self.text.length == 0) {
124 | [UIView animateWithDuration:0.35 delay:0 usingSpringWithDamping:0.8 initialSpringVelocity:2.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
125 | [self layoutPlaceholderInTextRect];
126 | self.placeholderLabel.alpha = 1;
127 | } completion:^(BOOL finished) {
128 | if (self.didEndEditingHandler != nil) {
129 | self.didEndEditingHandler();
130 | }
131 | }];
132 |
133 | self.borderLayer.frame = [self rectForBorderThickness:borderThickness isFilled:NO];
134 | }
135 | }
136 |
137 | #pragma mark - Private methods
138 | - (void)updateBorder {
139 | self.borderLayer.frame = [self rectForBorderThickness:borderThickness isFilled:NO];
140 | self.borderLayer.backgroundColor = self.borderColor.CGColor;
141 | }
142 |
143 | - (void)updatePlaceholder {
144 | self.placeholderLabel.text = self.placeholder;
145 | self.placeholderLabel.textColor = self.placeholderColor;
146 | [self.placeholderLabel sizeToFit];
147 | [self layoutPlaceholderInTextRect];
148 |
149 | if ([self isFirstResponder] || self.text.length!=0) {
150 | [self animateViewsForTextEntry];
151 | }
152 | }
153 |
154 | - (UIFont *)placeholderFontFromFont:(UIFont *)font {
155 | UIFont *smallerFont = [UIFont fontWithName:self.font.fontName size:self.font.pointSize*self.placeholderFontScale];
156 |
157 | return smallerFont;
158 | }
159 |
160 | - (CGRect)rectForBorderThickness:(CGFloat)thickness isFilled:(BOOL)isFilled {
161 | if (isFilled) {
162 | return CGRectMake(0, self.placeholderLabel.frame.origin.y+self.placeholderLabel.font.lineHeight, CGRectGetWidth(self.frame), CGRectGetHeight(self.frame));
163 | } else {
164 | return CGRectMake(0, CGRectGetHeight(self.frame)-thickness, CGRectGetWidth(self.frame), thickness);
165 | }
166 | }
167 |
168 | - (void)layoutPlaceholderInTextRect {
169 | if (self.text.length != 0) {
170 | return;
171 | }
172 |
173 | CGRect textRect = [self textRectForBounds:self.bounds];
174 | CGFloat originX = textRect.origin.x;
175 |
176 | switch (self.textAlignment) {
177 | case NSTextAlignmentCenter:
178 | originX += textRect.size.width/2-self.placeholderLabel.bounds.size.width/2;
179 | break;
180 | case NSTextAlignmentRight:
181 | originX += textRect.size.width-self.placeholderLabel.bounds.size.width;
182 | break;
183 | default:
184 | break;
185 | }
186 |
187 | self.placeholderLabel.frame = CGRectMake(originX, textRect.size.height/2, CGRectGetWidth(self.placeholderLabel.frame), CGRectGetHeight(self.placeholderLabel.frame));
188 | }
189 |
190 | @end
191 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/IsaoTextField.m:
--------------------------------------------------------------------------------
1 | //
2 | // IsaoTextField.m
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/25/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import "IsaoTextField.h"
10 |
11 | @interface IsaoTextField ()
12 |
13 | @property (strong, nonatomic) CALayer *borderLayer;
14 |
15 | @end
16 |
17 | @implementation IsaoTextField
18 |
19 | #pragma mark - Constants
20 | static CGFloat const activeBorderThickness = 4;
21 | static CGFloat const inactiveBorderThickness = 2;
22 | static CGPoint const textFieldInsets = {6, 6};
23 | static CGPoint const placeholderInsets = {6, 6};
24 |
25 | #pragma mark - Custom accessorys
26 | - (void)setInactiveColor:(UIColor *)inactiveColor {
27 | _inactiveColor = inactiveColor;
28 |
29 | [self updateBorder];
30 | }
31 |
32 | - (void)setActiveColor:(UIColor *)activeColor {
33 | _activeColor = activeColor;
34 |
35 | [self updateBorder];
36 | }
37 |
38 | - (void)setPlaceholderFontScale:(CGFloat)placeholderFontScale {
39 | _placeholderFontScale = placeholderFontScale;
40 |
41 | [self updatePlaceholder];
42 | }
43 |
44 | - (void)setPlaceholder:(NSString *)placeholder {
45 | [super setPlaceholder:placeholder];
46 |
47 | [self updatePlaceholder];
48 | }
49 |
50 | - (void)setBounds:(CGRect)bounds {
51 | [super setBounds:bounds];
52 |
53 | [self updateBorder];
54 | [self updatePlaceholder];
55 | }
56 |
57 | #pragma mark - Lifecycle
58 | - (instancetype)initWithFrame:(CGRect)frame {
59 | self = [super initWithFrame:frame];
60 |
61 | if (self) {
62 | [self commonInit];
63 | }
64 |
65 | return self;
66 | }
67 |
68 | - (instancetype) initWithCoder:(NSCoder *)aDecoder {
69 | self = [super initWithCoder:aDecoder];
70 |
71 | if (self) {
72 | [self commonInit];
73 | }
74 | return self;
75 | }
76 |
77 | - (void) commonInit {
78 | self.borderLayer = [[CALayer alloc] init];
79 | self.placeholderLabel = [[UILabel alloc] init];
80 |
81 | self.inactiveColor = [UIColor colorWithRed:0.8549 green:0.8549 blue:0.8549 alpha:1.0];
82 | self.activeColor = [UIColor colorWithRed:0.8549 green:0.4392 blue:0.4431 alpha:1.0];
83 | self.placeholderLabel.textColor = self.inactiveColor;
84 | self.cursorColor = [UIColor colorWithRed:0.6863 green:0.702 blue:0.7216 alpha:1.0];
85 | self.textColor = [UIColor colorWithRed:0.6863 green:0.702 blue:0.7216 alpha:1.0];
86 |
87 | self.placeholderFontScale = 0.7;
88 | }
89 |
90 | #pragma mark - Overridden methods
91 | - (void)drawRect:(CGRect)rect {
92 | CGRect frame = CGRectMake(0, 0, rect.size.width, rect.size.height);
93 | self.placeholderLabel.frame = CGRectInset(frame, placeholderInsets.x, placeholderInsets.y);
94 | self.placeholderLabel.font = [self placeholderFontFromFont:self.font];
95 |
96 | [self updateBorder];
97 | [self updatePlaceholder];
98 |
99 | [self.layer addSublayer:self.borderLayer];
100 | [self addSubview:self.placeholderLabel];
101 | }
102 |
103 | - (CGRect)editingRectForBounds:(CGRect)bounds {
104 | CGRect newBounds = CGRectMake(0, 0, bounds.size.width, bounds.size.height-self.font.lineHeight+textFieldInsets.y);
105 |
106 | return CGRectInset(newBounds, textFieldInsets.x, 0);
107 | }
108 |
109 | - (CGRect)textRectForBounds:(CGRect)bounds {
110 | CGRect newBounds = CGRectMake(0, 0, bounds.size.width, bounds.size.height-self.font.lineHeight+textFieldInsets.y);
111 |
112 | return CGRectInset(newBounds, textFieldInsets.x, 0);
113 | }
114 |
115 | - (void)animateViewsForTextEntry {
116 | [self updateBorder];
117 | [self performPlacerholderAnimation];
118 |
119 | self.placeholderLabel.textColor = self.activeColor;
120 | }
121 |
122 | - (void)animateViewsForTextDisplay {
123 | [self updateBorder];
124 |
125 | [self performPlacerholderAnimation];
126 |
127 | self.placeholderLabel.textColor = self.inactiveColor;
128 | }
129 |
130 | #pragma mark - Private methods
131 | - (void)updateBorder {
132 | self.borderLayer.frame = [self rectForBorderBounds:self.frame];
133 | self.borderLayer.backgroundColor = [self isFirstResponder]?self.activeColor.CGColor:self.inactiveColor.CGColor;
134 | }
135 |
136 | - (void)updatePlaceholder {
137 | self.placeholderLabel.text = self.placeholder;
138 | [self.placeholderLabel sizeToFit];
139 |
140 | [self layoutPlaceholderInTextRect];
141 |
142 | if ([self isFirstResponder]) {
143 | [self animateViewsForTextEntry];
144 | }
145 | }
146 |
147 | - (UIFont *)placeholderFontFromFont:(UIFont *)font {
148 | UIFont *smallerFont = [UIFont fontWithName:self.font.fontName size:self.font.pointSize*self.placeholderFontScale];
149 |
150 | return smallerFont;
151 | }
152 |
153 | - (CGRect)rectForBorderBounds:(CGRect)bounds {
154 | CGRect newRect;
155 |
156 | if ([self isFirstResponder]) {
157 | newRect = CGRectMake(0, bounds.size.height-self.font.lineHeight+textFieldInsets.y-activeBorderThickness, bounds.size.width, activeBorderThickness);
158 | } else {
159 | newRect = CGRectMake(0, bounds.size.height-self.font.lineHeight+textFieldInsets.y-inactiveBorderThickness, bounds.size.width, inactiveBorderThickness);
160 | }
161 |
162 | return newRect;
163 | }
164 |
165 | - (void)layoutPlaceholderInTextRect {
166 | CGRect textRect = [self textRectForBounds:self.bounds];
167 | CGFloat originX = textRect.origin.x;
168 |
169 | switch (self.textAlignment) {
170 | case NSTextAlignmentCenter:
171 | originX += textRect.size.width/2-self.placeholderLabel.bounds.size.width/2;
172 | break;
173 | case NSTextAlignmentRight:
174 | originX += textRect.size.width-self.placeholderLabel.bounds.size.width;
175 | break;
176 | default:
177 | break;
178 | }
179 |
180 | self.placeholderLabel.frame = CGRectMake(originX, self.bounds.size.height-self.placeholderLabel.frame.size.height, self.placeholderLabel.frame.size.width, self.placeholderLabel.frame.size.height);
181 | }
182 |
183 | - (void)performPlacerholderAnimation {
184 | CGFloat yOffset = 4;
185 |
186 | [UIView animateWithDuration:0.15 animations:^{
187 | self.placeholderLabel.transform = CGAffineTransformMakeTranslation(0, -yOffset);
188 | self.placeholderLabel.alpha = 0;
189 | } completion:^(BOOL finished){
190 | self.placeholderLabel.transform = CGAffineTransformIdentity;
191 | self.placeholderLabel.transform = CGAffineTransformMakeTranslation(0, yOffset);
192 |
193 | [UIView animateWithDuration:0.15 animations:^{
194 | self.placeholderLabel.transform = CGAffineTransformIdentity;
195 | self.placeholderLabel.alpha = 1;
196 | } completion:^(BOOL finished) {
197 | if ([self isFirstResponder] && self.didBeginEditingHandler!= nil) {
198 | self.didBeginEditingHandler();
199 | } else if (![self isFirstResponder] && self.didEndEditingHandler != nil) {
200 | self.didEndEditingHandler();
201 | }
202 | }];
203 | }];
204 | }
205 |
206 | @end
207 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/NarikoTextField.m:
--------------------------------------------------------------------------------
1 | //
2 | // NarikoTextField.m
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/30/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import "NarikoTextField.h"
10 |
11 | @interface NarikoTextField ()
12 |
13 | @property (strong, nonatomic) CALayer *borderLayer;
14 | @property (strong, nonatomic) CALayer *backgroundLayer;
15 | @property (strong, nonatomic) UIColor *backgroundLayerColor;
16 |
17 | @end
18 |
19 | @implementation NarikoTextField
20 |
21 | #pragma mark - Constants
22 | static CGFloat const borderThickness = 2.5;
23 | static CGPoint const textFieldInsets = {10, 6};
24 | static CGPoint const placeholderInsets = {6, 6};
25 |
26 | #pragma mark - Custom accessory
27 | - (void)setPlaceholderColor:(UIColor *)placeholderColor {
28 | _placeholderColor = placeholderColor;
29 |
30 | [self updatePlaceholder];
31 | }
32 |
33 | - (void)setBorderColor:(UIColor *)borderColor {
34 | _borderColor = borderColor;
35 |
36 | [self updateBorder];
37 | }
38 |
39 | - (void)setBackgroundColor:(UIColor *)backgroundColor {
40 | self.backgroundLayerColor = backgroundColor;
41 |
42 | self.backgroundLayer.backgroundColor = backgroundColor.CGColor;
43 | }
44 |
45 | - (UIColor *)backgroundColor {
46 | return self.backgroundLayerColor;
47 | }
48 |
49 | - (void)setPlaceholderFontScale:(CGFloat)placeholderFontScale {
50 | _placeholderFontScale = placeholderFontScale;
51 |
52 | [self updatePlaceholder];
53 | }
54 |
55 | - (void)setPlaceholder:(NSString *)placeholder {
56 | [super setPlaceholder:placeholder];
57 |
58 | [self updatePlaceholder];
59 | }
60 |
61 | - (void)setBounds:(CGRect)bounds {
62 | [super setBounds:bounds];
63 |
64 | [self updateBorder];
65 | [self updatePlaceholder];
66 | }
67 |
68 | #pragma mark - Lifecycle
69 | - (instancetype)initWithFrame:(CGRect)frame {
70 | self = [super initWithFrame:frame];
71 |
72 | if (self) {
73 | [self commonInit];
74 | }
75 |
76 | return self;
77 | }
78 |
79 | - (instancetype) initWithCoder:(NSCoder *)aDecoder {
80 | self = [super initWithCoder:aDecoder];
81 |
82 | if (self) {
83 | [self commonInit];
84 | }
85 | return self;
86 | }
87 |
88 | - (void) commonInit {
89 | self.borderLayer = [[CALayer alloc] init];
90 | self.backgroundLayer = [[CALayer alloc] init];
91 | self.placeholderLabel = [[UILabel alloc] init];
92 |
93 | self.placeholderColor = [UIColor colorWithRed:0.4118 green:0.4118 blue:0.4118 alpha:1.0];
94 | self.borderColor = [UIColor colorWithRed:0.6078 green:0.6235 blue:0.6235 alpha:1];
95 | self.backgroundColor = [UIColor whiteColor];
96 | self.cursorColor = [UIColor colorWithRed:0.9451 green:0.5098 blue:0.5725 alpha:1];
97 | self.textColor = self.cursorColor;
98 |
99 | self.placeholderFontScale = 0.85;
100 | }
101 |
102 | #pragma mark - Overridden methods
103 | - (void)drawRect:(CGRect)rect {
104 | self.placeholderLabel.frame = CGRectMake(placeholderInsets.x, CGRectGetHeight(rect)-placeholderInsets.y-self.placeholderLabel.font.lineHeight, CGRectGetWidth(rect), placeholderInsets.y+self.placeholderLabel.font.lineHeight);
105 | self.placeholderLabel.font = [self placeholderFontFromFont:self.font];
106 |
107 | [self updateBorder];
108 | [self updatePlaceholder];
109 |
110 | [self.layer addSublayer:self.borderLayer];
111 |
112 | self.backgroundLayer.frame = CGRectMake(0,CGRectGetHeight(self.bounds) , CGRectGetWidth(self.bounds), 0);
113 | [self.layer addSublayer:self.backgroundLayer];
114 |
115 | [self addSubview:self.placeholderLabel];
116 | }
117 |
118 | - (CGRect)editingRectForBounds:(CGRect)bounds {
119 | CGRect rect = [self textRectForBounds:bounds];
120 |
121 | /**
122 | Basically the return value should euqal to the return value of [self textRectForBounds:bounds] (aka. rect)
123 | But when you run the code, the editing rect is a little upper than text rect, though their origin.y are euqal.
124 | I have not figured out the reason, so I make 0.5 offset as a expedient.
125 | */
126 | return CGRectOffset(rect, 0, 0.5);
127 | }
128 |
129 | - (CGRect)textRectForBounds:(CGRect)bounds {
130 | return CGRectInset([self rectForBorderBounds:bounds], textFieldInsets.x, 0);
131 | }
132 |
133 | - (void)animateViewsForTextEntry {
134 | if (self.text.length == 0) {
135 | [UIView animateWithDuration:0.3 animations:^{
136 | CGRect backgroundRect = [self editingRectForBounds:self.bounds];
137 | self.backgroundLayer.frame = CGRectMake(0, CGRectGetHeight(self.bounds)-CGRectGetHeight(backgroundRect), CGRectGetWidth(self.bounds), CGRectGetHeight(backgroundRect));
138 | self.borderLayer.frame = CGRectOffset(self.borderLayer.frame, 0, -CGRectGetHeight(self.backgroundLayer.frame));
139 |
140 | CGAffineTransform translate = CGAffineTransformMakeTranslation(0, -CGRectGetHeight(self.backgroundLayer.frame)-placeholderInsets.y);
141 | CGAffineTransform scale = CGAffineTransformMakeScale(0.9, 0.9);
142 | self.placeholderLabel.transform = CGAffineTransformConcat(translate, scale);
143 | } completion:^(BOOL finished) {
144 | if (self.didBeginEditingHandler != nil) {
145 | self.didBeginEditingHandler();
146 | }
147 | }];
148 | }
149 | }
150 |
151 | - (void)animateViewsForTextDisplay {
152 | if (self.text.length == 0) {
153 | [UIView animateWithDuration:0.3 animations:^{
154 | self.placeholderLabel.transform = CGAffineTransformIdentity;
155 |
156 | self.backgroundLayer.frame = CGRectMake(0,CGRectGetHeight(self.bounds) , CGRectGetWidth(self.bounds), 0);
157 | self.borderLayer.frame = CGRectMake(0, CGRectGetHeight(self.bounds)-borderThickness, CGRectGetWidth(self.bounds), borderThickness);
158 | } completion:^(BOOL finished) {
159 | if (self.didEndEditingHandler != nil) {
160 | self.didEndEditingHandler();
161 | }
162 | }];
163 | }
164 | }
165 |
166 | #pragma mark - Private methods
167 | - (void)updateBorder {
168 | CGRect rect = [self rectForBorderBounds:self.bounds];
169 | self.borderLayer.frame = CGRectMake(0, CGRectGetHeight(self.bounds)-borderThickness, CGRectGetWidth(rect), borderThickness);
170 | self.borderLayer.borderWidth = borderThickness;
171 | self.borderLayer.borderColor = self.borderColor.CGColor;
172 | }
173 |
174 | - (void)updatePlaceholder {
175 | self.placeholderLabel.text = self.placeholder;
176 | self.placeholderLabel.textColor = self.placeholderColor;
177 | [self.placeholderLabel sizeToFit];
178 |
179 | if ([self isFirstResponder] || self.text.length!=0) {
180 | [self animateViewsForTextEntry];
181 | }
182 | }
183 |
184 | - (UIFont *)placeholderFontFromFont:(UIFont *)font {
185 | UIFont *smallerFont = [UIFont fontWithName:font.fontName size:font.pointSize*self.placeholderFontScale];
186 |
187 | return smallerFont;
188 | }
189 |
190 | - (CGRect)rectForBorderBounds:(CGRect)bounds {
191 | return CGRectMake(0, self.font.lineHeight+textFieldInsets.y, CGRectGetWidth(bounds), CGRectGetHeight(bounds)-self.font.lineHeight-textFieldInsets.y);
192 | }
193 |
194 | @end
195 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/YoshikoTextField.m:
--------------------------------------------------------------------------------
1 | //
2 | // YoshikoTextField.m
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/26/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import "YoshikoTextField.h"
10 |
11 | @interface YoshikoTextField ()
12 |
13 | @property (strong, nonatomic) CALayer *borderLayer;
14 | @property (nonatomic) CGFloat placeholderHeight;
15 |
16 | @end
17 |
18 | @implementation YoshikoTextField
19 |
20 | #pragma mark - Constants
21 | static CGFloat const borderSize = 2;
22 | static CGPoint const textFieldInsets = {6, 0};
23 | static CGPoint const placeholderInsets = {6, 0};
24 |
25 | #pragma mark - Custom accessorys
26 | - (void)setActiveBorderColor:(UIColor *)activeBorderColor {
27 | _activeBorderColor = activeBorderColor;
28 | [self updateBorder];
29 | [self updateBackground];
30 | [self updatePlaceholder];
31 | }
32 |
33 | - (void)setInactiveBorderColor:(UIColor *)inactiveBorderColor {
34 | _inactiveBorderColor = inactiveBorderColor;
35 |
36 | [self updateBorder];
37 | [self updateBackground];
38 | [self updatePlaceholder];
39 | }
40 |
41 | - (void)setActiveBackgroundColor:(UIColor *)activeBackgroundColor {
42 | _activeBackgroundColor = activeBackgroundColor;
43 |
44 | [self updateBackground];
45 | }
46 |
47 | - (void)setPlaceholderColor:(UIColor *)placeholderColor {
48 | _placeholderColor = placeholderColor;
49 | [self updatePlaceholder];
50 | }
51 |
52 | - (void)setPlaceholderFontScale:(CGFloat)placeholderFontScale {
53 | _placeholderFontScale = placeholderFontScale;
54 |
55 | [self updatePlaceholder];
56 | }
57 |
58 | - (void)setPlaceholder:(NSString *)placeholder {
59 | [super setPlaceholder:placeholder];
60 |
61 | [self updatePlaceholder];
62 | }
63 |
64 | - (void)setBounds:(CGRect)bounds {
65 | [super setBounds:bounds];
66 |
67 | [self updateBorder];
68 | [self updateBackground];
69 | [self updatePlaceholder];
70 | }
71 |
72 | - (CGFloat)placeholderHeight {
73 | return placeholderInsets.y + [self placeholderFontFromFont:self.font percentageOfOriginalSize:self.placeholderFontScale].lineHeight;
74 | }
75 |
76 | #pragma mark - Lifecycle
77 | - (instancetype)initWithFrame:(CGRect)frame {
78 | self = [super initWithFrame:frame];
79 |
80 | if (self) {
81 | [self commonInit];
82 | }
83 |
84 | return self;
85 | }
86 |
87 | - (instancetype) initWithCoder:(NSCoder *)aDecoder {
88 | self = [super initWithCoder:aDecoder];
89 |
90 | if (self) {
91 | [self commonInit];
92 | }
93 | return self;
94 | }
95 |
96 | - (void) commonInit {
97 | self.borderLayer = [[CALayer alloc] init];
98 | self.placeholderLabel = [[UILabel alloc] init];
99 |
100 | self.placeholderColor = [UIColor colorWithRed:0.5451 green:0.5490 blue:0.5490 alpha:1];
101 | self.inactiveBorderColor = [UIColor colorWithRed:0.8157 green:0.8196 blue:0.8157 alpha:1];
102 | self.activeBorderColor = [UIColor colorWithRed:0.6392 green:0.8275 blue:0.6118 alpha:1];
103 | self.activeBackgroundColor = [UIColor colorWithRed:0.9765 green:0.9686 blue:0.9647 alpha:1];
104 | self.cursorColor = [UIColor colorWithRed:0.6666 green:0.6666 blue:0.6666 alpha:1];
105 | self.textColor = self.cursorColor;
106 |
107 | self.placeholderFontScale = 0.7;
108 | }
109 |
110 | #pragma mark - Overridden methods
111 | - (void)drawRect:(CGRect)rect {
112 | [self updateBorder];
113 | [self updateBackground];
114 | [self updatePlaceholder];
115 |
116 | [self.layer addSublayer:self.borderLayer];
117 | [self addSubview:self.placeholderLabel];
118 | }
119 |
120 | - (CGRect)placeholderRectForBounds:(CGRect)bounds {
121 | if ([self isFirstResponder] || self.text.length!=0) {
122 | return CGRectMake(placeholderInsets.x, placeholderInsets.y, CGRectGetWidth(bounds), self.placeholderHeight);
123 | } else {
124 | return [self textRectForBounds:self.bounds];
125 | }
126 | }
127 |
128 | - (CGRect)editingRectForBounds:(CGRect)bounds {
129 | return [self textRectForBounds:bounds];
130 | }
131 |
132 | - (CGRect)textRectForBounds:(CGRect)bounds {
133 | return CGRectOffset(bounds, textFieldInsets.x, textFieldInsets.y+self.placeholderHeight/2);
134 | }
135 |
136 | - (void)prepareForInterfaceBuilder {
137 | self.placeholderLabel.alpha = 1;
138 | }
139 |
140 | - (void)animateViewsForTextEntry {
141 | [self animateViews];
142 | }
143 |
144 | - (void)animateViewsForTextDisplay {
145 | [self animateViews];
146 | }
147 |
148 | #pragma mark - Private methods
149 | - (void)animateViews {
150 | [UIView animateWithDuration:0.2 animations:^{
151 | // Prevents a "flash" in the placeholder
152 | if (self.text.length == 0) {
153 | self.placeholderLabel.alpha = 0;
154 | }
155 |
156 | self.placeholderLabel.frame = [self placeholderRectForBounds:self.bounds];
157 | } completion:^(BOOL finished) {
158 | [self updatePlaceholder];
159 |
160 | [UIView animateWithDuration:0.3 animations:^{
161 | self.placeholderLabel.alpha = 1;
162 | [self updateBorder];
163 | [self updateBackground];
164 | } completion:^(BOOL finished) {
165 | if ([self isFirstResponder] && self.didBeginEditingHandler != nil) {
166 | self.didBeginEditingHandler();
167 | } else if (![self isFirstResponder] && self.didEndEditingHandler != nil) {
168 | self.didEndEditingHandler();
169 | }
170 | }];
171 | }];
172 | }
173 |
174 | - (void)updateBorder {
175 | self.borderLayer.frame = [self rectForBounds:self.bounds];
176 | self.borderLayer.borderWidth = borderSize;
177 | self.borderLayer.borderColor = [self isFirstResponder] || self.text.length!=0?self.activeBorderColor.CGColor:self.inactiveBorderColor.CGColor;
178 | }
179 |
180 | - (void)updateBackground {
181 | if ([self isFirstResponder] || self.text.length!=0) {
182 | self.borderLayer.backgroundColor = self.activeBackgroundColor.CGColor;
183 | } else {
184 | self.borderLayer.backgroundColor = self.inactiveBorderColor.CGColor;
185 | }
186 | }
187 |
188 | - (void)updatePlaceholder {
189 | self.placeholderLabel.frame = [self placeholderRectForBounds:self.bounds];
190 | self.placeholderLabel.text = self.placeholder;
191 | self.placeholderLabel.textAlignment = self.textAlignment;
192 |
193 | if ([self isFirstResponder] || self.text.length!=0) {
194 | self.placeholderLabel.font = [self placeholderFontFromFont:self.font percentageOfOriginalSize:self.placeholderFontScale*0.8];
195 | self.placeholderLabel.text = self.placeholder.uppercaseString;
196 | self.placeholderLabel.textColor = self.activeBorderColor;
197 | } else {
198 | self.placeholderLabel.font = [self placeholderFontFromFont:self.font percentageOfOriginalSize:self.placeholderFontScale];
199 | self.placeholderLabel.textColor = self.placeholderColor;
200 | }
201 | }
202 |
203 | - (UIFont *)placeholderFontFromFont:(UIFont *)font percentageOfOriginalSize:(CGFloat)presentage {
204 | UIFont *smallerFont = [UIFont fontWithName:font.fontName size:font.pointSize*presentage];
205 |
206 | return smallerFont;
207 | }
208 |
209 | - (CGRect)rectForBounds:(CGRect)bounds {
210 | return CGRectMake(bounds.origin.x, bounds.origin.y+self.placeholderHeight, CGRectGetWidth(bounds), CGRectGetHeight(bounds)-self.placeholderHeight);
211 | }
212 |
213 | @end
214 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/MadokaTextField.m:
--------------------------------------------------------------------------------
1 | //
2 | // MadokaTextField.m
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/26/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import "MadokaTextField.h"
10 |
11 | @interface MadokaTextField ()
12 |
13 | @property (strong, nonatomic) CAShapeLayer *borderLayer;
14 |
15 | @end
16 |
17 | @implementation MadokaTextField
18 |
19 | #pragma mark - Constants
20 | static CGFloat const borderThickness = 1;
21 | static CGPoint const textFieldInsets = {6, 6};
22 | static CGPoint const placeholderInsets = {6, 6};
23 |
24 | #pragma mark - Custom accessory
25 | - (void)setPlaceholderColor:(UIColor *)placeholderColor {
26 | _placeholderColor = placeholderColor;
27 |
28 | [self updatePlaceholder];
29 | }
30 |
31 | - (void)setBorderColor:(UIColor *)borderColor {
32 | _borderColor = borderColor;
33 |
34 | [self updateBorder];
35 | }
36 |
37 | - (void)setPlaceholderFontScale:(CGFloat)placeholderFontScale {
38 | _placeholderFontScale = placeholderFontScale;
39 |
40 | [self updatePlaceholder];
41 | }
42 |
43 | - (void)setPlaceholder:(NSString *)placeholder {
44 | [super setPlaceholder:placeholder];
45 |
46 | [self updatePlaceholder];
47 | }
48 |
49 | - (void)setBounds:(CGRect)bounds {
50 | [super setBounds:bounds];
51 |
52 | [self updateBorder];
53 | [self updatePlaceholder];
54 | }
55 |
56 | #pragma mark - Lifecycle
57 | - (instancetype)initWithFrame:(CGRect)frame {
58 | self = [super initWithFrame:frame];
59 |
60 | if (self) {
61 | [self commonInit];
62 | }
63 |
64 | return self;
65 | }
66 |
67 | - (instancetype) initWithCoder:(NSCoder *)aDecoder {
68 | self = [super initWithCoder:aDecoder];
69 |
70 | if (self) {
71 | [self commonInit];
72 | }
73 | return self;
74 | }
75 |
76 | - (void) commonInit {
77 | self.borderLayer = [[CAShapeLayer alloc] init];
78 | self.borderLayer.fillColor = [UIColor clearColor].CGColor;
79 |
80 | self.placeholderLabel = [[UILabel alloc] init];
81 |
82 | self.placeholderColor = [UIColor colorWithRed:0.4039 green:0.3922 blue:0.4863 alpha:1.0];
83 | self.borderColor = self.placeholderColor;
84 | self.borderLayer.strokeColor = self.borderColor.CGColor;
85 | self.cursorColor = self.placeholderColor;
86 | self.textColor = self.placeholderColor;
87 |
88 | self.placeholderFontScale = 0.75;
89 | }
90 |
91 | #pragma mark - Overridden methods
92 | - (void)drawRect:(CGRect)rect {
93 | CGRect frame = CGRectMake(0, 0, CGRectGetWidth(rect), CGRectGetHeight(rect));
94 |
95 | self.placeholderLabel.frame = CGRectInset(frame, placeholderInsets.x, placeholderInsets.y);
96 | self.placeholderLabel.font = [self placeholderFontFromFont:self.font];
97 |
98 | [self updateBorder];
99 | [self updatePlaceholder];
100 |
101 | [self.layer addSublayer:self.borderLayer];
102 | [self addSubview:self.placeholderLabel];
103 | }
104 |
105 | - (CGRect)editingRectForBounds:(CGRect)bounds {
106 | return CGRectInset([self rectForBorderBounds:bounds], textFieldInsets.x, 0);
107 | }
108 |
109 | - (CGRect)textRectForBounds:(CGRect)bounds {
110 | return CGRectInset([self rectForBorderBounds:bounds], textFieldInsets.x, 0);
111 | }
112 |
113 | - (void)animateViewsForTextEntry {
114 | self.borderLayer.strokeEnd = 1;
115 |
116 | [UIView animateWithDuration:0.3 animations:^{
117 | CGAffineTransform translate = CGAffineTransformMakeTranslation(-placeholderInsets.x, self.placeholderLabel.bounds.size.height + (placeholderInsets.y*2));
118 | CGAffineTransform scale = CGAffineTransformMakeScale(0.9, 0.9);
119 |
120 | self.placeholderLabel.transform = CGAffineTransformConcat(translate, scale);
121 | } completion:^(BOOL finished) {
122 | if (self.didBeginEditingHandler != nil) {
123 | self.didBeginEditingHandler();
124 | }
125 | }];
126 | }
127 |
128 | - (void)animateViewsForTextDisplay {
129 | if (self.text.length == 0) {
130 | self.borderLayer.strokeEnd = [self percentageForBottomBorder];
131 |
132 | [UIView animateWithDuration:0.3 animations:^{
133 | self.placeholderLabel.transform = CGAffineTransformIdentity;
134 | } completion:^(BOOL finished) {
135 | if (self.didEndEditingHandler != nil) {
136 | self.didEndEditingHandler();
137 | }
138 | }];
139 | }
140 | }
141 |
142 | #pragma mark - Private methods
143 | - (void)updateBorder {
144 | CGRect rect = [self rectForBorderBounds:self.bounds];
145 |
146 | UIBezierPath *path = [UIBezierPath bezierPath];
147 | [path moveToPoint:CGPointMake(rect.origin.x+borderThickness, rect.size.height-borderThickness)];
148 | [path addLineToPoint:CGPointMake(rect.size.width-borderThickness, rect.size.height-borderThickness)];
149 | [path addLineToPoint:CGPointMake(rect.size.width-borderThickness, rect.origin.y+borderThickness)];
150 | [path addLineToPoint:CGPointMake(rect.origin.x+borderThickness, rect.origin.y+borderThickness)];
151 | [path closePath];
152 |
153 | self.borderLayer.path = path.CGPath;
154 | self.borderLayer.lineCap = kCALineCapSquare;
155 | self.borderLayer.lineWidth = borderThickness;
156 | self.borderLayer.fillColor = [UIColor clearColor].CGColor;
157 | self.borderLayer.strokeColor = self.borderColor.CGColor;
158 | self.borderLayer.strokeEnd = [self percentageForBottomBorder];
159 | }
160 |
161 | - (CGFloat)percentageForBottomBorder {
162 | CGRect borderRect = [self rectForBorderBounds:self.bounds];
163 | CGFloat sumOfSides = (borderRect.size.width*2) + (borderRect.size.height*2);
164 | return (borderRect.size.width*100 / sumOfSides) / 100;
165 | }
166 |
167 | - (void)updatePlaceholder {
168 | self.placeholderLabel.text = self.placeholder;
169 | self.placeholderLabel.textColor = self.placeholderColor;
170 | [self.placeholderLabel sizeToFit];
171 | [self layoutPlaceholderInTextRect];
172 |
173 | if ([self isFirstResponder] || self.text.length!=0) {
174 | [self animateViewsForTextEntry];
175 | }
176 | }
177 |
178 | - (UIFont *)placeholderFontFromFont:(UIFont *)font {
179 | UIFont *smallerFont = [UIFont fontWithName:font.fontName size:font.pointSize*self.placeholderFontScale];
180 |
181 | return smallerFont;
182 | }
183 |
184 | - (CGRect)rectForBorderBounds:(CGRect)bounds {
185 | return CGRectMake(0, 0, CGRectGetWidth(bounds), CGRectGetHeight(bounds)-self.font.lineHeight-self.placeholderLabel.font.lineHeight+textFieldInsets.y);
186 | }
187 |
188 | - (void)layoutPlaceholderInTextRect {
189 | self.placeholderLabel.transform = CGAffineTransformIdentity;
190 |
191 | CGRect textRect = [self textRectForBounds:self.bounds];
192 | CGFloat originX = textRect.origin.x;
193 |
194 | switch (self.textAlignment) {
195 | case NSTextAlignmentCenter:
196 | originX += textRect.size.width/2-self.placeholderLabel.bounds.size.width/2;
197 | break;
198 | case NSTextAlignmentRight:
199 | originX += textRect.size.width-self.placeholderLabel.bounds.size.width;
200 | break;
201 | default:
202 | break;
203 | }
204 |
205 | self.placeholderLabel.frame = CGRectMake(originX, CGRectGetHeight(textRect)-CGRectGetHeight(self.placeholderLabel.bounds)-placeholderInsets.y, CGRectGetWidth(self.placeholderLabel.bounds), CGRectGetHeight(self.placeholderLabel.bounds));
206 | }
207 |
208 | @end
209 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/RuriTextField.m:
--------------------------------------------------------------------------------
1 | //
2 | // RuriTextField.m
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/29/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 |
10 | #import "RuriTextField.h"
11 |
12 | @interface RuriTextField ()
13 |
14 | @property (strong, nonatomic) CALayer *borderLayer;
15 |
16 | @end
17 |
18 | @implementation RuriTextField
19 |
20 | #pragma mark - Constants
21 | static CGFloat const borderActiveThickness = 1;
22 | static CGFloat const borderInactiveThickness = 3;
23 | static CGPoint const textFieldInsets = {6, 6};
24 | static CGPoint const placeholderInsets = {6, 6};
25 |
26 | #pragma mark - Custom accessory
27 | - (void)setPlaceholderColor:(UIColor *)placeholderColor {
28 | _placeholderColor = placeholderColor;
29 |
30 | [self updatePlaceholder];
31 | }
32 |
33 | - (void)setBorderColor:(UIColor *)borderColor {
34 | _borderColor = borderColor;
35 |
36 | [self updateBorder];
37 | }
38 |
39 | - (void)setPlaceholderFontScale:(CGFloat)placeholderFontScale {
40 | _placeholderFontScale = placeholderFontScale;
41 |
42 | [self updatePlaceholder];
43 | }
44 |
45 | - (void)setPlaceholder:(NSString *)placeholder {
46 | [super setPlaceholder:placeholder];
47 |
48 | [self updatePlaceholder];
49 | }
50 |
51 | - (void)setBounds:(CGRect)bounds {
52 | [super setBounds:bounds];
53 |
54 | [self updateBorder];
55 | [self updatePlaceholder];
56 | }
57 |
58 | #pragma mark - Lifecycle
59 | - (instancetype)initWithFrame:(CGRect)frame {
60 | self = [super initWithFrame:frame];
61 |
62 | if (self) {
63 | [self commonInit];
64 | }
65 |
66 | return self;
67 | }
68 |
69 | - (instancetype) initWithCoder:(NSCoder *)aDecoder {
70 | self = [super initWithCoder:aDecoder];
71 |
72 | if (self) {
73 | [self commonInit];
74 | }
75 | return self;
76 | }
77 |
78 | - (void) commonInit {
79 | self.borderLayer = [[CALayer alloc] init];
80 | self.placeholderLabel = [[UILabel alloc] init];
81 |
82 | self.placeholderColor = [UIColor colorWithRed:0.4118 green:0.4118 blue:0.4118 alpha:1.0];
83 | self.borderColor = [UIColor colorWithRed:0.7137 green:0.7647 blue:0.6745 alpha:1];
84 | self.cursorColor = [UIColor whiteColor];
85 | self.textColor = self.cursorColor;
86 | self.activeColor = [UIColor colorWithRed:0.6392 green:0.8275 blue:0.6118 alpha:1];
87 |
88 | self.placeholderFontScale = 0.8;
89 | }
90 |
91 | #pragma mark - Overridden methods
92 | - (void)drawRect:(CGRect)rect {
93 | CGRect frame = CGRectMake(0, 0, CGRectGetWidth(rect), CGRectGetHeight(rect));
94 |
95 | self.placeholderLabel.frame = CGRectInset(frame, placeholderInsets.x, placeholderInsets.y);
96 | self.placeholderLabel.font = [self placeholderFontFromFont:self.font];
97 |
98 | [self updateBorder];
99 | [self updatePlaceholder];
100 |
101 | [self.layer addSublayer:self.borderLayer];
102 | [self addSubview:self.placeholderLabel];
103 | }
104 |
105 | - (CGRect)editingRectForBounds:(CGRect)bounds {
106 | return CGRectInset([self rectForBorderBounds:bounds], textFieldInsets.x, 0);
107 | }
108 |
109 | - (CGRect)textRectForBounds:(CGRect)bounds {
110 | return CGRectInset([self rectForBorderBounds:bounds], textFieldInsets.x, 0);
111 | }
112 |
113 | - (void)animateViewsForTextEntry {
114 |
115 | [UIView animateWithDuration:0.3 animations:^{
116 | CGAffineTransform translate = CGAffineTransformMakeTranslation(-placeholderInsets.x, self.placeholderLabel.bounds.size.height + (placeholderInsets.y*2));
117 | CGAffineTransform scale = CGAffineTransformMakeScale(0.9, 0.9);
118 | self.placeholderLabel.transform = CGAffineTransformConcat(translate, scale);
119 | self.placeholderLabel.textColor = self.activeColor;
120 | self.borderLayer.borderColor = self.activeColor.CGColor;
121 |
122 | CGRect rect = [self rectForBorderBounds:self.bounds];
123 | self.borderLayer.frame = CGRectMake(0, CGRectGetHeight(rect)-borderActiveThickness, CGRectGetWidth(rect), borderActiveThickness);
124 | } completion:^(BOOL finished) {
125 | if (self.didBeginEditingHandler != nil) {
126 | self.didBeginEditingHandler();
127 | }
128 | }];
129 | }
130 |
131 | - (void)animateViewsForTextDisplay {
132 | if (self.text.length == 0) {
133 |
134 | [UIView animateWithDuration:0.3 animations:^{
135 | self.placeholderLabel.transform = CGAffineTransformIdentity;
136 | self.placeholderLabel.textColor = self.placeholderColor;
137 | self.borderLayer.borderColor = self.borderColor.CGColor;
138 |
139 | CGRect rect = [self rectForBorderBounds:self.bounds];
140 | self.borderLayer.frame = CGRectMake(0, CGRectGetHeight(rect)-borderInactiveThickness, CGRectGetWidth(rect), borderInactiveThickness);
141 | } completion:^(BOOL finished) {
142 | if (self.didEndEditingHandler != nil) {
143 | self.didEndEditingHandler();
144 | }
145 | }];
146 | }
147 | }
148 |
149 | #pragma mark - Private methods
150 | - (void)updateBorder {
151 | CGRect rect = [self rectForBorderBounds:self.bounds];
152 |
153 | self.borderLayer.frame = CGRectMake(0, CGRectGetHeight(rect)-borderInactiveThickness, CGRectGetWidth(rect), borderInactiveThickness);
154 | self.borderLayer.borderColor = self.borderColor.CGColor;
155 | self.borderLayer.borderWidth = borderInactiveThickness;
156 | }
157 |
158 | - (CGFloat)percentageForBottomBorder {
159 | CGRect borderRect = [self rectForBorderBounds:self.bounds];
160 | CGFloat sumOfSides = (borderRect.size.width*2) + (borderRect.size.height*2);
161 | return (borderRect.size.width*100 / sumOfSides) / 100;
162 | }
163 |
164 | - (void)updatePlaceholder {
165 | self.placeholderLabel.text = self.placeholder;
166 | self.placeholderLabel.textColor = self.placeholderColor;
167 | [self.placeholderLabel sizeToFit];
168 | [self layoutPlaceholderInTextRect];
169 |
170 | if ([self isFirstResponder] || self.text.length!=0) {
171 | [self animateViewsForTextEntry];
172 | }
173 | }
174 |
175 | - (UIFont *)placeholderFontFromFont:(UIFont *)font {
176 | UIFont *smallerFont = [UIFont fontWithName:font.fontName size:font.pointSize*self.placeholderFontScale];
177 |
178 | return smallerFont;
179 | }
180 |
181 | - (CGRect)rectForBorderBounds:(CGRect)bounds {
182 | return CGRectMake(0, 0, CGRectGetWidth(bounds), CGRectGetHeight(bounds)-self.font.lineHeight-textFieldInsets.y);
183 | }
184 |
185 | - (void)layoutPlaceholderInTextRect {
186 | self.placeholderLabel.transform = CGAffineTransformIdentity;
187 |
188 | CGRect textRect = [self textRectForBounds:self.bounds];
189 | CGFloat originX = textRect.origin.x;
190 |
191 | switch (self.textAlignment) {
192 | case NSTextAlignmentCenter:
193 | originX += textRect.size.width/2-self.placeholderLabel.bounds.size.width/2;
194 | break;
195 | case NSTextAlignmentRight:
196 | originX += textRect.size.width-self.placeholderLabel.bounds.size.width;
197 | break;
198 | default:
199 | break;
200 | }
201 |
202 | self.placeholderLabel.frame = CGRectMake(originX, CGRectGetHeight(textRect)-CGRectGetHeight(self.placeholderLabel.bounds)-placeholderInsets.y, CGRectGetWidth(self.placeholderLabel.bounds), CGRectGetHeight(self.placeholderLabel.bounds));
203 | }
204 |
205 | @end
206 |
207 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/ManamiTextField.m:
--------------------------------------------------------------------------------
1 | //
2 | // ManamiTextField.m
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/30/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import "ManamiTextField.h"
10 |
11 | @interface ManamiTextField ()
12 |
13 | @property (strong, nonatomic) CALayer *borderLayer;
14 | @property (strong, nonatomic) CALayer *backgroundLayer;
15 | @property (strong, nonatomic) UIColor *backgroundLayerColor;
16 |
17 | @end
18 |
19 | @implementation ManamiTextField
20 |
21 | #pragma mark - Constants
22 | static CGFloat const borderThickness = 1.5;
23 | static CGPoint const textFieldInsets = {6, 6};
24 | static CGPoint const placeholderInsets = {6, 6};
25 |
26 | #pragma mark - Custom accessory
27 | - (void)setPlaceholderColor:(UIColor *)placeholderColor {
28 | _placeholderColor = placeholderColor;
29 |
30 | [self updatePlaceholder];
31 | }
32 |
33 | - (void)setBorderColor:(UIColor *)borderColor {
34 | _borderColor = borderColor;
35 |
36 | [self updateBorder];
37 | }
38 |
39 | - (void)setBackgroundColor:(UIColor *)backgroundColor {
40 | self.backgroundLayerColor = backgroundColor;
41 |
42 | self.backgroundLayer.backgroundColor = backgroundColor.CGColor;
43 | }
44 |
45 | - (UIColor *)backgroundColor {
46 | return self.backgroundLayerColor;
47 | }
48 |
49 | - (void)setPlaceholderFontScale:(CGFloat)placeholderFontScale {
50 | _placeholderFontScale = placeholderFontScale;
51 |
52 | [self updatePlaceholder];
53 | }
54 |
55 | - (void)setPlaceholder:(NSString *)placeholder {
56 | [super setPlaceholder:placeholder];
57 |
58 | [self updatePlaceholder];
59 | }
60 |
61 | - (void)setBounds:(CGRect)bounds {
62 | [super setBounds:bounds];
63 |
64 | [self updateBorder];
65 | [self updatePlaceholder];
66 | }
67 |
68 | #pragma mark - Lifecycle
69 | - (instancetype)initWithFrame:(CGRect)frame {
70 | self = [super initWithFrame:frame];
71 |
72 | if (self) {
73 | [self commonInit];
74 | }
75 |
76 | return self;
77 | }
78 |
79 | - (instancetype) initWithCoder:(NSCoder *)aDecoder {
80 | self = [super initWithCoder:aDecoder];
81 |
82 | if (self) {
83 | [self commonInit];
84 | }
85 | return self;
86 | }
87 |
88 | - (void) commonInit {
89 | self.borderLayer = [[CALayer alloc] init];
90 | self.backgroundLayer = [[CALayer alloc] init];
91 | self.placeholderLabel = [[UILabel alloc] init];
92 |
93 | self.placeholderColor = [UIColor colorWithRed:0.4118 green:0.4118 blue:0.4118 alpha:1.0];
94 | self.borderColor = [UIColor colorWithRed:0.6588 green:0.6588 blue:0.6588 alpha:1];
95 | self.backgroundColor = self.borderColor;
96 | self.cursorColor = [UIColor colorWithRed:0.9765 green:0.9686 blue:0.9647 alpha:1];
97 | self.textColor = self.cursorColor;
98 |
99 | self.placeholderFontScale = 0.9;
100 | }
101 |
102 | #pragma mark - Overridden methods
103 | - (void)drawRect:(CGRect)rect {
104 | CGRect frame = CGRectMake(0, 0, CGRectGetWidth(rect), CGRectGetHeight(rect));
105 |
106 | self.placeholderLabel.frame = CGRectInset(frame, placeholderInsets.x, placeholderInsets.y);
107 | self.placeholderLabel.font = [self placeholderFontFromFont:self.font];
108 |
109 | [self updateBorder];
110 | [self updatePlaceholder];
111 |
112 | [self.layer addSublayer:self.borderLayer];
113 | [self addSubview:self.placeholderLabel];
114 |
115 | CGRect backgroundRect = [self editingRectForBounds:self.bounds];
116 | self.backgroundLayer.frame = CGRectMake(0, backgroundRect.origin.y, CGRectGetWidth(backgroundRect), 0);
117 | [self.layer addSublayer:self.backgroundLayer];
118 | }
119 |
120 | - (CGRect)editingRectForBounds:(CGRect)bounds {
121 | return CGRectInset([self rectForBorderBounds:bounds], textFieldInsets.x, 0);
122 | }
123 |
124 | - (CGRect)textRectForBounds:(CGRect)bounds {
125 | return CGRectInset([self rectForBorderBounds:bounds], textFieldInsets.x, 0);
126 | }
127 |
128 | - (void)animateViewsForTextEntry {
129 | if (self.text.length == 0) {
130 | [UIView animateWithDuration:0.3 animations:^{
131 | CGAffineTransform translate = CGAffineTransformMakeTranslation(-placeholderInsets.x, self.placeholderLabel.bounds.size.height + (placeholderInsets.y*2));
132 | CGAffineTransform scale = CGAffineTransformMakeScale(0.9, 0.9);
133 | self.placeholderLabel.transform = CGAffineTransformConcat(translate, scale);
134 | self.placeholderLabel.alpha = 0.4;
135 |
136 | CGRect backgroundRect = [self editingRectForBounds:self.bounds];
137 | self.backgroundLayer.frame = CGRectMake(0, backgroundRect.origin.y, CGRectGetWidth(backgroundRect), CGRectGetHeight(backgroundRect));
138 |
139 | self.borderLayer.opacity = 0;
140 | } completion:^(BOOL finished) {
141 | if (self.didBeginEditingHandler != nil) {
142 | self.didBeginEditingHandler();
143 | }
144 | }];
145 | }
146 | }
147 |
148 | - (void)animateViewsForTextDisplay {
149 | if (self.text.length == 0) {
150 |
151 | [UIView animateWithDuration:0.3 animations:^{
152 | self.placeholderLabel.transform = CGAffineTransformIdentity;
153 | self.placeholderLabel.alpha = 1;
154 |
155 | CGRect backgroundRect = [self editingRectForBounds:self.bounds];
156 | self.backgroundLayer.frame = CGRectMake(0, backgroundRect.origin.y, CGRectGetWidth(backgroundRect), 0);
157 |
158 | self.borderLayer.opacity = 1;
159 | } completion:^(BOOL finished) {
160 | if (self.didEndEditingHandler != nil) {
161 | self.didEndEditingHandler();
162 | }
163 | }];
164 | }
165 | }
166 |
167 | #pragma mark - Private methods
168 | - (void)updateBorder {
169 | CGRect rect = [self rectForBorderBounds:self.bounds];
170 | self.borderLayer.frame = CGRectMake(0, CGRectGetHeight(rect), CGRectGetWidth(rect), borderThickness);
171 | self.borderLayer.borderWidth = borderThickness;
172 | self.borderLayer.borderColor = self.borderColor.CGColor;
173 | }
174 |
175 | - (void)updatePlaceholder {
176 | self.placeholderLabel.text = self.placeholder;
177 | self.placeholderLabel.textColor = self.placeholderColor;
178 | [self.placeholderLabel sizeToFit];
179 | [self layoutPlaceholderInTextRect];
180 |
181 | if ([self isFirstResponder] || self.text.length!=0) {
182 | [self animateViewsForTextEntry];
183 | }
184 | }
185 |
186 | - (UIFont *)placeholderFontFromFont:(UIFont *)font {
187 | UIFont *smallerFont = [UIFont fontWithName:font.fontName size:font.pointSize*self.placeholderFontScale];
188 |
189 | return smallerFont;
190 | }
191 |
192 | - (CGRect)rectForBorderBounds:(CGRect)bounds {
193 | return CGRectMake(0, 0, CGRectGetWidth(bounds), CGRectGetHeight(bounds)-self.font.lineHeight-textFieldInsets.y);
194 | }
195 |
196 | - (void)layoutPlaceholderInTextRect {
197 | self.placeholderLabel.transform = CGAffineTransformIdentity;
198 |
199 | CGRect textRect = [self textRectForBounds:self.bounds];
200 | CGFloat originX = textRect.origin.x;
201 |
202 | switch (self.textAlignment) {
203 | case NSTextAlignmentCenter:
204 | originX += textRect.size.width/2-self.placeholderLabel.bounds.size.width/2;
205 | break;
206 | case NSTextAlignmentRight:
207 | originX += textRect.size.width-self.placeholderLabel.bounds.size.width;
208 | break;
209 | default:
210 | break;
211 | }
212 |
213 | self.placeholderLabel.frame = CGRectMake(originX, CGRectGetHeight(textRect)-CGRectGetHeight(self.placeholderLabel.bounds)-placeholderInsets.y, CGRectGetWidth(self.placeholderLabel.bounds), CGRectGetHeight(self.placeholderLabel.bounds));
214 | }
215 |
216 | @end
217 |
218 |
219 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/HoshiTextField.m:
--------------------------------------------------------------------------------
1 | //
2 | // HoshiTextField.m
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/25/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import "HoshiTextField.h"
10 |
11 | @interface HoshiTextField ()
12 |
13 | @property (strong, nonatomic) CALayer *inactiveBorderLayer;
14 | @property (strong, nonatomic) CALayer *activeBorderLayer;
15 | @property (nonatomic) CGPoint activePlaceholderPoint;
16 |
17 | @end
18 |
19 | @implementation HoshiTextField
20 |
21 | #pragma mark - Constants
22 | static CGFloat const activeBorderThickness = 2;
23 | static CGFloat const inactiveBorderThickness = 0.7;
24 | static CGPoint const textFieldInsets = {0, 12};
25 | static CGPoint const placeholderInsets = {0, 6};
26 |
27 | #pragma mark - Custom accessorys
28 | - (void)setBorderInactiveColor:(UIColor *)borderInactiveColor {
29 | _borderInactiveColor = borderInactiveColor;
30 |
31 | [self updateBorder];
32 | }
33 |
34 | - (void)setBorderActiveColor:(UIColor *)borderActiveColor {
35 | _borderActiveColor = borderActiveColor;
36 |
37 | [self updateBorder];
38 | }
39 |
40 | - (void)setPlaceholderColor:(UIColor *)placeholderColor {
41 | _placeholderColor = placeholderColor;
42 |
43 | [self updatePlaceholder];
44 | }
45 |
46 | - (void)setPlaceholderFontScale:(CGFloat)placeholderFontScale {
47 | _placeholderFontScale = placeholderFontScale;
48 |
49 | [self updatePlaceholder];
50 | }
51 |
52 | - (void)setPlaceholder:(NSString *)placeholder {
53 | [super setPlaceholder:placeholder];
54 |
55 | [self updatePlaceholder];
56 | }
57 |
58 | - (void)setBounds:(CGRect)bounds {
59 | [super setBounds:bounds];
60 |
61 | [self updateBorder];
62 | [self updatePlaceholder];
63 | }
64 |
65 | #pragma mark - Lifecycle
66 | - (instancetype)initWithFrame:(CGRect)frame {
67 | self = [super initWithFrame:frame];
68 |
69 | if (self) {
70 | [self commonInit];
71 | }
72 |
73 | return self;
74 | }
75 |
76 | - (instancetype) initWithCoder:(NSCoder *)aDecoder {
77 | self = [super initWithCoder:aDecoder];
78 |
79 | if (self) {
80 | [self commonInit];
81 | }
82 | return self;
83 | }
84 |
85 | - (void) commonInit {
86 | self.inactiveBorderLayer = [[CALayer alloc] init];
87 | self.activeBorderLayer = [[CALayer alloc] init];
88 | self.placeholderLabel = [[UILabel alloc] init];
89 |
90 | self.borderInactiveColor = [UIColor colorWithRed:0.7255 green:0.7569 blue:0.7922 alpha:1.0];
91 | self.borderActiveColor = [UIColor colorWithRed:0.4157 green:0.4745 blue:0.5373 alpha:1.0];
92 | self.placeholderColor = self.borderInactiveColor;
93 | self.cursorColor = [UIColor colorWithRed:0.349 green:0.3725 blue:0.4314 alpha:1.0];
94 | self.textColor = [UIColor colorWithRed:0.2785 green:0.2982 blue:0.3559 alpha:1.0];
95 |
96 | self.placeholderFontScale = 0.65;
97 | self.activePlaceholderPoint = CGPointZero;
98 | }
99 |
100 | #pragma mark - Overridden methods
101 | - (void)drawRect:(CGRect)rect {
102 | CGRect frame = CGRectMake(0, 0, rect.size.width, rect.size.height);
103 | self.placeholderLabel.frame = CGRectInset(frame, placeholderInsets.x, placeholderInsets.y);
104 | self.placeholderLabel.font = [self placeholderFontFromFont:self.font];
105 |
106 | [self updateBorder];
107 | [self updatePlaceholder];
108 |
109 | [self.layer addSublayer:self.inactiveBorderLayer];
110 | [self.layer addSublayer:self.activeBorderLayer];
111 | [self addSubview:self.placeholderLabel];
112 | }
113 |
114 | - (CGRect)editingRectForBounds:(CGRect)bounds {
115 | return CGRectOffset(bounds, textFieldInsets.x, textFieldInsets.y);
116 | }
117 |
118 | - (CGRect)textRectForBounds:(CGRect)bounds {
119 | return CGRectOffset(bounds, textFieldInsets.x, textFieldInsets.y);
120 | }
121 |
122 | - (void)animateViewsForTextEntry {
123 | if (self.text.length == 0) {
124 | [UIView animateWithDuration:0.35 delay:0 usingSpringWithDamping:0.8 initialSpringVelocity:1.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
125 | self.placeholderLabel.frame = CGRectMake(10, self.placeholderLabel.frame.origin.y, CGRectGetWidth(self.placeholderLabel.frame), CGRectGetHeight(self.placeholderLabel.frame));
126 | self.placeholderLabel.alpha = 0;
127 | } completion:^(BOOL finished) {
128 | if (self.didBeginEditingHandler != nil) {
129 | self.didBeginEditingHandler();
130 | }
131 | }];
132 | }
133 |
134 | [self layoutPlaceholderInTextRect];
135 | self.placeholderLabel.frame = CGRectMake(self.activePlaceholderPoint.x, self.activePlaceholderPoint.y, CGRectGetWidth(self.placeholderLabel.frame), CGRectGetHeight(self.placeholderLabel.frame));
136 |
137 | [UIView animateWithDuration:0.2 animations:^{
138 | self.placeholderLabel.alpha = 0.5;
139 | }];
140 |
141 | self.activeBorderLayer.frame = [self rectForBorderThickness:activeBorderThickness isFilled:YES];
142 | }
143 |
144 | - (void)animateViewsForTextDisplay {
145 | if (self.text.length == 0) {
146 | [UIView animateWithDuration:0.35 delay:0 usingSpringWithDamping:0.8 initialSpringVelocity:2.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
147 | [self layoutPlaceholderInTextRect];
148 | self.placeholderLabel.alpha = 1.0;
149 | } completion:^(BOOL finished) {
150 | if (self.didEndEditingHandler != nil) {
151 | self.didEndEditingHandler();
152 | }
153 | }];
154 |
155 | self.activeBorderLayer.frame = [self rectForBorderThickness:activeBorderThickness isFilled:NO];
156 | }
157 | }
158 |
159 | #pragma mark - Private methods
160 | - (void)updateBorder{
161 | self.inactiveBorderLayer.frame = [self rectForBorderThickness:inactiveBorderThickness isFilled:YES];
162 | self.inactiveBorderLayer.backgroundColor = self.borderInactiveColor.CGColor;
163 |
164 | self.activeBorderLayer.frame = [self rectForBorderThickness:activeBorderThickness isFilled:NO];
165 | self.activeBorderLayer.backgroundColor = self.borderActiveColor.CGColor;
166 | }
167 |
168 | - (void)updatePlaceholder {
169 | self.placeholderLabel.text = self.placeholder;
170 | self.placeholderLabel.textColor = self.placeholderColor;
171 | [self.placeholderLabel sizeToFit];
172 | [self layoutPlaceholderInTextRect];
173 |
174 | if ([self isFirstResponder] || self.text.length!=0) {
175 | [self animateViewsForTextEntry];
176 | }
177 | }
178 |
179 | - (UIFont *)placeholderFontFromFont:(UIFont *)font {
180 | UIFont *smallerFont = [UIFont fontWithName:font.fontName size:font.pointSize*self.placeholderFontScale];
181 |
182 | return smallerFont;
183 | }
184 |
185 | - (CGRect)rectForBorderThickness:(CGFloat)thickness isFilled:(BOOL)isFilled {
186 | if (isFilled) {
187 | return CGRectMake(0, CGRectGetHeight(self.frame)-thickness, CGRectGetWidth(self.frame), thickness);
188 | } else {
189 | return CGRectMake(0, CGRectGetHeight(self.frame)-thickness, 0, thickness);
190 | }
191 | }
192 |
193 | - (void)layoutPlaceholderInTextRect {
194 | CGRect textRect = [self textRectForBounds:self.bounds];
195 | CGFloat originX = textRect.origin.x;
196 |
197 | switch (self.textAlignment) {
198 | case NSTextAlignmentCenter:
199 | originX += textRect.size.width/2-self.placeholderLabel.bounds.size.width/2;
200 | break;
201 | case NSTextAlignmentRight:
202 | originX += textRect.size.width-self.placeholderLabel.bounds.size.width;
203 | break;
204 | default:
205 | break;
206 | }
207 |
208 | self.placeholderLabel.frame = CGRectMake(originX, textRect.size.height/2, CGRectGetWidth(self.placeholderLabel.bounds), CGRectGetHeight(self.placeholderLabel.bounds));
209 | self.activePlaceholderPoint = CGPointMake(self.placeholderLabel.frame.origin.x, self.placeholderLabel.frame.origin.y-self.placeholderLabel.frame.size.height-placeholderInsets.y);
210 | }
211 |
212 | @end
213 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/KuroTextField.m:
--------------------------------------------------------------------------------
1 | //
2 | // KuroTextField.m
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/29/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import "KuroTextField.h"
10 |
11 | @interface KuroTextField ()
12 |
13 | @property (strong ,nonatomic) CAShapeLayer *leftLayer;
14 | @property (strong, nonatomic) CAShapeLayer *rightLayer;
15 | @property (nonatomic) CGFloat placeholderHeight;
16 |
17 | @end
18 |
19 |
20 | /**
21 | When I implement the original effect for Kuro with two CAShpaLayer, there is a issue for text alignment (thoungh I do not think it is the problem of CAShapeLayer), So I made some change to Kuro.
22 | The current effect for Kuro can be implemented simply by a CALayer. There is not need to use two CAShapeLayer. But I am somehow lazy to modify the code.
23 | // TODO: Use single CALayer.
24 | */
25 | @implementation KuroTextField
26 |
27 | # pragma mark - Constants
28 | static CGFloat const borderThickness = 3;
29 | static CGFloat const borderMoveDistance = 12;
30 | static CGPoint const placeholderInset = {10,2};
31 | static CGPoint const textFieldInset = {6,0};
32 |
33 | # pragma mark - Custom accessorys
34 | - (void)setBorderColor:(UIColor *)borderColor {
35 | _borderColor = borderColor;
36 |
37 | self.leftLayer.strokeColor = borderColor.CGColor;
38 | self.rightLayer.strokeColor = borderColor.CGColor;
39 | }
40 |
41 | - (void)setPlaceholderColor:(UIColor *)placeholderColor {
42 | _placeholderColor = placeholderColor;
43 |
44 | self.placeholderLabel.textColor = placeholderColor;
45 | }
46 |
47 | - (void)setPlaceholderFontScale:(CGFloat)placeholderFontScale {
48 | _placeholderFontScale = placeholderFontScale;
49 |
50 | self.placeholderLabel.font = [self placeholderFontFromFont:self.font];
51 | }
52 |
53 | - (void)setPlaceholder:(NSString *)placeholder {
54 | [super setPlaceholder:placeholder];
55 |
56 | self.placeholderLabel.text = placeholder;
57 | }
58 |
59 | - (CGFloat)placeholderHeight {
60 | return self.placeholderLabel.font.lineHeight;
61 | }
62 |
63 | # pragma mark - Lifecycle
64 | - (instancetype)initWithFrame:(CGRect)frame {
65 | self = [super initWithFrame:frame];
66 |
67 | if (self) {
68 | [self commonInit];
69 | }
70 |
71 | return self;
72 | }
73 |
74 | - (instancetype) initWithCoder:(NSCoder *)aDecoder {
75 | self = [super initWithCoder:aDecoder];
76 |
77 | if (self) {
78 | [self commonInit];
79 | }
80 | return self;
81 | }
82 |
83 | - (void) commonInit {
84 | self.leftLayer = [[CAShapeLayer alloc] init];
85 | self.leftLayer.fillColor = [UIColor clearColor].CGColor;
86 | self.leftLayer.borderColor = self.leftLayer.fillColor;
87 | self.leftLayer.lineWidth = borderThickness;
88 |
89 | self.rightLayer = [[CAShapeLayer alloc] init];
90 | self.rightLayer.fillColor = [UIColor clearColor].CGColor;
91 | self.rightLayer.borderColor = self.rightLayer.fillColor;
92 | self.rightLayer.lineWidth = borderThickness;
93 |
94 | self.placeholderLabel = [[UILabel alloc] init];
95 |
96 | self.borderColor = [UIColor colorWithRed:0.4549 green:0.4745 blue:0.5059 alpha:1];
97 | self.placeholderColor = [UIColor colorWithRed:0.8745 green:0.3961 blue:0.5373 alpha:1];
98 | self.cursorColor = [UIColor colorWithRed:0.5686 green:0.5882 blue:0.6314 alpha:1];
99 | self.textColor = self.cursorColor;
100 |
101 | self.placeholderFontScale = 0.85;
102 | }
103 |
104 | # pragma mark - Overridden methods
105 | - (void)drawRect:(CGRect)rect {
106 | UIBezierPath *leftPath = [UIBezierPath bezierPath];
107 | [leftPath moveToPoint:CGPointMake(CGRectGetWidth(rect)/2+borderMoveDistance*2,borderThickness/2)];
108 | [leftPath addLineToPoint:CGPointMake(borderMoveDistance+borderThickness,borderThickness/2)];
109 | [leftPath addLineToPoint:CGPointMake(borderMoveDistance+borderThickness,CGRectGetHeight(rect)-borderThickness-placeholderInset.y-self.placeholderHeight)];
110 | [leftPath addLineToPoint:CGPointMake(CGRectGetWidth(rect)/2+2*borderMoveDistance,CGRectGetHeight(rect)-borderThickness-placeholderInset.y-self.placeholderHeight)];
111 | self.leftLayer.path = leftPath.CGPath;
112 | [self.layer addSublayer:self.leftLayer];
113 |
114 | UIBezierPath *rightPath = [UIBezierPath bezierPath];
115 | [rightPath moveToPoint:CGPointMake(CGRectGetWidth(rect)/2,borderThickness/2)];
116 | [rightPath addLineToPoint:CGPointMake(CGRectGetWidth(rect)-borderMoveDistance-borderThickness,borderThickness/2)];
117 | [rightPath addLineToPoint:CGPointMake(CGRectGetWidth(rect)-borderMoveDistance-borderThickness,CGRectGetHeight(rect)-borderThickness-placeholderInset.y-self.placeholderHeight)];
118 | [rightPath addLineToPoint:CGPointMake(CGRectGetWidth(rect)/2,CGRectGetHeight(rect)-borderThickness-placeholderInset.y-self.placeholderHeight)];
119 | self.rightLayer.path = rightPath.CGPath;
120 | [self.layer addSublayer:self.rightLayer];
121 |
122 | self.placeholderLabel.frame = CGRectMake(placeholderInset.x+borderMoveDistance, (CGRectGetHeight([self textRectForBounds:rect])-self.placeholderHeight)/2+2*borderThickness, CGRectGetWidth(rect), self.placeholderHeight);
123 | [self.placeholderLabel sizeToFit];
124 | [self addSubview:self.placeholderLabel];
125 | }
126 |
127 | - (CGRect)textRectForBounds:(CGRect)bounds {
128 | CGRect newBounds = CGRectMake(0, 0, CGRectGetWidth(bounds), CGRectGetHeight(bounds)-borderThickness-placeholderInset.y-self.placeholderHeight);
129 |
130 | return CGRectInset(newBounds, 1.5*borderThickness+textFieldInset.x, 1.5*borderThickness);
131 | }
132 |
133 | - (CGRect)editingRectForBounds:(CGRect)bounds {
134 | CGRect newBounds = CGRectMake(0, 0, CGRectGetWidth(bounds), CGRectGetHeight(bounds)-borderThickness-placeholderInset.y-self.placeholderHeight);
135 |
136 | return CGRectInset(newBounds, 1.5*borderThickness+textFieldInset.x, 1.5*borderThickness);
137 | }
138 |
139 | - (void)animateViewsForTextEntry {
140 | if (self.text.length == 0) {
141 | // Hide cursor when animating.
142 | UIColor *originalCursorColor = self.cursorColor;
143 | self.cursorColor = [UIColor clearColor];
144 |
145 | [UIView transitionWithView:self.placeholderLabel duration:0.35 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
146 | self.placeholderLabel.transform = CGAffineTransformMakeScale(0.001, 0.001);
147 | self.leftLayer.frame = CGRectOffset(self.leftLayer.frame, -borderMoveDistance, 0);
148 | self.rightLayer.frame = CGRectOffset(self.rightLayer.frame, borderMoveDistance, 0);
149 | } completion:^(BOOL finished) {
150 | [UIView animateWithDuration:0.1 animations:^{
151 | self.placeholderLabel.frame = CGRectOffset(self.placeholderLabel.frame, -borderMoveDistance, CGRectGetHeight(self.bounds)*0.5-0.75*borderThickness-0.5*placeholderInset.y);
152 | self.placeholderLabel.transform = CGAffineTransformIdentity;
153 | } completion:^(BOOL finished) {
154 | self.cursorColor = originalCursorColor;
155 |
156 | if (self.didBeginEditingHandler != nil) {
157 | self.didBeginEditingHandler();
158 | }
159 | }];
160 | }];
161 | }
162 | }
163 |
164 | - (void)animateViewsForTextDisplay {
165 | if (self.text.length == 0) {
166 | [UIView transitionWithView:self.placeholderLabel duration:0.35 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
167 | self.placeholderLabel.transform = CGAffineTransformMakeScale(0.001, 0.001);
168 | self.leftLayer.frame = CGRectOffset(self.leftLayer.frame, borderMoveDistance, 0);
169 | self.rightLayer.frame = CGRectOffset(self.rightLayer.frame, -borderMoveDistance, 0);
170 | } completion:^(BOOL finished) {
171 | [UIView animateWithDuration:0.2 animations:^{
172 | self.placeholderLabel.frame = CGRectOffset(self.placeholderLabel.frame, borderMoveDistance, -CGRectGetHeight(self.bounds)*0.5+0.75*borderThickness+0.5*placeholderInset.y);
173 | self.placeholderLabel.transform = CGAffineTransformIdentity;
174 | } completion:^(BOOL finished) {
175 | if (self.didEndEditingHandler != nil) {
176 | self.didEndEditingHandler();
177 | }
178 | }];
179 | }];
180 | }
181 | }
182 |
183 | # pragma mark - Private methods
184 | - (UIFont *)placeholderFontFromFont:(UIFont *)font {
185 | UIFont *smallerFont = [UIFont fontWithName:self.font.fontName size:self.font.pointSize*self.placeholderFontScale];
186 |
187 | return smallerFont;
188 | }
189 |
190 | @end
191 |
--------------------------------------------------------------------------------
/CCTextFieldEffects/YokoTextField.m:
--------------------------------------------------------------------------------
1 | //
2 | // YokoTextField.m
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/26/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import "YokoTextField.h"
10 |
11 | @interface YokoTextField ()
12 |
13 | @property (strong, nonatomic) UIView *foregroundView;
14 | @property (strong, nonatomic) CALayer *foregroundLayer;
15 |
16 | @end
17 |
18 | @implementation YokoTextField
19 |
20 | #pragma mark - Constants
21 | static CGFloat const borderThickness = 3;
22 | static CGPoint const textFieldInsets = {6, 6};
23 | //static CGPoint const placeholderInsets = {6, 6};
24 |
25 | #pragma mark - Custom accessorys
26 | - (void)setPlaceholderColor:(UIColor *)placeholderColor {
27 | _placeholderColor = placeholderColor;
28 |
29 | [self updatePlaceholder];
30 | }
31 |
32 | - (void)setForegroundColor:(UIColor *)foregroundColor {
33 | _foregroundColor = foregroundColor;
34 |
35 | [self updateForeground];
36 | }
37 |
38 | - (void)setPlaceholderFontScale:(CGFloat)placeholderFontScale {
39 | _placeholderFontScale = placeholderFontScale;
40 |
41 | [self updatePlaceholder];
42 | }
43 |
44 | - (void)setPlaceholder:(NSString *)placeholder {
45 | [super setPlaceholder:placeholder];
46 |
47 | [self updatePlaceholder];
48 | }
49 |
50 | - (void)setBounds:(CGRect)bounds {
51 | [super setBounds:bounds];
52 |
53 | [self updateForeground];
54 | [self updatePlaceholder];
55 | }
56 |
57 | #pragma mark - Lifecycle
58 | - (instancetype)initWithFrame:(CGRect)frame {
59 | self = [super initWithFrame:frame];
60 |
61 | if (self) {
62 | [self commonInit];
63 | }
64 |
65 | return self;
66 | }
67 |
68 | - (instancetype) initWithCoder:(NSCoder *)aDecoder {
69 | self = [super initWithCoder:aDecoder];
70 |
71 | if (self) {
72 | [self commonInit];
73 | }
74 | return self;
75 | }
76 |
77 | - (void) commonInit {
78 | self.foregroundView = [[UIView alloc] init];
79 | self.foregroundLayer = [[CALayer alloc] init];
80 | self.placeholderLabel = [[UILabel alloc] init];
81 |
82 | self.placeholderColor = [UIColor colorWithRed:0.6902 green:0.2941 blue:0.2501 alpha:1.0];
83 | self.foregroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:1];
84 | self.cursorColor = [UIColor colorWithRed:0.9608 green:0.9608 blue:0.9608 alpha:1.0];
85 | self.textColor = self.cursorColor;
86 |
87 | self.placeholderFontScale = 0.7;
88 | }
89 |
90 | #pragma mark - Overridden methods
91 | - (void)drawRect:(CGRect)rect {
92 | [self updateForeground];
93 | [self updatePlaceholder];
94 |
95 | [self addSubview:self.foregroundView];
96 | [self addSubview:self.placeholderLabel];
97 | [self.layer addSublayer:self.foregroundLayer];
98 | }
99 |
100 | - (CGRect)editingRectForBounds:(CGRect)bounds {
101 | CGRect newBounds = CGRectMake(0, 0, CGRectGetWidth(bounds), CGRectGetHeight(bounds)-self.font.lineHeight+textFieldInsets.y);
102 |
103 | return CGRectInset(newBounds, textFieldInsets.x, 0);
104 | }
105 |
106 | - (CGRect)textRectForBounds:(CGRect)bounds {
107 | CGRect newBounds = CGRectMake(0, 0, CGRectGetWidth(bounds), CGRectGetHeight(bounds)-self.font.lineHeight+textFieldInsets.y);
108 |
109 | return CGRectInset(newBounds, textFieldInsets.x, 0);
110 | }
111 |
112 | - (void)animateViewsForTextEntry {
113 | [UIView animateWithDuration:0.4 delay:0 usingSpringWithDamping:1.0 initialSpringVelocity:0.6 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
114 | self.foregroundView.layer.transform = CATransform3DIdentity;
115 | } completion:^(BOOL finished) {
116 | if (self.didBeginEditingHandler != nil) {
117 | self.didBeginEditingHandler();
118 | }
119 | }];
120 |
121 | self.foregroundLayer.frame = [self rectForBorderBounds:self.foregroundView.frame isFilled:NO];
122 | }
123 |
124 | - (void)animateViewsForTextDisplay {
125 | if (self.text.length == 0) {
126 | [UIView animateWithDuration:0.5 delay:0 usingSpringWithDamping:1.0 initialSpringVelocity:0.6 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
127 | self.foregroundLayer.frame = [self rectForBorderBounds:self.foregroundView.frame isFilled:YES];
128 | self.foregroundView.layer.transform = [self rotationAndPerspectiveTransformForView:self.foregroundView];
129 | } completion:^(BOOL finished) {
130 | if (self.didEndEditingHandler != nil) {
131 | self.didEndEditingHandler();
132 | }
133 | }];
134 | }
135 | }
136 |
137 | #pragma mark - Private methods
138 | - (void)updatePlaceholder {
139 | self.placeholderLabel.font = [self placeholderFontFromFont:self.font];
140 | self.placeholderLabel.text = self.placeholder;
141 | self.placeholderLabel.textColor = self.placeholderColor;
142 | [self.placeholderLabel sizeToFit];
143 | [self layoutPlaceholderInTextRect];
144 |
145 | if ([self isFirstResponder] || self.text.length!=0) {
146 | [self animateViewsForTextEntry];
147 | }
148 | }
149 |
150 | - (void)updateForeground {
151 | self.foregroundView.frame = [self rectForForegroundBounds:self.frame];
152 | self.foregroundView.userInteractionEnabled = NO;
153 | self.foregroundView.layer.transform = [self rotationAndPerspectiveTransformForView:self.foregroundView];
154 | self.foregroundView.backgroundColor = [self colorWithColor:self.foregroundColor alphaFactor:0.5];
155 |
156 | self.foregroundLayer.frame = [self rectForBorderBounds:self.foregroundView.frame isFilled:YES];
157 | self.foregroundLayer.borderWidth = borderThickness;
158 | self.foregroundLayer.borderColor = [self colorWithColor:self.foregroundColor alphaFactor:0.5].CGColor;
159 | }
160 |
161 | - (UIFont *)placeholderFontFromFont:(UIFont *)font {
162 | UIFont *smallerFont = [UIFont fontWithName:font.fontName size:font.pointSize*self.placeholderFontScale];
163 |
164 | return smallerFont;
165 | }
166 |
167 | - (CGRect)rectForForegroundBounds:(CGRect)bounds {
168 | return CGRectMake(0, 0, CGRectGetWidth(bounds), CGRectGetHeight(bounds)-self.font.lineHeight+textFieldInsets.y-borderThickness);
169 | }
170 |
171 | - (CGRect)rectForBorderBounds:(CGRect)bounds isFilled:(BOOL)isFilled {
172 | CGRect newRect = CGRectMake(0, CGRectGetHeight(bounds), CGRectGetWidth(bounds), isFilled?borderThickness:0);
173 |
174 | if (!CATransform3DIsIdentity(self.foregroundView.layer.transform)) {
175 | newRect = CGRectMake(0, bounds.origin.y, CGRectGetWidth(newRect), CGRectGetHeight(newRect));
176 | }
177 |
178 | return newRect;
179 | }
180 |
181 | - (void)layoutPlaceholderInTextRect {
182 | CGRect textRect = [self textRectForBounds:self.bounds];
183 | CGFloat originX = textRect.origin.x;
184 |
185 | switch (self.textAlignment) {
186 | case NSTextAlignmentCenter:
187 | originX += textRect.size.width/2-self.placeholderLabel.bounds.size.width/2;
188 | break;
189 | case NSTextAlignmentRight:
190 | originX += textRect.size.width-self.placeholderLabel.bounds.size.width;
191 | break;
192 | default:
193 | break;
194 | }
195 |
196 | self.placeholderLabel.frame = CGRectMake(originX, CGRectGetHeight(self.bounds)-CGRectGetHeight(self.placeholderLabel.frame), CGRectGetWidth(self.placeholderLabel.frame), CGRectGetHeight(self.placeholderLabel.frame));
197 | }
198 |
199 | - (void)setAnchorPoint:(CGPoint)anchorPoint forView:(UIView *)view {
200 | CGPoint newPoint = CGPointMake(CGRectGetWidth(view.bounds)*anchorPoint.x, CGRectGetHeight(view.bounds)*anchorPoint.y);
201 | CGPoint oldPoint = CGPointMake(CGRectGetWidth(view.bounds)*view.layer.anchorPoint.x, CGRectGetHeight(view.bounds)*view.layer.anchorPoint.y);
202 |
203 | newPoint = CGPointApplyAffineTransform(newPoint, view.transform);
204 | oldPoint = CGPointApplyAffineTransform(oldPoint, view.transform);
205 |
206 | CGPoint position = view.layer.position;
207 |
208 | position.x -= oldPoint.x;
209 | position.x += newPoint.x;
210 |
211 | position.y -= oldPoint.y;
212 | position.y += newPoint.y;
213 |
214 | view.layer.position = position;
215 | view.layer.anchorPoint = anchorPoint;
216 | }
217 |
218 | - (UIColor *)colorWithColor:(UIColor *)color alphaFactor:(CGFloat)factor {
219 | CGFloat hue = 0;
220 | CGFloat saturation = 0;
221 | CGFloat brightness = 0;
222 | CGFloat alpha = 0;
223 |
224 | if ([color getHue:&hue saturation:&saturation brightness:&brightness alpha:&alpha]) {
225 | return [UIColor colorWithHue:hue saturation:saturation brightness:brightness alpha:alpha*factor];
226 | } else {
227 | return color;
228 | }
229 | }
230 |
231 | - (CATransform3D)rotationAndPerspectiveTransformForView:(UIView *)view {
232 | [self setAnchorPoint:CGPointMake(0.5, 1.0) forView:view];
233 |
234 | CATransform3D rotationAndPerspectiveTransform = CATransform3DIdentity;
235 | rotationAndPerspectiveTransform.m34 = 1.0/800;
236 | CGFloat radians = -90/180.0*M_PI;
237 | rotationAndPerspectiveTransform = CATransform3DRotate(rotationAndPerspectiveTransform, radians, 1.0, 0.0, 0.0);
238 | return rotationAndPerspectiveTransform;
239 | }
240 |
241 | @end
242 |
--------------------------------------------------------------------------------
/CCTextFieldEffectsDemo/DetailViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // DetailViewController.m
3 | // CCTextFieldEffects
4 | //
5 | // Created by Kelvin on 6/25/16.
6 | // Copyright © 2016 Cokile. All rights reserved.
7 | //
8 |
9 | #import "DetailViewController.h"
10 | #import "CCTextFieldEffects.h"
11 |
12 | @interface DetailViewController ()
13 |
14 | @property (nonatomic) CGRect highFrame;
15 | @property (nonatomic) CGRect lowFrame;
16 |
17 | @end
18 |
19 | @implementation DetailViewController
20 |
21 | #pragma mark - Lifecycle
22 | - (void)viewDidLoad {
23 | [super viewDidLoad];
24 |
25 | self.view.backgroundColor = [UIColor colorWithRed:self.red/255 green:self.green/255 blue:self.blue/255 alpha:1];
26 |
27 | self.highFrame = CGRectMake(16, self.navigationController.navigationBar.frame.size.height+80, CGRectGetWidth(self.view.frame)-32, 70);
28 |
29 | self.lowFrame = CGRectMake(16, self.highFrame.origin.y+CGRectGetHeight(self.highFrame)+40, CGRectGetWidth(self.view.frame)-32, 70);
30 | }
31 |
32 | - (void)viewWillAppear:(BOOL)animated {
33 | [super viewWillAppear:animated];
34 |
35 | if ([self.title isEqualToString:@"Akira"]) {
36 | AkiraTextField *tf1 = [[AkiraTextField alloc] initWithFrame:self.highFrame];
37 | tf1.placeholder = @"First Name";
38 | [self.view addSubview:tf1];
39 |
40 | AkiraTextField *tf2 = [[AkiraTextField alloc] initWithFrame:self.lowFrame];
41 | tf2.placeholder = @"Last Name";
42 | [self.view addSubview:tf2];
43 | } else if ([self.title isEqualToString:@"Hoshi"]) {
44 | HoshiTextField *tf1 = [[HoshiTextField alloc] initWithFrame:self.highFrame];
45 | tf1.placeholder = @"First Name";
46 | [self.view addSubview:tf1];
47 |
48 | HoshiTextField *tf2 = [[HoshiTextField alloc] initWithFrame:self.lowFrame];
49 | tf2.placeholder = @"Last Name";
50 | [self.view addSubview:tf2];
51 | } else if ([self.title isEqualToString:@"Isao"]) {
52 | IsaoTextField *tf1 = [[IsaoTextField alloc] initWithFrame:self.highFrame];
53 | tf1.placeholder = @"First Name";
54 | [self.view addSubview:tf1];
55 |
56 | IsaoTextField *tf2 = [[IsaoTextField alloc] initWithFrame:self.lowFrame];
57 | tf2.placeholder = @"Last Name";
58 | [self.view addSubview:tf2];
59 | } else if ([self.title isEqualToString:@"Jiro"]) {
60 | JiroTextField *tf1 = [[JiroTextField alloc] initWithFrame:self.highFrame];
61 | tf1.placeholder = @"First Name";
62 | [self.view addSubview:tf1];
63 |
64 | JiroTextField *tf2 = [[JiroTextField alloc] initWithFrame:self.lowFrame];
65 | tf2.placeholder = @"Last Name";
66 | [self.view addSubview:tf2];
67 | } else if ([self.title isEqualToString:@"Kaede"]) {
68 | KaedeTextField *tf1 = [[KaedeTextField alloc] initWithFrame:CGRectInset(self.highFrame, 0, 7)];
69 | tf1.placeholder = @"First Name";
70 | [self.view addSubview:tf1];
71 |
72 | KaedeTextField *tf2 = [[KaedeTextField alloc] initWithFrame:CGRectInset(self.lowFrame, 0, 7)];
73 | tf2.placeholder = @"Last Name";
74 | [self.view addSubview:tf2];
75 | } else if ([self.title isEqualToString:@"Madoka"]) {
76 | MadokaTextField *tf1 = [[MadokaTextField alloc] initWithFrame:self.highFrame];
77 | tf1.placeholder = @"First Name";
78 | [self.view addSubview:tf1];
79 |
80 | MadokaTextField *tf2 = [[MadokaTextField alloc] initWithFrame:self.lowFrame];
81 | tf2.placeholder = @"Last Name";
82 | [self.view addSubview:tf2];
83 | } else if ([self.title isEqualToString:@"Yoko"]) {
84 | YokoTextField *tf1 = [[YokoTextField alloc] initWithFrame:self.highFrame];
85 | tf1.placeholder = @"First Name";
86 | [self.view addSubview:tf1];
87 |
88 | YokoTextField *tf2 = [[YokoTextField alloc] initWithFrame:self.lowFrame];
89 | tf2.placeholder = @"Last Name";
90 | [self.view addSubview:tf2];
91 | } else if ([self.title isEqualToString:@"Yoshiko"]) {
92 | YoshikoTextField *tf1 = [[YoshikoTextField alloc] initWithFrame:self.highFrame];
93 | tf1.placeholder = @"First Name";
94 | [self.view addSubview:tf1];
95 |
96 | YoshikoTextField *tf2 = [[YoshikoTextField alloc] initWithFrame:self.lowFrame];
97 | tf2.placeholder = @"Last Name";
98 | [self.view addSubview:tf2];
99 | } else if ([self.title isEqualToString:@"Hoshi"]) {
100 | HoshiTextField *tf1 = [[HoshiTextField alloc] initWithFrame:self.highFrame];
101 | tf1.placeholder = @"First Name";
102 | [self.view addSubview:tf1];
103 |
104 | HoshiTextField *tf2 = [[HoshiTextField alloc] initWithFrame:self.lowFrame];
105 | tf2.placeholder = @"Last Name";
106 | [self.view addSubview:tf2];
107 | } else if ([self.title isEqualToString:@"Hideo"]) {
108 | HideoTextField *tf1 = [[HideoTextField alloc] initWithFrame:CGRectInset(self.highFrame, 0, 7)];
109 | tf1.image = [UIImage imageNamed:@"mail.png"];
110 | [self.view addSubview:tf1];
111 |
112 | HideoTextField *tf2 = [[HideoTextField alloc] initWithFrame:CGRectInset(self.lowFrame, 0, 7)];
113 | tf2.image = [UIImage imageNamed:@"user.png"];
114 | [self.view addSubview:tf2];
115 | } else if ([self.title isEqualToString:@"Haruki"]) {
116 | HarukiTextField *tf1 = [[HarukiTextField alloc] initWithFrame:self.highFrame];
117 | tf1.placeholder = @"First Name";
118 | [self.view addSubview:tf1];
119 |
120 | HarukiTextField *tf2 = [[HarukiTextField alloc] initWithFrame:self.lowFrame];
121 | tf2.placeholder = @"Last Name";
122 | [self.view addSubview:tf2];
123 | } else if ([self.title isEqualToString:@"Minoru"]) {
124 | MinoruTextField *tf1 = [[MinoruTextField alloc] initWithFrame:self.highFrame];
125 | tf1.placeholder = @"First Name";
126 | [self.view addSubview:tf1];
127 |
128 | MinoruTextField *tf2 = [[MinoruTextField alloc] initWithFrame:self.lowFrame];
129 | tf2.placeholder = @"Last Name";
130 | [self.view addSubview:tf2];
131 | } else if ([self.title isEqualToString:@"Kyo"]) {
132 | KyoTextField *tf1 = [[KyoTextField alloc] initWithFrame:self.highFrame];
133 | tf1.placeholder = @"First Name";
134 | [self.view addSubview:tf1];
135 |
136 | KyoTextField *tf2 = [[KyoTextField alloc] initWithFrame:self.lowFrame];
137 | tf2.placeholder = @"Last Name";
138 | [self.view addSubview:tf2];
139 | } else if ([self.title isEqualToString:@"Kuro"]) {
140 | KuroTextField *tf1 = [[KuroTextField alloc] initWithFrame:self.highFrame];
141 | tf1.placeholder = @"First Name";
142 | [self.view addSubview:tf1];
143 |
144 | KuroTextField *tf2 = [[KuroTextField alloc] initWithFrame:self.lowFrame];
145 | tf2.placeholder = @"Last Name";
146 | [self.view addSubview:tf2];
147 | } else if ([self.title isEqualToString:@"Ruri"]) {
148 | RuriTextField *tf1 = [[RuriTextField alloc] initWithFrame:self.highFrame];
149 | tf1.placeholder = @"First Name";
150 | [self.view addSubview:tf1];
151 |
152 | RuriTextField *tf2 = [[RuriTextField alloc] initWithFrame:self.lowFrame];
153 | tf2.placeholder = @"Last Name";
154 | [self.view addSubview:tf2];
155 | } else if ([self.title isEqualToString:@"Chisato"]) {
156 | ChisatoTextField *tf1 = [[ChisatoTextField alloc] initWithFrame:self.highFrame];
157 | tf1.placeholder = @"First Name";
158 | [self.view addSubview:tf1];
159 |
160 | ChisatoTextField *tf2 = [[ChisatoTextField alloc] initWithFrame:self.lowFrame];
161 | tf2.placeholder = @"Last Name";
162 | [self.view addSubview:tf2];
163 | } else if ([self.title isEqualToString:@"Manami"]) {
164 | ManamiTextField *tf1 = [[ManamiTextField alloc] initWithFrame:self.highFrame];
165 | tf1.placeholder = @"First Name";
166 | [self.view addSubview:tf1];
167 |
168 | ManamiTextField *tf2 = [[ManamiTextField alloc] initWithFrame:self.lowFrame];
169 | tf2.placeholder = @"Last Name";
170 | [self.view addSubview:tf2];
171 | } else if ([self.title isEqualToString:@"Nariko"]) {
172 | NarikoTextField *tf1 = [[NarikoTextField alloc] initWithFrame:self.highFrame];
173 | tf1.placeholder = @"First Name";
174 | [self.view addSubview:tf1];
175 |
176 | NarikoTextField *tf2 = [[NarikoTextField alloc] initWithFrame:self.lowFrame];
177 | tf2.placeholder = @"Last Name";
178 | [self.view addSubview:tf2];
179 | } else if ([self.title isEqualToString:@"Sae"]) {
180 | SaeTextField *tf1 = [[SaeTextField alloc] initWithFrame:CGRectInset(self.highFrame, 80, 0)];
181 | tf1.placeholder = @"First Name";
182 | [self.view addSubview:tf1];
183 |
184 | SaeTextField *tf2 = [[SaeTextField alloc] initWithFrame:CGRectInset(self.lowFrame, 80, 0)];
185 | tf2.placeholder = @"Last Name";
186 | [self.view addSubview:tf2];
187 | } else if ([self.title isEqualToString:@"Kohana"]) {
188 | KohanaTextField *tf1 = [[KohanaTextField alloc] initWithFrame:CGRectInset(self.highFrame, 0, 7)];
189 | tf1.placeholder = @"Mail";
190 | tf1.image = [UIImage imageNamed:@"mail.png"];
191 | [self.view addSubview:tf1];
192 |
193 | KohanaTextField *tf2 = [[KohanaTextField alloc] initWithFrame:CGRectInset(self.lowFrame, 0, 7)];
194 | tf2.placeholder = @"User Name";
195 | tf2.image = [UIImage imageNamed:@"user.png"];
196 | [self.view addSubview:tf2];
197 | }
198 | }
199 |
200 | #pragma mark - Pirvate methods
201 |
202 |
203 | @end
204 |
--------------------------------------------------------------------------------