diff --git a/Config.json b/Config.json index da6ab97..c38bddb 100644 --- a/Config.json +++ b/Config.json @@ -1,4 +1,4 @@ { - "version": "1.5.2", - "release_notes": "Imported `SpreadsheetView` library into codebase" + "version": "1.5.3", + "release_notes": "Fixed `PBUITextField` text truncation issue on scale down process" } diff --git a/Sources/PashaKit/Extensions/UILabel+Extensions.swift b/Sources/PashaKit/Extensions/UILabel+Extensions.swift new file mode 100644 index 0000000..e3fbd50 --- /dev/null +++ b/Sources/PashaKit/Extensions/UILabel+Extensions.swift @@ -0,0 +1,37 @@ +// +// UILabel+Extensions.swift +// +// +// Created by Murad on 20.01.24. +// +// +// MIT License +// +// Copyright (c) 2022 Murad Abbasov +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import UIKit + +public extension UILabel { + convenience init(font: UIFont) { + self.init() + self.font = font + } +} diff --git a/Sources/PashaKit/Extensions/UIView+Extensions.swift b/Sources/PashaKit/Extensions/UIView+Extensions.swift index 5b3d6cd..9d37a1b 100644 --- a/Sources/PashaKit/Extensions/UIView+Extensions.swift +++ b/Sources/PashaKit/Extensions/UIView+Extensions.swift @@ -62,15 +62,36 @@ extension UIView { } extension UIView { - func performAnimation(transform: CGAffineTransform) { - UIView.animate(withDuration: 0.3, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, animations: { - self.transform = transform - self.layoutIfNeeded() - }, completion: nil) + func performAnimation( + transform: CGAffineTransform, + completion: ((Bool) -> Void)? = nil + ) { + UIView.animate( + withDuration: 0.3, + delay: 0, + usingSpringWithDamping: 1, + initialSpringVelocity: 1, + animations: { + self.transform = transform + self.layoutIfNeeded() + }, + completion: completion + ) } - func performAnimation(animation: @escaping (() -> Void)) { - UIView.animate(withDuration: 0.3, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, animations: animation, completion: nil) + func performAnimation( + animation: @escaping (() -> Void), + completion: ((Bool) -> Void)? = nil + ) { + UIView.animate( + withDuration: 0.35, + delay: 0, + usingSpringWithDamping: 1, + initialSpringVelocity: 1, + options: .allowUserInteraction, + animations: animation, + completion: completion + ) } } @@ -221,4 +242,14 @@ public extension UIView { view.layer.mask = maskLayer } + + static func transform(from source: CGRect, to destination: CGRect) -> CGAffineTransform { + let scaleX = destination.width / source.width + let scaleY = destination.height / source.height + + let translationX = destination.origin.x - source.origin.x - (source.width * (1.0 - scaleX) / 2) + let translationY = destination.origin.y - source.origin.y - (source.height * (1.0 - scaleY) / 2) + + return CGAffineTransform(translationX: translationX, y: translationY).scaledBy(x: scaleX, y: scaleY) + } } diff --git a/Sources/PashaKit/PBMorphingLabel/PBMorphingLabel.swift b/Sources/PashaKit/PBMorphingLabel/PBMorphingLabel.swift new file mode 100644 index 0000000..bccfbd2 --- /dev/null +++ b/Sources/PashaKit/PBMorphingLabel/PBMorphingLabel.swift @@ -0,0 +1,297 @@ +// +// PBMorphingLabel.swift +// +// +// Created by Murad on 10.12.23. +// +// +// MIT License +// +// Copyright (c) 2022 Murad Abbasov +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Foundation +import UIKit + +class PBMorphingLabel: UIView { + + private(set) var state = PBTextInputState.empty + + var text: String? { + get { + self.titleLabel.text + } + + set { + self.titleLabel.text = newValue + self.transformerLabelSmall.text = newValue + self.transformerLabelBig.text = newValue + self.titlePlaceholderLabel.text = newValue + } + } + + var textColor: UIColor? { + get { + self.titleLabel.textColor + } + + set { + self.titleLabel.textColor = newValue + self.titlePlaceholderLabel.textColor = newValue + + self.transformerLabelSmall.textColor = newValue + self.transformerLabelBig.textColor = newValue + } + } + + var placeholderFont: UIFont? { + get { + self.titlePlaceholderLabel.font + } + + set { + self.titlePlaceholderLabel.font = newValue + self.transformerLabelBig.font = newValue + } + } + + private lazy var upwardTransformBlock = { + self.transformerLabelSmall.transform = .identity + self.transformerLabelBig.transform = UIView.transform( + from: self.titlePlaceholderLabel.frame, + to: self.titleLabel.frame + ) + } + + private lazy var downwardTransformBlock = { + self.transformerLabelBig.transform = .identity + self.transformerLabelSmall.transform = UIView.transform( + from: self.titleLabel.frame, + to: self.titlePlaceholderLabel.frame + ) + } + + private lazy var titleLabel = { + let view = UILabel(font: UIFont.systemFont(ofSize: 12, weight: .regular)) + + self.addSubview(view) + + view.translatesAutoresizingMaskIntoConstraints = false + view.isUserInteractionEnabled = false + + return view + }() + + private lazy var transformerLabelSmall = { + let view = UILabel(font: UIFont.systemFont(ofSize: 12, weight: .regular)) + + self.addSubview(view) + + view.translatesAutoresizingMaskIntoConstraints = false + view.isUserInteractionEnabled = false + + return view + }() + + private lazy var titlePlaceholderLabel = { + let view = UILabel() + + self.addSubview(view) + + view.translatesAutoresizingMaskIntoConstraints = false + view.isUserInteractionEnabled = false + + return view + }() + + private lazy var transformerLabelBig = { + let view = UILabel() + + self.addSubview(view) + + view.translatesAutoresizingMaskIntoConstraints = false + view.isUserInteractionEnabled = false + + return view + }() + + override init(frame: CGRect) { + super.init(frame: frame) + self.commonInit() + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + self.commonInit() + } + + func setState(_ newState: PBTextInputState, animated: Bool) { + #if DEBUG + print("OLD STATE: \(self.state) NEW STATE: \(newState)") + #endif + + guard newState != self.state else { return } + + let oldState = self.state + self.state = newState + + let animated = animated && self.window != nil && self.frame != .zero + + switch (oldState, newState) { + case (_, .empty): + if animated { + self.moveTitleDown(animated: true) + } else { + self.stateDidUpdate() + } + case (.empty, .placeholder): + self.moveTitleUp(animated: animated) + case (.empty, .text): + if animated { + self.moveTitleUp(animated: true) + } else { + self.stateDidUpdate() + } + default: + self.stateDidUpdate() + } + } + + private func commonInit() { + self.isUserInteractionEnabled = false + + self.setupConstraints() + + self.titleLabel.alpha = 0.0 + self.titlePlaceholderLabel.alpha = 1.0 + + self.transformerLabelBig.alpha = 0.0 + self.transformerLabelSmall.alpha = 0.0 + } + + private func setupConstraints() { + self.layoutMargins = .zero + + #if DEBUG + self.titleLabel.backgroundColor = .orange + self.titlePlaceholderLabel.backgroundColor = .green + + self.transformerLabelSmall.backgroundColor = .cyan + self.transformerLabelBig.backgroundColor = .yellow + #endif + + NSLayoutConstraint.activate([ + self.titleLabel.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor), + self.titleLabel.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor), + self.titleLabel.trailingAnchor.constraint(lessThanOrEqualTo: layoutMarginsGuide.trailingAnchor), + + self.titlePlaceholderLabel.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor), + self.titlePlaceholderLabel.trailingAnchor.constraint(lessThanOrEqualTo: layoutMarginsGuide.trailingAnchor), + self.titlePlaceholderLabel.centerYAnchor.constraint(lessThanOrEqualTo: layoutMarginsGuide.centerYAnchor), + + self.transformerLabelSmall.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor), + self.transformerLabelSmall.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor), + self.transformerLabelSmall.trailingAnchor.constraint(lessThanOrEqualTo: layoutMarginsGuide.trailingAnchor), + + self.transformerLabelBig.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor), + self.transformerLabelBig.trailingAnchor.constraint(lessThanOrEqualTo: layoutMarginsGuide.trailingAnchor), + self.transformerLabelBig.centerYAnchor.constraint(lessThanOrEqualTo: layoutMarginsGuide.centerYAnchor), + ]) + } + + override func layoutSubviews() { + super.layoutSubviews() + + if self.state == .empty { + self.downwardTransformBlock() + } else if self.state == .text { + self.upwardTransformBlock() + } + } + + private func stateDidUpdate() { + self.updateTitle() + } + + private func updateTitle() { + switch state { + case .empty: + self.titleLabel.alpha = 0.0 + self.titlePlaceholderLabel.alpha = 1.0 + + self.downwardTransformBlock() + case .text, .placeholder, .textInput: + self.titleLabel.alpha = 1.0 + self.titlePlaceholderLabel.alpha = 0.0 + + self.upwardTransformBlock() + } + } + + private func moveTitleDown(animated: Bool) { + self.titleLabel.alpha = 0.0 + self.transformerLabelSmall.alpha = 1.0 + + let animationBlock = { + self.transformerLabelBig.alpha = 1.0 + self.transformerLabelSmall.alpha = 0.0 + + self.downwardTransformBlock() + } + + if animated { + self.performAnimation(animation: animationBlock) { isComplete in + self.titlePlaceholderLabel.alpha = 1.0 + self.transformerLabelBig.alpha = 0.0 + } + } else { + UIView.performWithoutAnimation { + animationBlock() + self.titlePlaceholderLabel.alpha = 1.0 + self.transformerLabelBig.alpha = 0.0 + } + } + } + + private func moveTitleUp(animated: Bool) { + self.titlePlaceholderLabel.alpha = 0.0 + self.transformerLabelBig.alpha = 1.0 + + let animationBlock = { + self.transformerLabelBig.alpha = 0.0 + self.transformerLabelSmall.alpha = 1.0 + + self.upwardTransformBlock() + } + + if animated { + self.performAnimation(animation: animationBlock) { isComplete in + self.titleLabel.alpha = 1.0 + self.transformerLabelSmall.alpha = 0.0 + } + } else { + UIView.performWithoutAnimation { + animationBlock() + self.titleLabel.alpha = 1.0 + self.transformerLabelSmall.alpha = 0.0 + } + } + } +} diff --git a/Sources/PashaKit/PBMorphingLabel/PBTextInputState.swift b/Sources/PashaKit/PBMorphingLabel/PBTextInputState.swift new file mode 100644 index 0000000..84ad4fd --- /dev/null +++ b/Sources/PashaKit/PBMorphingLabel/PBTextInputState.swift @@ -0,0 +1,50 @@ +// +// PBTextInputState.swift +// +// +// Created by Murad on 14.01.24. +// +// +// MIT License +// +// Copyright (c) 2022 Murad Abbasov +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Foundation + +enum PBTextInputState { + case empty + case text + case placeholder + case textInput + + public init(hasText: Bool, firstResponder: Bool) { + switch (hasText, firstResponder) { + case (false, false): + self = .empty + case (true, false): + self = .text + case (false, true): + self = .placeholder + case (true, true): + self = .textInput + } + } +} diff --git a/Sources/PashaKit/PBUITextField/PBUITextField.swift b/Sources/PashaKit/PBUITextField/PBUITextField.swift index ab34663..5e9399e 100644 --- a/Sources/PashaKit/PBUITextField/PBUITextField.swift +++ b/Sources/PashaKit/PBUITextField/PBUITextField.swift @@ -335,21 +335,13 @@ public class PBUITextField: UIView { self.inputMaskDelegate.put(text: text, into: self.customTextField) - self.layoutCompletionBlock = { - if text.isEmpty { - self.animatePlaceholderToInactivePosition(animated: animated) - } else { - self.animatePlaceholderToActivePosition(animated: animated) - } + if text.isEmpty { + self.animatePlaceholderToInactivePosition(animated: animated) + } else { + self.animatePlaceholderToActivePosition(animated: animated) } self.onTextSetted?(text) - self.layoutSubviews() - } - - public override func layoutSubviews() { - super.layoutSubviews() - self.layoutCompletionBlock?() } /// The keyboard type for text field. @@ -388,15 +380,6 @@ public class PBUITextField: UIView { return delegate }() - private let topPadding: CGFloat = 8.0 - private let placeholderFont = UIFont.systemFont(ofSize: 17, weight: .regular) - private let placeholderSizeFactor: CGFloat = 0.73 - private let leftPadding: CGFloat = 16 - private let animationDuration = 0.3 - - private var editingConstraints: [NSLayoutConstraint] = [] - private var notEditingConstraints: [NSLayoutConstraint] = [] - private var activeConstraints: [NSLayoutConstraint] = [] private var activeRightIconConstraints: [NSLayoutConstraint] = [] private var textFieldStyle: TextFieldStyle = .bordered { @@ -406,7 +389,6 @@ public class PBUITextField: UIView { } private var isComplete: Bool = false - private var layoutCompletionBlock: (() -> Void)? // MARK: - VIEW HIERARCHY @@ -418,16 +400,16 @@ public class PBUITextField: UIView { customBorder.layer.cornerRadius = 12.0 customBorder.layer.borderWidth = 1.0 customBorder.layer.borderColor = self.defaultBorderColor.cgColor + customBorder.layer.cornerCurve = .continuous return customBorder }() - private lazy var customPlaceholder: UILabel = { - let placeholder = UILabel() + private lazy var customPlaceholder: PBMorphingLabel = { + let placeholder = PBMorphingLabel() + placeholder.isOpaque = true placeholder.translatesAutoresizingMaskIntoConstraints = false - placeholder.textAlignment = .left - placeholder.font = self.placeholderFont placeholder.textColor = self.placeholderTextColor return placeholder @@ -465,7 +447,7 @@ public class PBUITextField: UIView { view.tintColor = self.theme.getPrimaryColor() view.isHidden = true - let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(onIconTap)) + let tapGestureRecognizer = UITapGestureRecognizer(target: self,action: #selector(onIconTap)) view.addGestureRecognizer(tapGestureRecognizer) return view @@ -533,13 +515,12 @@ public class PBUITextField: UIView { private func setupViews() { self.addSubview(self.customBorder) + self.customBorder.addSubview(self.customPlaceholder) self.customBorder.addSubview(self.textFieldStack) self.textFieldStack.addArrangedSubview(self.customTextField) self.textFieldStack.addArrangedSubview(self.rightIconView) - self.customBorder.addSubview(self.customPlaceholder) - self.addSubview(self.footerLabel) } @@ -567,15 +548,25 @@ public class PBUITextField: UIView { switch style { case .bordered: NSLayoutConstraint.activate([ - self.textFieldStack.leftAnchor.constraint(equalTo: self.customBorder.leftAnchor, constant: self.leftPadding), - self.textFieldStack.rightAnchor.constraint(equalTo: self.customBorder.rightAnchor, constant: -self.leftPadding), - self.textFieldStack.centerYAnchor.constraint(equalTo: self.customBorder.centerYAnchor) + self.textFieldStack.topAnchor.constraint(greaterThanOrEqualTo: self.customBorder.topAnchor), + self.textFieldStack.leftAnchor.constraint(equalTo: self.customBorder.leftAnchor, constant: 16.0), + self.textFieldStack.rightAnchor.constraint(equalTo: self.customBorder.rightAnchor, constant: -16.0), + self.textFieldStack.centerYAnchor.constraint(equalTo: self.customBorder.centerYAnchor), + self.textFieldStack.bottomAnchor.constraint(lessThanOrEqualTo: self.customBorder.bottomAnchor), + ]) + + NSLayoutConstraint.activate([ + self.customPlaceholder.topAnchor.constraint(equalTo: self.textFieldStack.topAnchor), + self.customPlaceholder.leftAnchor.constraint(equalTo: self.customTextField.leftAnchor), + self.customPlaceholder.rightAnchor.constraint(equalTo: self.customTextField.rightAnchor), + self.customPlaceholder.bottomAnchor.constraint(equalTo: self.textFieldStack.bottomAnchor) ]) NSLayoutConstraint.activate([ self.footerLabel.topAnchor.constraint(equalTo: self.customBorder.bottomAnchor, constant: 6), - self.footerLabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: self.leftPadding), - self.footerLabel.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -self.leftPadding) + self.footerLabel.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 16.0), + self.footerLabel.rightAnchor.constraint(equalTo: self.rightAnchor, constant: -16.0), + self.footerLabel.bottomAnchor.constraint(equalTo: self.bottomAnchor) ]) case .underlined: @@ -586,7 +577,14 @@ public class PBUITextField: UIView { ]) NSLayoutConstraint.activate([ - self.footerLabel.topAnchor.constraint(equalTo: self.customBorder.bottomAnchor), + self.customPlaceholder.topAnchor.constraint(equalTo: self.topAnchor, constant: 12.0), + self.customPlaceholder.leftAnchor.constraint(equalTo: self.customTextField.leftAnchor), + self.customPlaceholder.rightAnchor.constraint(equalTo: self.customTextField.rightAnchor), + self.customPlaceholder.bottomAnchor.constraint(equalTo: self.customBorder.bottomAnchor) + ]) + + NSLayoutConstraint.activate([ + self.footerLabel.topAnchor.constraint(equalTo: self.customBorder.bottomAnchor, constant: 6.0), self.footerLabel.leftAnchor.constraint(equalTo: self.leftAnchor), self.footerLabel.rightAnchor.constraint(equalTo: self.rightAnchor), self.footerLabel.bottomAnchor.constraint(equalTo: self.bottomAnchor) @@ -599,18 +597,6 @@ public class PBUITextField: UIView { ] NSLayoutConstraint.activate(self.activeRightIconConstraints) - - NSLayoutConstraint.activate([ - self.customPlaceholder.widthAnchor.constraint(equalTo: self.customTextField.widthAnchor) - ]) - - self.notEditingConstraints = [ - self.customPlaceholder.leftAnchor.constraint(equalTo: self.customTextField.leftAnchor), - self.customPlaceholder.centerYAnchor.constraint(equalTo: self.customTextField.centerYAnchor) - ] - - self.activeConstraints = self.notEditingConstraints - NSLayoutConstraint.activate(self.activeConstraints) } private func setupRightIconConstraints(for iconSize: RightIconSize) { @@ -716,22 +702,9 @@ public class PBUITextField: UIView { } } - private func calculateEditingConstraints() -> [NSLayoutConstraint] { - let originalWidth = customPlaceholder.bounds.width - let xOffset = (originalWidth - (originalWidth * placeholderSizeFactor)) / 2 - - switch self.textFieldStyle { - case .bordered: - return [ - self.customPlaceholder.topAnchor.constraint(equalTo: self.topAnchor, constant: 6.0), - self.customPlaceholder.leftAnchor.constraint(equalTo: self.textFieldStack.leftAnchor, constant: -xOffset) - ] - case .underlined: - return [ - self.customPlaceholder.bottomAnchor.constraint(equalTo: self.textFieldStack.topAnchor, constant: self.topPadding), - self.customPlaceholder.leftAnchor.constraint(equalTo: self.leftAnchor, constant: -xOffset) - ] - } + private func updatePlaceholderState(animated: Bool) { + let state = PBTextInputState(hasText: self.hasText, firstResponder: self.isFirstResponder) + self.customPlaceholder.setState(state, animated: animated) } private func animatePlaceholderIfNeeded(animationEnabled: Bool = true) { @@ -750,47 +723,35 @@ public class PBUITextField: UIView { } private func animatePlaceholderToActivePosition(animated: Bool = true) { - NSLayoutConstraint.deactivate(self.activeConstraints) - self.activeConstraints = self.calculateEditingConstraints() - NSLayoutConstraint.activate(self.activeConstraints) + self.updatePlaceholderState(animated: animated) if animated { self.performAnimation { - self.layoutIfNeeded() - - self.customPlaceholder.transform = CGAffineTransform(scaleX: self.placeholderSizeFactor, y: self.placeholderSizeFactor) - if self.textFieldStyle == .bordered { self.customTextField.transform = CGAffineTransform(translationX: 0, y: 8) } + + self.layoutIfNeeded() } } else { - self.layoutIfNeeded() - - self.customPlaceholder.transform = CGAffineTransform(scaleX: self.placeholderSizeFactor, y: self.placeholderSizeFactor) - if self.textFieldStyle == .bordered { self.customTextField.transform = CGAffineTransform(translationX: 0, y: 8) } + + self.layoutIfNeeded() } } private func animatePlaceholderToInactivePosition(animated: Bool = true) { - NSLayoutConstraint.deactivate(self.activeConstraints) - self.activeConstraints = self.notEditingConstraints - NSLayoutConstraint.activate(self.activeConstraints) + self.updatePlaceholderState(animated: animated) if animated { self.performAnimation { - self.customPlaceholder.transform = .identity self.customTextField.transform = .identity - self.layoutIfNeeded() } } else { - self.customPlaceholder.transform = .identity self.customTextField.transform = .identity - self.layoutIfNeeded() } } @@ -868,10 +829,26 @@ public class PBUITextField: UIView { /// Makes text field become first responder. /// + @available(*, deprecated, renamed: "becomeFirstResponder") public func makeFirstResponder() { self.customTextField.becomeFirstResponder() } + public override func becomeFirstResponder() -> Bool { + self.customTextField.becomeFirstResponder() + } + + /// Resigns text field from being first responder. + /// + @available(*, deprecated, renamed: "resignFirstResponder") + public func undoFirstResponder() { + self.customTextField.resignFirstResponder() + } + + override public func resignFirstResponder() -> Bool { + self.customTextField.resignFirstResponder() + } + /// Resets text field to its initial form at the beginning /// public func resetField() { @@ -886,16 +863,6 @@ public class PBUITextField: UIView { self.customTextField.addDoneButtonOnKeyboard(title: title) } - /// Resigns text field from being first responder. - /// - public func undoFirstResponder() { - self.customTextField.resignFirstResponder() - } - - override public func resignFirstResponder() -> Bool { - self.customTextField.resignFirstResponder() - } - // MARK: - INPUT DELEGATES /// Get called when entered text updates. @@ -918,6 +885,14 @@ public class PBUITextField: UIView { /// Gets called when editing did begin. public var onDidBegin: (() -> Void)? + + public var hasText: Bool { + return self.customTextField.hasText + } + + public override var isFirstResponder: Bool { + return self.customTextField.isFirstResponder + } } extension PBUITextField: MaskedTextFieldDelegateListener { diff --git a/Sources/PashaKit/SkeletonView/Internal/UIKitExtensions/CALayer+Extensions.swift b/Sources/PashaKit/SkeletonView/Internal/UIKitExtensions/SKCALayer+Extensions.swift similarity index 100% rename from Sources/PashaKit/SkeletonView/Internal/UIKitExtensions/CALayer+Extensions.swift rename to Sources/PashaKit/SkeletonView/Internal/UIKitExtensions/SKCALayer+Extensions.swift diff --git a/Sources/PashaKit/SkeletonView/Internal/UIKitExtensions/UILabel+Extensions.swift b/Sources/PashaKit/SkeletonView/Internal/UIKitExtensions/SKUILabel+Extensions.swift similarity index 100% rename from Sources/PashaKit/SkeletonView/Internal/UIKitExtensions/UILabel+Extensions.swift rename to Sources/PashaKit/SkeletonView/Internal/UIKitExtensions/SKUILabel+Extensions.swift diff --git a/Sources/PashaKit/SkeletonView/Internal/UIKitExtensions/UITableView+Extensions.swift b/Sources/PashaKit/SkeletonView/Internal/UIKitExtensions/SKUITableView+Extensions.swift similarity index 100% rename from Sources/PashaKit/SkeletonView/Internal/UIKitExtensions/UITableView+Extensions.swift rename to Sources/PashaKit/SkeletonView/Internal/UIKitExtensions/SKUITableView+Extensions.swift