diff --git a/Sources/FontAnimation.swift b/Sources/FontAnimation.swift index 95df842..c64eead 100644 --- a/Sources/FontAnimation.swift +++ b/Sources/FontAnimation.swift @@ -7,15 +7,12 @@ import QuartzCore import CoreFoundation internal final class FontAnimation { - - private let displayLink: CADisplayLink? + private var displayLink: CADisplayLink? private(set) var startTime: CFTimeInterval? - private let target: Any private let selector: Selector - init(target: Any, selector: Selector) { - self.target = target + init(target: AnyObject, selector: Selector) { self.selector = selector displayLink = CADisplayLink(target: target, selector: selector) @@ -27,12 +24,14 @@ internal final class FontAnimation { } func start() { - startTime = CFAbsoluteTimeGetCurrent() displayLink?.isPaused = false + + startTime = CFAbsoluteTimeGetCurrent() } func stop() { startTime = nil + displayLink?.isPaused = true } } diff --git a/Sources/TweePlaceholderTextField.swift b/Sources/TweePlaceholderTextField.swift index ac05498..02839f9 100644 --- a/Sources/TweePlaceholderTextField.swift +++ b/Sources/TweePlaceholderTextField.swift @@ -85,8 +85,8 @@ open class TweePlaceholderTextField: UITextField { } } - private lazy var minimizeFontAnimation = FontAnimation(target: self, selector: #selector(minimizePlaceholderFontSize)) - private lazy var maximizeFontAnimation = FontAnimation(target: self, selector: #selector(maximizePlaceholderFontSize)) + private lazy var minimizeFontAnimation = FontAnimation(target: WeakTargetProxy(target: self), selector: #selector(minimizePlaceholderFontSize)) + private lazy var maximizeFontAnimation = FontAnimation(target: WeakTargetProxy(target: self), selector: #selector(maximizePlaceholderFontSize)) private let placeholderLayoutGuide = UILayoutGuide() private var leadingPlaceholderConstraint: NSLayoutConstraint? diff --git a/Sources/WeakTargetProxy.swift b/Sources/WeakTargetProxy.swift new file mode 100644 index 0000000..50eeb65 --- /dev/null +++ b/Sources/WeakTargetProxy.swift @@ -0,0 +1,27 @@ +// Created by Oleg Hnidets on 9/14/18. +// Copyright © 2018 Oleg Hnidets. All rights reserved. +// + +import Foundation + +internal final class WeakTargetProxy: NSObject { + private weak var target: NSObjectProtocol? + + init(target: NSObjectProtocol) { + self.target = target + + super.init() + } + + override func responds(to aSelector: Selector!) -> Bool { + guard let target = target else { + return super.responds(to: aSelector) + } + + return target.responds(to: aSelector) || super.responds(to: aSelector) + } + + override func forwardingTarget(for aSelector: Selector!) -> Any? { + return target + } +} diff --git a/TweeTextField.xcodeproj/project.pbxproj b/TweeTextField.xcodeproj/project.pbxproj index 5e7d8ac..bb9ae0c 100644 --- a/TweeTextField.xcodeproj/project.pbxproj +++ b/TweeTextField.xcodeproj/project.pbxproj @@ -15,6 +15,8 @@ 7C065D3920E3F02C00B8F983 /* TweeAttributedTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92A146091FEC228900CEADAA /* TweeAttributedTextField.swift */; }; 7C065D3A20E3F02C00B8F983 /* TweeActiveTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92A1460A1FEC228900CEADAA /* TweeActiveTextField.swift */; }; 7C065D3B20E3F02C00B8F983 /* FontAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92A1460B1FEC228900CEADAA /* FontAnimation.swift */; }; + 7C15066C214BF43D006A7D4C /* WeakTargetProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C15066B214BF43D006A7D4C /* WeakTargetProxy.swift */; }; + 7C15066D214BF47E006A7D4C /* WeakTargetProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C15066B214BF43D006A7D4C /* WeakTargetProxy.swift */; }; 7CF5909A2125DB5D0015777F /* PasswordTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7CF590992125DB5D0015777F /* PasswordTextField.swift */; }; 92A1460C1FEC228900CEADAA /* TweePlaceholderTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92A146071FEC228900CEADAA /* TweePlaceholderTextField.swift */; }; 92A1460D1FEC228900CEADAA /* TweeBorderedTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92A146081FEC228900CEADAA /* TweeBorderedTextField.swift */; }; @@ -56,6 +58,7 @@ 7C065D2B20E3EFCD00B8F983 /* TweeTextField.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TweeTextField.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 7C065D2D20E3EFCD00B8F983 /* TweeTextField.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TweeTextField.h; sourceTree = ""; }; 7C065D2E20E3EFCD00B8F983 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 7C15066B214BF43D006A7D4C /* WeakTargetProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WeakTargetProxy.swift; sourceTree = ""; }; 7CF590992125DB5D0015777F /* PasswordTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PasswordTextField.swift; sourceTree = ""; }; 92A146071FEC228900CEADAA /* TweePlaceholderTextField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TweePlaceholderTextField.swift; sourceTree = ""; }; 92A146081FEC228900CEADAA /* TweeBorderedTextField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TweeBorderedTextField.swift; sourceTree = ""; }; @@ -119,6 +122,7 @@ 92A146091FEC228900CEADAA /* TweeAttributedTextField.swift */, 92A1460A1FEC228900CEADAA /* TweeActiveTextField.swift */, 92A1460B1FEC228900CEADAA /* FontAnimation.swift */, + 7C15066B214BF43D006A7D4C /* WeakTargetProxy.swift */, ); path = Sources; sourceTree = SOURCE_ROOT; @@ -303,6 +307,7 @@ 7C065D3920E3F02C00B8F983 /* TweeAttributedTextField.swift in Sources */, 7C065D3A20E3F02C00B8F983 /* TweeActiveTextField.swift in Sources */, 7C065D3B20E3F02C00B8F983 /* FontAnimation.swift in Sources */, + 7C15066C214BF43D006A7D4C /* WeakTargetProxy.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -311,6 +316,7 @@ buildActionMask = 2147483647; files = ( 92A146101FEC228900CEADAA /* FontAnimation.swift in Sources */, + 7C15066D214BF47E006A7D4C /* WeakTargetProxy.swift in Sources */, 92A1460F1FEC228900CEADAA /* TweeActiveTextField.swift in Sources */, 92E7FC3C1FE0374600E58DF5 /* ViewController.swift in Sources */, 92E7FC3A1FE0374600E58DF5 /* AppDelegate.swift in Sources */, diff --git a/TweeTextField/Base.lproj/Main.storyboard b/TweeTextField/Base.lproj/Main.storyboard index 464099b..de019ef 100644 --- a/TweeTextField/Base.lproj/Main.storyboard +++ b/TweeTextField/Base.lproj/Main.storyboard @@ -20,7 +20,7 @@ - + @@ -147,53 +147,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + - + + - - + diff --git a/TweeTextField/ViewController.swift b/TweeTextField/ViewController.swift index 43a7504..3a27597 100644 --- a/TweeTextField/ViewController.swift +++ b/TweeTextField/ViewController.swift @@ -13,22 +13,24 @@ extension String { } final class ViewController: UIViewController { - + @IBOutlet private weak var stackView: UIStackView! @IBOutlet private weak var usernameTextField: TweeBorderedTextField! - @IBOutlet private weak var passwordTextField: TweeActiveTextField! - @IBOutlet private weak var emailTextField: TweeAttributedTextField! override func viewDidLoad() { super.viewDidLoad() -// usernameTextField.text = "text" -// usernameTextField.tweePlaceholder = "User name" passwordTextField.text = "password" emailTextField.text = "text" } + @IBAction private func removeFirstField() { + stackView.arrangedSubviews.first.flatMap { + $0.removeFromSuperview() + } + } + @IBAction private func confirm() { emailTextField.text = "Issue #8" }