Compare commits

..

No commits in common. "master" and "0.1.9" have entirely different histories.

8 changed files with 146 additions and 257 deletions

View File

@ -1 +0,0 @@
4.0

View File

@ -1,5 +0,0 @@
# Changelog
## 0.2.0
- **Fix**: date setting after picker presented.

View File

@ -12,7 +12,7 @@
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
12D59B30305289F1A0BAB148 /* UIAnimatedTextField.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = UIAnimatedTextField.podspec; path = ../UIAnimatedTextField.podspec; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 12D59B30305289F1A0BAB148 /* UIAnimatedTextField.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = UIAnimatedTextField.podspec; path = ../UIAnimatedTextField.podspec; sourceTree = "<group>"; };
3023902FA98A29EAE27CE743 /* Pods_UIAnimatedTextField_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_UIAnimatedTextField_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 3023902FA98A29EAE27CE743 /* Pods_UIAnimatedTextField_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_UIAnimatedTextField_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
305D07AC233331112B594740 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = "<group>"; }; 305D07AC233331112B594740 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = "<group>"; };
3EE19024E4B841DD8F1FEA61 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = "<group>"; }; 3EE19024E4B841DD8F1FEA61 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = "<group>"; };
@ -110,6 +110,7 @@
607FACE21AFB9204008FA782 /* Frameworks */, 607FACE21AFB9204008FA782 /* Frameworks */,
607FACE31AFB9204008FA782 /* Resources */, 607FACE31AFB9204008FA782 /* Resources */,
4EB68626CEDBCD2943AF13ED /* [CP] Embed Pods Frameworks */, 4EB68626CEDBCD2943AF13ED /* [CP] Embed Pods Frameworks */,
AFE96432D6D5B8E3FF680C55 /* [CP] Copy Pods Resources */,
); );
buildRules = ( buildRules = (
); );
@ -127,12 +128,12 @@
isa = PBXProject; isa = PBXProject;
attributes = { attributes = {
LastSwiftUpdateCheck = 0720; LastSwiftUpdateCheck = 0720;
LastUpgradeCheck = 1000; LastUpgradeCheck = 0820;
ORGANIZATIONNAME = CocoaPods; ORGANIZATIONNAME = CocoaPods;
TargetAttributes = { TargetAttributes = {
607FACE41AFB9204008FA782 = { 607FACE41AFB9204008FA782 = {
CreatedOnToolsVersion = 6.3.1; CreatedOnToolsVersion = 6.3.1;
LastSwiftMigration = 0910; LastSwiftMigration = 0820;
TestTargetID = 607FACCF1AFB9204008FA782; TestTargetID = 607FACCF1AFB9204008FA782;
}; };
}; };
@ -172,34 +173,43 @@
files = ( files = (
); );
inputPaths = ( inputPaths = (
"${SRCROOT}/Pods/Target Support Files/Pods-UIAnimatedTextField_Tests/Pods-UIAnimatedTextField_Tests-frameworks.sh",
"${BUILT_PRODUCTS_DIR}/UIAnimatedTextField/UIAnimatedTextField.framework",
); );
name = "[CP] Embed Pods Frameworks"; name = "[CP] Embed Pods Frameworks";
outputPaths = ( outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/UIAnimatedTextField.framework",
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-UIAnimatedTextField_Tests/Pods-UIAnimatedTextField_Tests-frameworks.sh\"\n"; shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-UIAnimatedTextField_Tests/Pods-UIAnimatedTextField_Tests-frameworks.sh\"\n";
showEnvVarsInLog = 0; showEnvVarsInLog = 0;
}; };
AFE96432D6D5B8E3FF680C55 /* [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-UIAnimatedTextField_Tests/Pods-UIAnimatedTextField_Tests-resources.sh\"\n";
showEnvVarsInLog = 0;
};
D458C72BE72F89E2185E2C11 /* [CP] Check Pods Manifest.lock */ = { D458C72BE72F89E2185E2C11 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
); );
inputPaths = ( inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
); );
name = "[CP] Check Pods Manifest.lock"; name = "[CP] Check Pods Manifest.lock";
outputPaths = ( outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-UIAnimatedTextField_Tests-checkManifestLockResult.txt",
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/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# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 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; showEnvVarsInLog = 0;
}; };
/* End PBXShellScriptBuildPhase section */ /* End PBXShellScriptBuildPhase section */
@ -224,22 +234,14 @@
CLANG_CXX_LIBRARY = "libc++"; CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@ -279,22 +281,14 @@
CLANG_CXX_LIBRARY = "libc++"; CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
@ -332,8 +326,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_SWIFT3_OBJC_INFERENCE = Default; SWIFT_VERSION = 3.0;
SWIFT_VERSION = 4.2;
}; };
name = Debug; name = Debug;
}; };
@ -346,8 +339,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_SWIFT3_OBJC_INFERENCE = Default; SWIFT_VERSION = 3.0;
SWIFT_VERSION = 4.2;
}; };
name = Release; name = Release;
}; };

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Scheme <Scheme
LastUpgradeVersion = "1000" LastUpgradeVersion = "0820"
version = "1.3"> version = "1.3">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@ -1,6 +1,6 @@
Pod::Spec.new do |s| Pod::Spec.new do |s|
s.name = 'UIAnimatedTextField' s.name = 'UIAnimatedTextField'
s.version = '0.3.0' s.version = '0.1.9'
s.summary = 'UITextField with animated placeholder' s.summary = 'UITextField with animated placeholder'
s.description = <<-DESC s.description = <<-DESC
This custom control can be used as a replacement for UITextField. It comes with 5 different text types: simple, password, url, tappable, date. This custom control can be used as a replacement for UITextField. It comes with 5 different text types: simple, password, url, tappable, date.

View File

@ -24,32 +24,9 @@
import Foundation import Foundation
public enum EditableActionType { public class EditableTextField: UITextField {
case selectAll
case select
case cut
case copy
case paste
public static let allActions: [EditableActionType] = [.selectAll, .select, .cut, .paste, .copy] var getType: (() -> TextType?)?
}
open class EditableTextField: UITextField {
/// Actions, that will be disabled for this textField.
/// By default no actions are disabled.
open var disabledActions: [EditableActionType] = []
/// Allows to disable moving cursor for user
open var pinCursorToEnd: Bool = false
open var getType: (() -> TextType?)?
// MARK: - Private
private var disabledSelectors: [Selector] {
return disabledActions.map { selector(from: $0) }
}
private let menuSelectors = [ private let menuSelectors = [
#selector(selectAll(_:)), #selector(selectAll(_:)),
@ -59,13 +36,7 @@ open class EditableTextField: UITextField {
#selector(paste(_:)) #selector(paste(_:))
] ]
// MARK: - Overriden override public func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
override open func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
if disabledSelectors.contains(action) {
return false
}
guard let type = getType?() else { guard let type = getType?() else {
return super.canPerformAction(action, withSender: sender) return super.canPerformAction(action, withSender: sender)
} }
@ -79,7 +50,7 @@ open class EditableTextField: UITextField {
return super.canPerformAction(action, withSender: sender) return super.canPerformAction(action, withSender: sender)
} }
override open func caretRect(for position: UITextPosition) -> CGRect { override public func caretRect(for position: UITextPosition) -> CGRect {
guard let type = getType?() else { guard let type = getType?() else {
return super.caretRect(for: position) return super.caretRect(for: position)
} }
@ -91,32 +62,4 @@ open class EditableTextField: UITextField {
return super.caretRect(for: position) return super.caretRect(for: position)
} }
override open func closestPosition(to point: CGPoint) -> UITextPosition? {
if pinCursorToEnd {
return endOfDocument
}
return super.closestPosition(to: point)
}
}
// MARK: - Private extensions
private extension UITextField {
func selector(from actionTyoe: EditableActionType) -> Selector {
switch actionTyoe {
case .selectAll:
return #selector(selectAll(_:))
case .select:
return #selector(select(_:))
case .cut:
return #selector(cut(_:))
case .copy:
return #selector(copy(_:))
case .paste:
return #selector(paste(_:))
}
}
} }

View File

@ -97,16 +97,8 @@ open class UIAnimatedTextField: UIView {
} }
} }
@IBInspectable public var placeholderTopColor: UIColor = UIColor.gray { @IBInspectable public var placeholderTopColor: UIColor = UIColor.gray
didSet { @IBInspectable public var placeholderBottomColor: UIColor = UIColor.gray
setState(toState: state)
}
}
@IBInspectable public var placeholderBottomColor: UIColor = UIColor.gray {
didSet {
setState(toState: state)
}
}
@IBInspectable public var enteredTextColor: UIColor { @IBInspectable public var enteredTextColor: UIColor {
get { return textField.textColor ?? UIColor.black } get { return textField.textColor ?? UIColor.black }
@ -194,21 +186,14 @@ open class UIAnimatedTextField: UIView {
} }
} }
@objc public dynamic var selectedDate: Date? public var selectedDate: Date?
public var dateFormat: String = Constants.defaultDateFormat public var dateFormat: String = Constants.defaultDateFormat
public var doneTitle: String = Constants.done { public var doneTitle: String = Constants.done {
didSet { didSet {
textField.inputAccessoryView = getDateInputAccessoryView() textField.inputAccessoryView = getDateInputAccessoryView()
} }
} }
public var doneTitleColor: UIColor = .black {
didSet {
textField.inputAccessoryView = getDateInputAccessoryView()
}
}
// MARK: - Static Properties // MARK: - Static Properties
static public let animationDuration: TimeInterval = 0.3 static public let animationDuration: TimeInterval = 0.3
@ -223,7 +208,7 @@ open class UIAnimatedTextField: UIView {
private var state: AnimatedTextFieldState { private var state: AnimatedTextFieldState {
var state: AnimatedTextFieldState = .placeholder var state: AnimatedTextFieldState = .placeholder
if textField.text?.count ?? 0 > 0 || textField.isFirstResponder { if textField.text?.characters.count ?? 0 > 0 || textField.isFirstResponder {
state = .text state = .text
} }
@ -339,7 +324,7 @@ open class UIAnimatedTextField: UIView {
// MARK: - Animation // MARK: - Animation
public func setState(toState state: AnimatedTextFieldState, duration: TimeInterval = 0) { public func setState(toState state: AnimatedTextFieldState, duration: TimeInterval) {
UIView.animate( UIView.animate(
withDuration: duration, withDuration: duration,
delay: 0, delay: 0,
@ -349,14 +334,8 @@ open class UIAnimatedTextField: UIView {
return return
} }
if strongSelf.isLeftTextAlignment {
strongSelf.placeholderLabel.transform = strongSelf.placeholderLabelTransform(state: state)
strongSelf.placeholderLabel.frame = strongSelf.placeholderLabelFrame(state: state)
} else {
strongSelf.placeholderLabel.frame = strongSelf.placeholderLabelFrame(state: state) strongSelf.placeholderLabel.frame = strongSelf.placeholderLabelFrame(state: state)
strongSelf.placeholderLabel.transform = strongSelf.placeholderLabelTransform(state: state) strongSelf.placeholderLabel.transform = strongSelf.placeholderLabelTransform(state: state)
}
switch state { switch state {
case .placeholder: case .placeholder:
strongSelf.placeholderLabel.textColor = strongSelf.placeholderBottomColor strongSelf.placeholderLabel.textColor = strongSelf.placeholderBottomColor
@ -430,7 +409,7 @@ open class UIAnimatedTextField: UIView {
datePicker.timeZone = TimeZone(secondsFromGMT: 0) datePicker.timeZone = TimeZone(secondsFromGMT: 0)
datePicker.datePickerMode = .date datePicker.datePickerMode = .date
datePicker.backgroundColor = UIColor.white datePicker.backgroundColor = UIColor.white
datePicker.setDate(selectedDate ?? currentDate, animated: true) datePicker.setDate(currentDate, animated: true)
datePicker.maximumDate = currentDate datePicker.maximumDate = currentDate
datePicker.addTarget(self, action: #selector(datePickerValueChanged(_:)), for: .valueChanged) datePicker.addTarget(self, action: #selector(datePickerValueChanged(_:)), for: .valueChanged)
@ -438,7 +417,8 @@ open class UIAnimatedTextField: UIView {
} }
@objc private func datePickerValueChanged(_ datePicker: UIDatePicker) { @objc private func datePickerValueChanged(_ datePicker: UIDatePicker) {
updateText(from: datePicker) selectedDate = datePicker.date
text = datePicker.date.toString(withFormat: dateFormat)
} }
private func getDateInputAccessoryView() -> UIView { private func getDateInputAccessoryView() -> UIView {
@ -453,25 +433,17 @@ open class UIAnimatedTextField: UIView {
target: self, target: self,
action: #selector(datePickerDoneAction)) action: #selector(datePickerDoneAction))
let attributes = [ let attributes = [
NSAttributedString.Key.foregroundColor: doneTitleColor NSForegroundColorAttributeName: UIColor.black
] ]
doneItem.setTitleTextAttributes(attributes, for: .normal) doneItem.setTitleTextAttributes(attributes, for: .normal)
toolbar.setItems([spacerItem, doneItem], animated: false) toolbar.items = [spacerItem, doneItem]
return toolbar return toolbar
} }
fileprivate func updateText(from datePicker: UIDatePicker) {
selectedDate = datePicker.date
text = datePicker.date.toString(withFormat: dateFormat)
}
@objc private func datePickerDoneAction() { @objc private func datePickerDoneAction() {
if let datePicker = textField.inputView as? UIDatePicker {
updateText(from: datePicker)
}
textField.resignFirstResponder() textField.resignFirstResponder()
} }
@ -496,7 +468,7 @@ extension UIAnimatedTextField: UITextFieldDelegate {
} }
open func textFieldDidBeginEditing(_ textField: UITextField) { open func textFieldDidBeginEditing(_ textField: UITextField) {
if textField.text?.count ?? 0 == 0 { if textField.text?.characters.count ?? 0 == 0 {
setState(toState: .text, duration: UIAnimatedTextField.animationDuration) setState(toState: .text, duration: UIAnimatedTextField.animationDuration)
} }
@ -520,14 +492,10 @@ extension UIAnimatedTextField: UITextFieldDelegate {
} }
open func textFieldDidEndEditing(_ textField: UITextField) { open func textFieldDidEndEditing(_ textField: UITextField) {
if textField.text?.count ?? 0 == 0 { if textField.text?.characters.count ?? 0 == 0 {
setState(toState: .placeholder, duration: UIAnimatedTextField.animationDuration) setState(toState: .placeholder, duration: UIAnimatedTextField.animationDuration)
} }
if let datePicker = textField.inputView as? UIDatePicker {
updateText(from: datePicker)
}
delegate?.animatedTextFieldDidEndEditing?(self) delegate?.animatedTextFieldDidEndEditing?(self)
} }