Commit 0cad3020 by Daniel Dahan

updated MTextView animations and API

parent 7c8e3238
......@@ -33,7 +33,10 @@ import UIKit
public protocol MTextViewDelegate : UITextViewDelegate {}
@IBDesignable
public class MTextView: UITextView {
public class MTextView: UITextView, TextDelegate {
/// A Text storage object that monitors the changes within the textView.
public private(set) lazy var mText: Text = Text()
/// A Boolean that indicates if the TextView is in an editing state.
public private(set) var editing: Bool = false
......@@ -218,7 +221,7 @@ public class MTextView: UITextView {
if let v: String = value {
detailLabel.attributedText = NSAttributedString(string: v, attributes: [NSForegroundColorAttributeName: detailColor])
}
// layoutDetailLabel()
layoutDetailLabel()
}
}
......@@ -272,6 +275,17 @@ public class MTextView: UITextView {
self.init(frame: CGRectZero, textContainer: textContainer)
}
/// Convenience initializer.
public convenience init() {
let layoutManager: NSLayoutManager = NSLayoutManager()
let textContainer: NSTextContainer = NSTextContainer(size: CGSizeZero)
layoutManager.addTextContainer(textContainer)
self.init(frame: CGRectZero, textContainer: textContainer)
mText.textStorage.addLayoutManager(layoutManager)
mText.delegate = self
}
/** Denitializer. This should never be called unless you know
what you are doing.
*/
......@@ -282,13 +296,13 @@ public class MTextView: UITextView {
/// Overriding the layout callback for subviews.
public override func layoutSubviews() {
super.layoutSubviews()
layoutToSize()
}
public override func layoutSublayersOfLayer(layer: CALayer) {
super.layoutSublayersOfLayer(layer)
if self.layer == layer {
layoutDivider()
}
}
......@@ -348,7 +362,9 @@ public class MTextView: UITextView {
/// Notification handler for when text editing began.
internal func handleTextViewTextDidBegin() {
editing = true
dividerEditingDidBeginAnimation()
placeholderEditingDidBeginAnimation()
}
/// Notification handler for when text changed.
......@@ -358,7 +374,9 @@ public class MTextView: UITextView {
/// Notification handler for when text editing ended.
internal func handleTextViewTextDidEnd() {
editing = false
dividerEditingDidEndAnimation()
placeholderEditingDidEndAnimation()
}
/**
......@@ -373,6 +391,8 @@ public class MTextView: UITextView {
textContainerInset = UIEdgeInsetsZero
backgroundColor = MaterialColor.white
masksToBounds = false
textColor = MaterialColor.darkText.primary
font = RobotoFont.regularWithSize(16)
prepareDivider()
preparePlaceholderLabel()
prepareDetailLabel()
......@@ -428,6 +448,62 @@ public class MTextView: UITextView {
detailLabel.frame = CGRectMake(0, divider.frame.origin.y + 8, width, h)
}
/// The animation for the divider when editing begins.
public func dividerEditingDidBeginAnimation() {
divider.frame.size.height = dividerActiveHeight
divider.backgroundColor = nil == dividerActiveColor ? placeholderActiveColor.CGColor : dividerActiveColor!.CGColor
}
/// The animation for the divider when editing ends.
public func dividerEditingDidEndAnimation() {
divider.frame.size.height = dividerHeight
divider.backgroundColor = dividerColor.CGColor
}
/// The animation for the placeholder when editing begins.
public func placeholderEditingDidBeginAnimation() {
if CGAffineTransformIsIdentity(placeholderLabel.transform) {
animating = true
UIView.animateWithDuration(0.15, animations: { [weak self] in
if let v: MTextView = self {
v.placeholderLabel.transform = CGAffineTransformMakeScale(0.75, 0.75)
switch v.textAlignment {
case .Left, .Natural:
v.placeholderLabel.frame.origin.x = 0
case .Right:
v.placeholderLabel.frame.origin.x = v.width - v.placeholderLabel.frame.width
default:break
}
v.placeholderLabel.frame.origin.y = -v.placeholderLabel.frame.size.height
v.placeholderLabel.textColor = v.placeholderActiveColor
}
}) { [weak self] _ in
self?.animating = false
}
} else if editing {
placeholderLabel.textColor = placeholderActiveColor
}
}
/// The animation for the placeholder when editing ends.
public func placeholderEditingDidEndAnimation() {
if !CGAffineTransformIsIdentity(placeholderLabel.transform) && true == text?.isEmpty {
animating = true
UIView.animateWithDuration(0.15, animations: { [weak self] in
if let v: MTextView = self {
v.placeholderLabel.transform = CGAffineTransformIdentity
v.placeholderLabel.frame.origin.x = 0
v.placeholderLabel.frame.origin.y = 0
v.placeholderLabel.textColor = v.placeholderColor
}
}) { [weak self] _ in
self?.animating = false
}
} else if !editing {
placeholderLabel.textColor = placeholderColor
}
}
/// Prepares the divider.
private func prepareDivider() {
dividerColor = MaterialColor.darkText.dividers
......
......@@ -32,20 +32,38 @@ import UIKit
public class MaterialNoteViewController : UIViewController {
/// Reference to the textView.
public private(set) var textView: TextView!
public private(set) var textView: MTextView!
public override func viewDidLoad() {
super.viewDidLoad()
prepareView()
}
public override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
textView.resignFirstResponder()
}
public override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
layoutTextView()
}
/// Prepares the view.
public func prepareView() {
view.backgroundColor = MaterialColor.white
prepareTextView()
}
/// Layout the textView.
public func layoutTextView() {
textView.frame = view.bounds
}
/// Prepares the textView.
private func prepareTextView() {
textView = TextView()
textView = MTextView()
textView.placeholder = "Placeholder"
view.addSubview(textView)
}
}
......@@ -261,7 +261,7 @@ public class TextField : UITextField {
clearIconButtonAutoHandle = clearIconButtonAutoHandle ? true : false
}
} else {
clearIconButton?.removeTarget(self, action: #selector(handleClearButton), forControlEvents: .TouchUpInside)
clearIconButton?.removeTarget(self, action: #selector(handleClearIconButton), forControlEvents: .TouchUpInside)
clearIconButton = nil
}
}
......@@ -270,9 +270,9 @@ public class TextField : UITextField {
/// Enables the automatic handling of the clearIconButton.
@IBInspectable public var clearIconButtonAutoHandle: Bool = true {
didSet {
clearIconButton?.removeTarget(self, action: #selector(handleClearButton), forControlEvents: .TouchUpInside)
clearIconButton?.removeTarget(self, action: #selector(handleClearIconButton), forControlEvents: .TouchUpInside)
if clearIconButtonAutoHandle {
clearIconButton?.addTarget(self, action: #selector(handleClearButton), forControlEvents: .TouchUpInside)
clearIconButton?.addTarget(self, action: #selector(handleClearIconButton), forControlEvents: .TouchUpInside)
}
}
}
......@@ -300,7 +300,7 @@ public class TextField : UITextField {
visibilityIconButtonAutoHandle = visibilityIconButtonAutoHandle ? true : false
}
} else {
visibilityIconButton?.removeTarget(self, action: #selector(handleClearButton), forControlEvents: .TouchUpInside)
visibilityIconButton?.removeTarget(self, action: #selector(handleVisibilityIconButton), forControlEvents: .TouchUpInside)
visibilityIconButton = nil
}
}
......@@ -309,9 +309,9 @@ public class TextField : UITextField {
/// Enables the automatic handling of the visibilityIconButton.
@IBInspectable public var visibilityIconButtonAutoHandle: Bool = true {
didSet {
visibilityIconButton?.removeTarget(self, action: #selector(handleVisibilityButton), forControlEvents: .TouchUpInside)
visibilityIconButton?.removeTarget(self, action: #selector(handleVisibilityIconButton), forControlEvents: .TouchUpInside)
if visibilityIconButtonAutoHandle {
visibilityIconButton?.addTarget(self, action: #selector(handleVisibilityButton), forControlEvents: .TouchUpInside)
visibilityIconButton?.addTarget(self, action: #selector(handleVisibilityIconButton), forControlEvents: .TouchUpInside)
}
}
}
......@@ -431,7 +431,7 @@ public class TextField : UITextField {
}
/// Handles the clearIconButton TouchUpInside event.
public func handleClearButton() {
public func handleClearIconButton() {
if false == delegate?.textFieldShouldClear?(self) {
return
}
......@@ -439,7 +439,7 @@ public class TextField : UITextField {
}
/// Handles the visibilityIconButton TouchUpInside event.
public func handleVisibilityButton() {
public func handleVisibilityIconButton() {
secureTextEntry = !secureTextEntry
visibilityIconButton?.tintColor = visibilityIconButton?.tintColor.colorWithAlphaComponent(secureTextEntry ? 0.38 : 0.54)
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment