-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
781127d
commit a0272e3
Showing
8 changed files
with
252 additions
and
49 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
// | ||
// DossyText.swift | ||
// DossyText | ||
// | ||
// Created by Joey Nelson on 7/9/17. | ||
// Copyright © 2017 NelsonJE. All rights reserved. | ||
// | ||
|
||
import UIKit | ||
|
||
@objc | ||
public protocol DossyTextLabelDelegate { | ||
@objc optional func DossyTextLabel(_ label: DossyTextLabel, didFinishTypingText text: String) | ||
@objc optional func didFinishBlinking(_ label: DossyTextLabel) | ||
} | ||
|
||
open class DossyTextLabel: UILabel { | ||
|
||
private enum LabelState { | ||
case typing | ||
case blinking | ||
case idle | ||
} | ||
|
||
// MARK: - Properties | ||
|
||
//Public | ||
public var delegate: DossyTextLabelDelegate? | ||
public var blinksWhileIdle: Bool = true | ||
public var millisecondsPerLetter = 70 | ||
|
||
// Private | ||
private var state: LabelState = .idle | ||
private var mostRecentAddition: String = "" | ||
private var currentText: String = "" | ||
private var fullText: String = "" | ||
private var blinkingText: String = "" | ||
private var blinking = false | ||
private var timer: Timer! | ||
|
||
// MARK: - Blinking | ||
public func blinkIndefinitely() { | ||
state = .blinking | ||
|
||
blink() | ||
|
||
blinking = true | ||
} | ||
|
||
public func blink(forInterval interval: TimeInterval) { | ||
blinkIndefinitely() | ||
timer = Timer.scheduledTimer(timeInterval: interval, target: self, selector: #selector(stopBlinking), userInfo: nil, repeats: false) | ||
} | ||
|
||
private func blink(_ repeats: Bool = true) { | ||
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(250)) { | ||
if self.text == self.blinkingText { | ||
self.text = "\(self.blinkingText)█" | ||
} else { | ||
self.text = self.blinkingText | ||
} | ||
|
||
if self.state == .blinking && repeats { | ||
self.blink() | ||
} else { | ||
self.delegate?.didFinishBlinking?(self) | ||
} | ||
} | ||
} | ||
|
||
public func stopBlinking() { | ||
state = .idle | ||
} | ||
|
||
|
||
// MARK: - Typing | ||
public func type(_ stringToType: String) { | ||
state = .typing | ||
mostRecentAddition = stringToType | ||
fullText = "\(fullText)\(stringToType)" | ||
type() | ||
} | ||
|
||
private func type() { | ||
if fullText == currentText { | ||
typingEnded() | ||
return | ||
} | ||
|
||
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(millisecondsPerLetter)) { | ||
let stripped = self.fullText.replacingOccurrences(of: self.currentText, with: "") | ||
guard let char = stripped.characters.first else { return } | ||
self.currentText = self.currentText + String(describing: char) | ||
self.text = self.currentText | ||
self.type() | ||
} | ||
} | ||
|
||
private func typingEnded() { | ||
blinkingText = fullText | ||
|
||
if blinksWhileIdle { | ||
blinkIndefinitely() | ||
} else { | ||
state = .idle | ||
} | ||
|
||
delegate?.DossyTextLabel?(self, didFinishTypingText: mostRecentAddition) | ||
} | ||
|
||
// MARK: - Idling | ||
public func idle(){ | ||
stopBlinking() | ||
text = fullText | ||
state = .idle | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// | ||
// View.swift | ||
// DossyText | ||
// | ||
// Created by Joey Nelson on 7/9/17. | ||
// Copyright © 2017 NelsonJE. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
// | ||
// BaseView.swift | ||
// | ||
|
||
import UIKit | ||
|
||
class View: UIView { | ||
|
||
// MARK: - Properties | ||
|
||
// MARK: - Subviews | ||
var blink: DossyTextLabel! | ||
|
||
// MARK: - Initialization | ||
|
||
convenience init() { | ||
self.init(frame: .zero) | ||
configureSubviews() | ||
configureLayout() | ||
} | ||
|
||
/// Set view/subviews appearances | ||
fileprivate func configureSubviews() { | ||
backgroundColor = UIColor.fromHex(rgbValue: 0x181818) | ||
|
||
blink = DossyTextLabel() | ||
blink.textColor = UIColor.fromHex(rgbValue: 0x1DB954) | ||
blink.numberOfLines = 0 | ||
} | ||
|
||
/// Add subviews, set layoutMargins, initialize stored constraints, set layout priorities, activate constraints | ||
fileprivate func configureLayout() { | ||
|
||
addSubview(blink) | ||
blink.translatesAutoresizingMaskIntoConstraints = false | ||
|
||
// Activate NSLayoutAnchors within this closure | ||
NSLayoutConstraint.activate([ | ||
blink.topAnchor.constraint(equalTo: topAnchor, constant: 25), | ||
blink.leftAnchor.constraint(equalTo: leftAnchor, constant: 25), | ||
blink.rightAnchor.constraint(equalTo: rightAnchor, constant: -25) | ||
]) | ||
} | ||
} | ||
|
||
extension UIColor{ | ||
class func fromHex(rgbValue:UInt32, alpha:Double=1.0) -> UIColor{ | ||
let red = CGFloat((rgbValue & 0xFF0000) >> 16)/256.0 | ||
let green = CGFloat((rgbValue & 0xFF00) >> 8)/256.0 | ||
let blue = CGFloat(rgbValue & 0xFF)/256.0 | ||
|
||
return UIColor(red:red, green:green, blue:blue, alpha:CGFloat(alpha)) | ||
} | ||
} |
Oops, something went wrong.