11 Commits

Author SHA1 Message Date
Dhaval Thanki a4168519eb - Code optimized 2017-04-07 16:42:33 +05:30
Dhaval Thanki e52d3a5793 - Example updated with keyboard notificaiton 2017-04-07 16:38:28 +05:30
Dhaval Thanki 02fa27c6c9 - Project file updated 2017-04-04 12:36:22 +05:30
Dhaval Thanki b6973166c6 - Deployment target changed 2017-04-04 12:31:02 +05:30
Dhaval Thanki 3b9e4b8408 - Update gitignore 2017-04-04 12:29:13 +05:30
iDhaval 06c95722ed Update .gitignore 2017-04-04 12:22:52 +05:30
iDhaval 1a17b82199 Update .gitignore 2017-04-04 12:20:33 +05:30
Dhaval Thanki b23514f710 - Podfile updated 2017-04-04 12:20:40 +05:30
iDhaval 129d5ebad0 Update README.md 2017-04-04 12:14:19 +05:30
Dhaval Thanki b70402014d - Demo gif Added 2017-04-04 11:00:09 +05:30
Dhaval Thanki 2966fea8f1 - Version updated 2017-04-03 19:25:59 +05:30
10 changed files with 719 additions and 63 deletions
+2 -1
View File
@@ -1 +1,2 @@
*.xcodeproj
_Pods.xcodeproj
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

+1 -1
View File
@@ -9,7 +9,7 @@
Pod::Spec.new do |s|
s.name = 'DTTextField'
s.version = '0.2.0'
s.version = '0.2.1'
s.summary = 'DTTextField is UITextField library.'
s.description = <<-DESC
+64 -54
View File
@@ -10,14 +10,7 @@ import Foundation
import UIKit
public extension String {
func heightWithConstrainedWidth(width: CGFloat, font: UIFont) -> CGFloat {
let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude)
let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [NSFontAttributeName: font], context: nil)
return boundingBox.height
}
var isEmptyStr:Bool{
return self.trimmingCharacters(in: NSCharacterSet.whitespaces).isEmpty
}
@@ -30,15 +23,20 @@ public class DTTextField: UITextField {
fileprivate let paddingX:CGFloat = 5.0
fileprivate let floatingLabelShowAnimationDuration = 0.3
fileprivate let paddingHeight:CGFloat = 10.0
public var dtLayer:CALayer = CALayer()
public var floatPlaceholderColor:UIColor = UIColor.black
public var floatPlaceholderActiveColor:UIColor = UIColor.black
public var errorMessage:String = ""{
didSet{ lblError.text = errorMessage }
}
public var animateFloatPlaceholder:Bool = true
public var hideErrorWhenEditing:Bool = true
public var errorFont = UIFont.systemFont(ofSize: 10.0){
didSet{ invalidateIntrinsicContentSize() }
}
@@ -95,10 +93,6 @@ public class DTTextField: UITextField {
return width - (self.x * 2)
}
fileprivate var floatLabelHeight:CGFloat{
return lblFloatPlaceholder.text!.heightWithConstrainedWidth(width: floatLabelWidth, font: floatPlaceholderFont)
}
fileprivate var placeholderFinal:String{
if let attributed = attributedPlaceholder { return attributed.string }
return placeholder ?? " "
@@ -109,6 +103,8 @@ public class DTTextField: UITextField {
public var showError:Bool = false{
didSet{
guard showError != oldValue else { return }
guard showError else {
hideErrorMessage()
return
@@ -126,6 +122,10 @@ public class DTTextField: UITextField {
}
}
public override var text: String?{
didSet{ self.textFieldTextChanged() }
}
override public var placeholder: String?{
didSet{
@@ -152,8 +152,6 @@ public class DTTextField: UITextField {
commonInit()
}
fileprivate func commonInit() {
dtLayer.cornerRadius = 4.5
@@ -184,10 +182,12 @@ public class DTTextField: UITextField {
}
fileprivate func showErrorMessage(){
let errorHeight = errorMessage.heightWithConstrainedWidth(width: bounds.width, font: errorFont)
lblError.text = errorMessage
lblError.isHidden = false
lblError.frame = CGRect(x: paddingX, y: 0, width: bounds.width - (paddingX * 2), height: errorHeight)
let boundWithPadding = CGSize(width: bounds.width - (x * 2), height: bounds.height)
let errorLabelSize = lblError.sizeThatFits(boundWithPadding)
lblError.frame = CGRect(x: paddingX, y: 0, width: errorLabelSize.width, height: errorLabelSize.height)
invalidateIntrinsicContentSize()
}
@@ -198,68 +198,72 @@ public class DTTextField: UITextField {
invalidateIntrinsicContentSize()
}
fileprivate func showFloatingLabel() {
fileprivate func showFloatingLabel(_ animated:Bool) {
let animations:(()->()) = {
self.lblFloatPlaceholder.alpha = 1.0
self.lblFloatPlaceholder.frame = CGRect(x: self.x, y: self.paddingYFloatLabel, width: self.floatLabelWidth, height: self.floatLabelHeight)
self.lblFloatPlaceholder.frame = CGRect(x: self.lblFloatPlaceholder.frame.origin.x, y: self.paddingYFloatLabel, width: self.lblFloatPlaceholder.bounds.size.width, height: self.lblFloatPlaceholder.bounds.size.height)
}
UIView.animate(withDuration: floatingLabelShowAnimationDuration,
delay: 0.0,
options: [.beginFromCurrentState,.curveEaseOut],
animations: animations){ status in
DispatchQueue.main.async {
self.layoutIfNeeded()
}
if animated && animateFloatPlaceholder {
UIView.animate(withDuration: floatingLabelShowAnimationDuration,
delay: 0.0,
options: [.beginFromCurrentState,.curveEaseOut],
animations: animations){ status in
DispatchQueue.main.async {
self.layoutIfNeeded()
}
}
}else{
animations()
}
}
fileprivate func hideFlotingLabel() {
fileprivate func hideFlotingLabel(_ animated:Bool) {
let animations:(()->()) = {
self.lblFloatPlaceholder.alpha = 0.0
let labelHeight = self.floatLabelHeight
self.lblFloatPlaceholder.frame = CGRect(x: self.x, y: labelHeight, width: self.floatLabelWidth, height: labelHeight)
self.lblFloatPlaceholder.frame = CGRect(x: self.lblFloatPlaceholder.frame.origin.x, y: self.lblFloatPlaceholder.font.lineHeight, width: self.lblFloatPlaceholder.bounds.size.width, height: self.lblFloatPlaceholder.bounds.size.height)
}
UIView.animate(withDuration: floatingLabelShowAnimationDuration,
delay: 0.0,
options: [.beginFromCurrentState,.curveEaseOut],
animations: animations){ status in
DispatchQueue.main.async {
self.layoutIfNeeded()
}
if animated && animateFloatPlaceholder {
UIView.animate(withDuration: floatingLabelShowAnimationDuration,
delay: 0.0,
options: [.beginFromCurrentState,.curveEaseOut],
animations: animations){ status in
DispatchQueue.main.async {
self.layoutIfNeeded()
}
}
}else{
animations()
}
}
fileprivate func insetRectForEmptyBounds(rect:CGRect) -> CGRect{
if showError {
let topInset = ((rect.size.height - lblError.bounds.size.height - paddingYErrorLabel) / 2.0) - (ceil(font!.lineHeight) / 2.0)
let textY = (rect.height / 2.0) - (ceil(font!.lineHeight) / 2.0) - topInset
return CGRect(x: x, y: -ceil(textY), width: rect.size.width, height: rect.size.height)
}else{
return CGRect(x: x, y: 0.0, width: rect.width, height: rect.height)
}
guard showError else { return CGRect(x: x, y: 0, width: rect.width, height: rect.height) }
let topInset = (rect.size.height - lblError.bounds.size.height - paddingYErrorLabel - ceil(font!.lineHeight)) / 2.0
let textY = ((rect.height - ceil(font!.lineHeight)) / 2.0) - topInset
return CGRect(x: x, y: -ceil(textY), width: rect.size.width, height: rect.size.height)
}
fileprivate func insetRectForBounds(rect:CGRect) -> CGRect {
guard !lblFloatPlaceholder.text!.isEmptyStr else {
return insetRectForEmptyBounds(rect: rect)
}
guard !lblFloatPlaceholder.text!.isEmptyStr else { return insetRectForEmptyBounds(rect: rect) }
if let text = text,text.isEmptyStr {
return insetRectForEmptyBounds(rect: rect)
}else{
let topInset = (paddingYFloatLabel * 2) + lblFloatPlaceholder.bounds.size.height
let textY = (rect.height / 2.0) - (ceil(font!.lineHeight) / 2.0) - topInset
let topInset = paddingYFloatLabel + lblFloatPlaceholder.bounds.size.height + (paddingHeight / 2.0)
let textOriginalY = (rect.height - font!.lineHeight) / 2.0
let textY = textOriginalY - topInset
return CGRect(x: x, y: -ceil(textY), width: rect.size.width, height: rect.size.height)
}
}
@objc fileprivate func textFieldTextChanged(){
guard showError else { return }
guard hideErrorWhenEditing && showError else { return }
showError = false
}
@@ -268,15 +272,15 @@ public class DTTextField: UITextField {
let textFieldIntrinsicContentSize = super.intrinsicContentSize
lblFloatPlaceholder.sizeToFit()
lblError.sizeToFit()
if showError {
lblFloatPlaceholder.sizeToFit()
return CGSize(width: textFieldIntrinsicContentSize.width,
height: textFieldIntrinsicContentSize.height + (paddingYFloatLabel * 3) + paddingYErrorLabel + lblFloatPlaceholder.bounds.size.height + lblError.bounds.size.height)
height: textFieldIntrinsicContentSize.height + paddingYFloatLabel + paddingYErrorLabel + lblFloatPlaceholder.bounds.size.height + lblError.bounds.size.height + paddingHeight)
}else{
return CGSize(width: textFieldIntrinsicContentSize.width,
height: textFieldIntrinsicContentSize.height + (paddingYFloatLabel * 3) + lblFloatPlaceholder.bounds.size.height)
height: textFieldIntrinsicContentSize.height + paddingYFloatLabel + lblFloatPlaceholder.bounds.size.height + paddingHeight)
}
}
@@ -331,12 +335,18 @@ public class DTTextField: UITextField {
height: bounds.height)
}
let floatingLabelSize = lblFloatPlaceholder.sizeThatFits(lblFloatPlaceholder.superview!.bounds.size)
lblFloatPlaceholder.frame = CGRect(x: x, y: lblFloatPlaceholder.frame.origin.y,
width: floatingLabelSize.width,
height: floatingLabelSize.height)
lblFloatPlaceholder.textColor = isFirstResponder ? floatPlaceholderActiveColor : floatPlaceholderColor
if let enteredText = text,!enteredText.isEmptyStr{
showFloatingLabel()
showFloatingLabel(isFirstResponder)
}else{
hideFlotingLabel()
hideFlotingLabel(isFirstResponder)
}
}
}
+1 -1
View File
@@ -1,3 +1,3 @@
/DTTextField.xcworkspace/
/Pods/
*.lock
/DTTextField.xcworkspace/
@@ -0,0 +1,579 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD51AFB9204008FA782 /* AppDelegate.swift */; };
607FACD81AFB9204008FA782 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD71AFB9204008FA782 /* ViewController.swift */; };
607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 607FACD91AFB9204008FA782 /* Main.storyboard */; };
607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDC1AFB9204008FA782 /* Images.xcassets */; };
607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; };
607FACEC1AFB9204008FA782 /* Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACEB1AFB9204008FA782 /* Tests.swift */; };
7CBDD22C174BE4A9D62F0838 /* Pods_DTTextField_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F0D037025A52EC73A143FA2 /* Pods_DTTextField_Example.framework */; };
F3B670DD4D60B75D53BF34AB /* Pods_DTTextField_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A73FFAC2C238F6E99F680420 /* Pods_DTTextField_Tests.framework */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
607FACE61AFB9204008FA782 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 607FACC81AFB9204008FA782 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 607FACCF1AFB9204008FA782;
remoteInfo = DTTextField;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
060B7103A3E600F8B2BD7D22 /* Pods-DTTextField_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DTTextField_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-DTTextField_Example/Pods-DTTextField_Example.debug.xcconfig"; sourceTree = "<group>"; };
2C22D21F3A2AE3ADC3442B4C /* Pods-DTTextField_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DTTextField_Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-DTTextField_Tests/Pods-DTTextField_Tests.release.xcconfig"; sourceTree = "<group>"; };
4F0D037025A52EC73A143FA2 /* Pods_DTTextField_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_DTTextField_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; };
5B7FD7AC92A60AFDB02B68F9 /* Pods-DTTextField_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DTTextField_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-DTTextField_Example/Pods-DTTextField_Example.release.xcconfig"; sourceTree = "<group>"; };
607FACD01AFB9204008FA782 /* DTTextField_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DTTextField_Example.app; sourceTree = BUILT_PRODUCTS_DIR; };
607FACD41AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
607FACD51AFB9204008FA782 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
607FACD71AFB9204008FA782 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
607FACDA1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
607FACDC1AFB9204008FA782 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
607FACDF1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
607FACE51AFB9204008FA782 /* DTTextField_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DTTextField_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
607FACEA1AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
607FACEB1AFB9204008FA782 /* Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests.swift; sourceTree = "<group>"; };
9DCF83E02A68CA6BD5E2E2CF /* Pods-DTTextField_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DTTextField_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-DTTextField_Tests/Pods-DTTextField_Tests.debug.xcconfig"; sourceTree = "<group>"; };
A73FFAC2C238F6E99F680420 /* Pods_DTTextField_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_DTTextField_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
607FACCD1AFB9204008FA782 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
7CBDD22C174BE4A9D62F0838 /* Pods_DTTextField_Example.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
607FACE21AFB9204008FA782 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
F3B670DD4D60B75D53BF34AB /* Pods_DTTextField_Tests.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
0AA3E72CF6526EF5C790DC68 /* Pods */ = {
isa = PBXGroup;
children = (
060B7103A3E600F8B2BD7D22 /* Pods-DTTextField_Example.debug.xcconfig */,
5B7FD7AC92A60AFDB02B68F9 /* Pods-DTTextField_Example.release.xcconfig */,
9DCF83E02A68CA6BD5E2E2CF /* Pods-DTTextField_Tests.debug.xcconfig */,
2C22D21F3A2AE3ADC3442B4C /* Pods-DTTextField_Tests.release.xcconfig */,
);
name = Pods;
sourceTree = "<group>";
};
3D2E65FC1F3555D9D00626A6 /* Frameworks */ = {
isa = PBXGroup;
children = (
4F0D037025A52EC73A143FA2 /* Pods_DTTextField_Example.framework */,
A73FFAC2C238F6E99F680420 /* Pods_DTTextField_Tests.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
607FACC71AFB9204008FA782 = {
isa = PBXGroup;
children = (
607FACD21AFB9204008FA782 /* Example for DTTextField */,
607FACE81AFB9204008FA782 /* Tests */,
607FACD11AFB9204008FA782 /* Products */,
0AA3E72CF6526EF5C790DC68 /* Pods */,
3D2E65FC1F3555D9D00626A6 /* Frameworks */,
);
sourceTree = "<group>";
};
607FACD11AFB9204008FA782 /* Products */ = {
isa = PBXGroup;
children = (
607FACD01AFB9204008FA782 /* DTTextField_Example.app */,
607FACE51AFB9204008FA782 /* DTTextField_Tests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
607FACD21AFB9204008FA782 /* Example for DTTextField */ = {
isa = PBXGroup;
children = (
607FACD51AFB9204008FA782 /* AppDelegate.swift */,
607FACD71AFB9204008FA782 /* ViewController.swift */,
607FACD91AFB9204008FA782 /* Main.storyboard */,
607FACDC1AFB9204008FA782 /* Images.xcassets */,
607FACDE1AFB9204008FA782 /* LaunchScreen.xib */,
607FACD31AFB9204008FA782 /* Supporting Files */,
);
name = "Example for DTTextField";
path = DTTextField;
sourceTree = "<group>";
};
607FACD31AFB9204008FA782 /* Supporting Files */ = {
isa = PBXGroup;
children = (
607FACD41AFB9204008FA782 /* Info.plist */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
607FACE81AFB9204008FA782 /* Tests */ = {
isa = PBXGroup;
children = (
607FACEB1AFB9204008FA782 /* Tests.swift */,
607FACE91AFB9204008FA782 /* Supporting Files */,
);
path = Tests;
sourceTree = "<group>";
};
607FACE91AFB9204008FA782 /* Supporting Files */ = {
isa = PBXGroup;
children = (
607FACEA1AFB9204008FA782 /* Info.plist */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
607FACCF1AFB9204008FA782 /* DTTextField_Example */ = {
isa = PBXNativeTarget;
buildConfigurationList = 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "DTTextField_Example" */;
buildPhases = (
8D9A9A1AA162783013888FFF /* [CP] Check Pods Manifest.lock */,
607FACCC1AFB9204008FA782 /* Sources */,
607FACCD1AFB9204008FA782 /* Frameworks */,
607FACCE1AFB9204008FA782 /* Resources */,
EEDC89F8840910979DA52450 /* [CP] Embed Pods Frameworks */,
11408D7F6D7029447C5C8ADF /* [CP] Copy Pods Resources */,
);
buildRules = (
);
dependencies = (
);
name = DTTextField_Example;
productName = DTTextField;
productReference = 607FACD01AFB9204008FA782 /* DTTextField_Example.app */;
productType = "com.apple.product-type.application";
};
607FACE41AFB9204008FA782 /* DTTextField_Tests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "DTTextField_Tests" */;
buildPhases = (
30328B87BF196F8639A96E90 /* [CP] Check Pods Manifest.lock */,
607FACE11AFB9204008FA782 /* Sources */,
607FACE21AFB9204008FA782 /* Frameworks */,
607FACE31AFB9204008FA782 /* Resources */,
E8431CE4674170545D9AD7F5 /* [CP] Embed Pods Frameworks */,
2A1C3BCADED2085C775AC86D /* [CP] Copy Pods Resources */,
);
buildRules = (
);
dependencies = (
607FACE71AFB9204008FA782 /* PBXTargetDependency */,
);
name = DTTextField_Tests;
productName = Tests;
productReference = 607FACE51AFB9204008FA782 /* DTTextField_Tests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
607FACC81AFB9204008FA782 /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0720;
LastUpgradeCheck = 0820;
ORGANIZATIONNAME = CocoaPods;
TargetAttributes = {
607FACCF1AFB9204008FA782 = {
CreatedOnToolsVersion = 6.3.1;
LastSwiftMigration = 0820;
};
607FACE41AFB9204008FA782 = {
CreatedOnToolsVersion = 6.3.1;
LastSwiftMigration = 0820;
TestTargetID = 607FACCF1AFB9204008FA782;
};
};
};
buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "DTTextField" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 607FACC71AFB9204008FA782;
productRefGroup = 607FACD11AFB9204008FA782 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
607FACCF1AFB9204008FA782 /* DTTextField_Example */,
607FACE41AFB9204008FA782 /* DTTextField_Tests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
607FACCE1AFB9204008FA782 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */,
607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */,
607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
607FACE31AFB9204008FA782 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
11408D7F6D7029447C5C8ADF /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-DTTextField_Example/Pods-DTTextField_Example-resources.sh\"\n";
showEnvVarsInLog = 0;
};
2A1C3BCADED2085C775AC86D /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-DTTextField_Tests/Pods-DTTextField_Tests-resources.sh\"\n";
showEnvVarsInLog = 0;
};
30328B87BF196F8639A96E90 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Check Pods Manifest.lock";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
8D9A9A1AA162783013888FFF /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Check Pods Manifest.lock";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
E8431CE4674170545D9AD7F5 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-DTTextField_Tests/Pods-DTTextField_Tests-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
EEDC89F8840910979DA52450 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-DTTextField_Example/Pods-DTTextField_Example-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
607FACCC1AFB9204008FA782 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
607FACD81AFB9204008FA782 /* ViewController.swift in Sources */,
607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
607FACE11AFB9204008FA782 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
607FACEC1AFB9204008FA782 /* Tests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
607FACE71AFB9204008FA782 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 607FACCF1AFB9204008FA782 /* DTTextField_Example */;
targetProxy = 607FACE61AFB9204008FA782 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
607FACD91AFB9204008FA782 /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
607FACDA1AFB9204008FA782 /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
607FACDE1AFB9204008FA782 /* LaunchScreen.xib */ = {
isa = PBXVariantGroup;
children = (
607FACDF1AFB9204008FA782 /* Base */,
);
name = LaunchScreen.xib;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
607FACED1AFB9204008FA782 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
607FACEE1AFB9204008FA782 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
607FACF01AFB9204008FA782 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 060B7103A3E600F8B2BD7D22 /* Pods-DTTextField_Example.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = DTTextField/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MODULE_NAME = ExampleApp;
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
name = Debug;
};
607FACF11AFB9204008FA782 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 5B7FD7AC92A60AFDB02B68F9 /* Pods-DTTextField_Example.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
INFOPLIST_FILE = DTTextField/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
MODULE_NAME = ExampleApp;
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
name = Release;
};
607FACF31AFB9204008FA782 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9DCF83E02A68CA6BD5E2E2CF /* Pods-DTTextField_Tests.debug.xcconfig */;
buildSettings = {
FRAMEWORK_SEARCH_PATHS = (
"$(SDKROOT)/Developer/Library/Frameworks",
"$(inherited)",
);
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
INFOPLIST_FILE = Tests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
name = Debug;
};
607FACF41AFB9204008FA782 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 2C22D21F3A2AE3ADC3442B4C /* Pods-DTTextField_Tests.release.xcconfig */;
buildSettings = {
FRAMEWORK_SEARCH_PATHS = (
"$(SDKROOT)/Developer/Library/Frameworks",
"$(inherited)",
);
INFOPLIST_FILE = Tests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "DTTextField" */ = {
isa = XCConfigurationList;
buildConfigurations = (
607FACED1AFB9204008FA782 /* Debug */,
607FACEE1AFB9204008FA782 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "DTTextField_Example" */ = {
isa = XCConfigurationList;
buildConfigurations = (
607FACF01AFB9204008FA782 /* Debug */,
607FACF11AFB9204008FA782 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "DTTextField_Tests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
607FACF31AFB9204008FA782 /* Debug */,
607FACF41AFB9204008FA782 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 607FACC81AFB9204008FA782 /* Project object */;
}
@@ -4,7 +4,6 @@
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
@@ -108,6 +107,7 @@
</view>
<navigationItem key="navigationItem" id="W1x-bm-hbZ"/>
<connections>
<outlet property="scrollView" destination="3qx-l3-jfU" id="Wim-19-5FL"/>
<outlet property="txtConfirmPassword" destination="zBn-BA-f2Y" id="kBp-NH-lSI"/>
<outlet property="txtEmail" destination="6gk-3f-Yz6" id="0vh-rG-4OR"/>
<outlet property="txtFirstName" destination="LZk-sC-XSt" id="gxg-Mj-Ljm"/>
+22
View File
@@ -11,6 +11,7 @@ import DTTextField
class ViewController: UIViewController {
@IBOutlet weak var scrollView: UIScrollView!
@IBOutlet weak var txtFirstName: DTTextField!
@IBOutlet weak var txtLastName: DTTextField!
@IBOutlet weak var txtEmail: DTTextField!
@@ -37,6 +38,19 @@ class ViewController: UIViewController {
// Do any additional setup after loading the view, typically from a nib.
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(notification:)), name: .UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(notification:)), name: .UIKeyboardWillHide, object: nil)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillShow, object: nil)
NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillHide, object: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
@@ -67,6 +81,14 @@ class ViewController: UIViewController {
// MARK: User Define Methods
extension ViewController{
func keyboardWillShow(notification:Notification) {
guard let keyboardHeight = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue else { return }
scrollView.contentInset = UIEdgeInsetsMake(0, 0, keyboardHeight.height, 0)
}
func keyboardWillHide(notification:Notification) {
scrollView.contentInset = .zero
}
func validateData() -> Bool {
+1 -1
View File
@@ -1,7 +1,7 @@
use_frameworks!
target 'DTTextField_Example' do
pod 'DTTextField', :path => '../'
pod 'DTTextField'
target 'DTTextField_Tests' do
inherit! :search_paths
+48 -4
View File
@@ -1,16 +1,27 @@
# DTTextField
![Version](https://img.shields.io/badge/Version-0.1.0-green.svg)
![Version](https://img.shields.io/badge/Pod-V0.2.1-green.svg)
![License](https://img.shields.io/github/license/mashape/apistatus.svg)
![Platform](https://img.shields.io/badge/Swift-3.0-orange.svg)
![Platform](https://img.shields.io/badge/Language-Swift_3.0-orange.svg)
![Xcode](https://img.shields.io/badge/Xcode-8.0-blue.svg)
![Demo](https://github.com/iDhaval/DTTextField/blob/master/DTTextField.gif?raw=true)
## Introduction
DTTextField is a UITextField library with floating placeholder and error label.
Floating placeholder inspired from [JVFloatLabeledTextField](https://github.com/jverdi/JVFloatLabeledTextField) :+1:.
## Example
To run the example project, clone the repo, and run `pod install` from the Example directory first.
## Requirements
* Xcode 8.0
* Swift 3.0
## Installation
DTTextField is available through [CocoaPods](http://cocoapods.org). To install
@@ -20,10 +31,43 @@ it, simply add the following line to your Podfile:
pod 'DTTextField'
```
## Usage
1. Open a storyboard or Xib file.
2. Drag and drop a `UITextField` to a ViewController.
3. In Identity Inspector, replace the class from `UITextField` to `DTTextField` and the module to `DTTextField`.
## Properties
| Property name | Type | Remark |
| ------------- |------------- | ----- |
| errorMessage | String | Add your error message to this property|
| errorFont | UIFont | Change font of error text |
| showError | Bool | Use to toggle error message|
| paddingYErrorLabel | CGFloat | Error text top padding |
| floatPlaceholderColor | UIColor | To change float placeholder color |
| floatPlaceholderActiveColor | UIColor | To change float placeholder color while TextField is active(First responder)|
| floatPlaceholderFont | UIFont | Change font of float placeholder |
| paddingYFloatLabel | CGFloat | float placeholder top padding |
| placeholderColor | UIColor | change placeholder color |
### Important Properties
| Property name | Type | Remark |
| ------------- |------------- | ----- |
| dtLayer | CALayer | If you want to formate DTTextField than use dtLayer property instead of layer |
| borderColor | UIColor | Change border color of DTTextField |
| canShowBorder | Bool | Toggle border of DTTextField |
## TODO
* Add inbuilt validation
## Author
Dhaval Thanki
Dhaval Thanki :sunglasses:
## License
DTTextField is available under the MIT license. See the LICENSE file for more info.
```DTTextField``` is available under the MIT license. See the [LICENSE](https://github.com/iDhaval/DTTextField/blob/master/LICENSE) file for more info.