Commit 0cad3020 by Daniel Dahan

updated MTextView animations and API

parent 7c8e3238
...@@ -33,7 +33,10 @@ import UIKit ...@@ -33,7 +33,10 @@ import UIKit
public protocol MTextViewDelegate : UITextViewDelegate {} public protocol MTextViewDelegate : UITextViewDelegate {}
@IBDesignable @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. /// A Boolean that indicates if the TextView is in an editing state.
public private(set) var editing: Bool = false public private(set) var editing: Bool = false
...@@ -218,7 +221,7 @@ public class MTextView: UITextView { ...@@ -218,7 +221,7 @@ public class MTextView: UITextView {
if let v: String = value { if let v: String = value {
detailLabel.attributedText = NSAttributedString(string: v, attributes: [NSForegroundColorAttributeName: detailColor]) detailLabel.attributedText = NSAttributedString(string: v, attributes: [NSForegroundColorAttributeName: detailColor])
} }
// layoutDetailLabel() layoutDetailLabel()
} }
} }
...@@ -272,6 +275,17 @@ public class MTextView: UITextView { ...@@ -272,6 +275,17 @@ public class MTextView: UITextView {
self.init(frame: CGRectZero, textContainer: textContainer) 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 /** Denitializer. This should never be called unless you know
what you are doing. what you are doing.
*/ */
...@@ -282,13 +296,13 @@ public class MTextView: UITextView { ...@@ -282,13 +296,13 @@ public class MTextView: UITextView {
/// Overriding the layout callback for subviews. /// Overriding the layout callback for subviews.
public override func layoutSubviews() { public override func layoutSubviews() {
super.layoutSubviews() super.layoutSubviews()
layoutToSize()
} }
public override func layoutSublayersOfLayer(layer: CALayer) { public override func layoutSublayersOfLayer(layer: CALayer) {
super.layoutSublayersOfLayer(layer) super.layoutSublayersOfLayer(layer)
if self.layer == layer { if self.layer == layer {
layoutDivider()
} }
} }
...@@ -348,7 +362,9 @@ public class MTextView: UITextView { ...@@ -348,7 +362,9 @@ public class MTextView: UITextView {
/// Notification handler for when text editing began. /// Notification handler for when text editing began.
internal func handleTextViewTextDidBegin() { internal func handleTextViewTextDidBegin() {
editing = true
dividerEditingDidBeginAnimation()
placeholderEditingDidBeginAnimation()
} }
/// Notification handler for when text changed. /// Notification handler for when text changed.
...@@ -358,7 +374,9 @@ public class MTextView: UITextView { ...@@ -358,7 +374,9 @@ public class MTextView: UITextView {
/// Notification handler for when text editing ended. /// Notification handler for when text editing ended.
internal func handleTextViewTextDidEnd() { internal func handleTextViewTextDidEnd() {
editing = false
dividerEditingDidEndAnimation()
placeholderEditingDidEndAnimation()
} }
/** /**
...@@ -373,6 +391,8 @@ public class MTextView: UITextView { ...@@ -373,6 +391,8 @@ public class MTextView: UITextView {
textContainerInset = UIEdgeInsetsZero textContainerInset = UIEdgeInsetsZero
backgroundColor = MaterialColor.white backgroundColor = MaterialColor.white
masksToBounds = false masksToBounds = false
textColor = MaterialColor.darkText.primary
font = RobotoFont.regularWithSize(16)
prepareDivider() prepareDivider()
preparePlaceholderLabel() preparePlaceholderLabel()
prepareDetailLabel() prepareDetailLabel()
...@@ -428,6 +448,62 @@ public class MTextView: UITextView { ...@@ -428,6 +448,62 @@ public class MTextView: UITextView {
detailLabel.frame = CGRectMake(0, divider.frame.origin.y + 8, width, h) 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. /// Prepares the divider.
private func prepareDivider() { private func prepareDivider() {
dividerColor = MaterialColor.darkText.dividers dividerColor = MaterialColor.darkText.dividers
......
...@@ -32,20 +32,38 @@ import UIKit ...@@ -32,20 +32,38 @@ import UIKit
public class MaterialNoteViewController : UIViewController { public class MaterialNoteViewController : UIViewController {
/// Reference to the textView. /// Reference to the textView.
public private(set) var textView: TextView! public private(set) var textView: MTextView!
public override func viewDidLoad() { public override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
prepareView() prepareView()
} }
public override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
textView.resignFirstResponder()
}
public override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
layoutTextView()
}
/// Prepares the view. /// Prepares the view.
public func prepareView() { public func prepareView() {
view.backgroundColor = MaterialColor.white view.backgroundColor = MaterialColor.white
prepareTextView()
}
/// Layout the textView.
public func layoutTextView() {
textView.frame = view.bounds
} }
/// Prepares the textView. /// Prepares the textView.
private func prepareTextView() { private func prepareTextView() {
textView = TextView() textView = MTextView()
textView.placeholder = "Placeholder"
view.addSubview(textView)
} }
} }
...@@ -261,7 +261,7 @@ public class TextField : UITextField { ...@@ -261,7 +261,7 @@ public class TextField : UITextField {
clearIconButtonAutoHandle = clearIconButtonAutoHandle ? true : false clearIconButtonAutoHandle = clearIconButtonAutoHandle ? true : false
} }
} else { } else {
clearIconButton?.removeTarget(self, action: #selector(handleClearButton), forControlEvents: .TouchUpInside) clearIconButton?.removeTarget(self, action: #selector(handleClearIconButton), forControlEvents: .TouchUpInside)
clearIconButton = nil clearIconButton = nil
} }
} }
...@@ -270,9 +270,9 @@ public class TextField : UITextField { ...@@ -270,9 +270,9 @@ public class TextField : UITextField {
/// Enables the automatic handling of the clearIconButton. /// Enables the automatic handling of the clearIconButton.
@IBInspectable public var clearIconButtonAutoHandle: Bool = true { @IBInspectable public var clearIconButtonAutoHandle: Bool = true {
didSet { didSet {
clearIconButton?.removeTarget(self, action: #selector(handleClearButton), forControlEvents: .TouchUpInside) clearIconButton?.removeTarget(self, action: #selector(handleClearIconButton), forControlEvents: .TouchUpInside)
if clearIconButtonAutoHandle { 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 { ...@@ -300,7 +300,7 @@ public class TextField : UITextField {
visibilityIconButtonAutoHandle = visibilityIconButtonAutoHandle ? true : false visibilityIconButtonAutoHandle = visibilityIconButtonAutoHandle ? true : false
} }
} else { } else {
visibilityIconButton?.removeTarget(self, action: #selector(handleClearButton), forControlEvents: .TouchUpInside) visibilityIconButton?.removeTarget(self, action: #selector(handleVisibilityIconButton), forControlEvents: .TouchUpInside)
visibilityIconButton = nil visibilityIconButton = nil
} }
} }
...@@ -309,9 +309,9 @@ public class TextField : UITextField { ...@@ -309,9 +309,9 @@ public class TextField : UITextField {
/// Enables the automatic handling of the visibilityIconButton. /// Enables the automatic handling of the visibilityIconButton.
@IBInspectable public var visibilityIconButtonAutoHandle: Bool = true { @IBInspectable public var visibilityIconButtonAutoHandle: Bool = true {
didSet { didSet {
visibilityIconButton?.removeTarget(self, action: #selector(handleVisibilityButton), forControlEvents: .TouchUpInside) visibilityIconButton?.removeTarget(self, action: #selector(handleVisibilityIconButton), forControlEvents: .TouchUpInside)
if visibilityIconButtonAutoHandle { 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 { ...@@ -431,7 +431,7 @@ public class TextField : UITextField {
} }
/// Handles the clearIconButton TouchUpInside event. /// Handles the clearIconButton TouchUpInside event.
public func handleClearButton() { public func handleClearIconButton() {
if false == delegate?.textFieldShouldClear?(self) { if false == delegate?.textFieldShouldClear?(self) {
return return
} }
...@@ -439,7 +439,7 @@ public class TextField : UITextField { ...@@ -439,7 +439,7 @@ public class TextField : UITextField {
} }
/// Handles the visibilityIconButton TouchUpInside event. /// Handles the visibilityIconButton TouchUpInside event.
public func handleVisibilityButton() { public func handleVisibilityIconButton() {
secureTextEntry = !secureTextEntry secureTextEntry = !secureTextEntry
visibilityIconButton?.tintColor = visibilityIconButton?.tintColor.colorWithAlphaComponent(secureTextEntry ? 0.38 : 0.54) 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