Commit 689efbd7 by Daniel Dahan

development: added keyboard notification delegation handlers for EditorDelegate

parent 3105d5d5
......@@ -137,7 +137,6 @@ open class Button: UIButton, Pulseable, PulseableLayer {
*/
public required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
tintColor = Color.blue.base
prepare()
}
......
......@@ -171,6 +171,22 @@ public protocol EditorDelegate {
@objc
optional func editor(editor: Editor, textView: UITextView, shouldInteractWith textAttachment: NSTextAttachment, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool
*/
/**
A delegation method that is executed when the keyboard will open.
- Parameter editor: An Editor.
- Parameter willShowKeyboard value: A NSValue.
*/
@objc
optional func editor(editor: Editor, willShowKeyboard value: NSValue)
/**
A delegation method that is executed when the keyboard will close.
- Parameter editor: An Editor.
- Parameter willHideKeyboard value: A NSValue.
*/
@objc
optional func editor(editor: Editor, willHideKeyboard value: NSValue)
}
open class Editor: View {
......@@ -179,6 +195,9 @@ open class Editor: View {
return 0 < width && 0 < height && nil != superview
}
/// Is the keyboard hidden.
open fileprivate(set) var isKeyboardHidden = true
/// TextStorage instance that is observed while editing.
open fileprivate(set) var textStorage: TextStorage!
......@@ -249,6 +268,11 @@ open class Editor: View {
textView.frame = CGRect(x: textViewEdgeInsets.left, y: textViewEdgeInsets.top, width: width - textViewEdgeInsets.left - textViewEdgeInsets.right, height: height - textViewEdgeInsets.top - textViewEdgeInsets.bottom)
}
/// Deinitializer.
deinit {
NotificationCenter.default.removeObserver(self)
}
/**
Prepares the view instance when intialized. When subclassing,
it is recommended to override the prepare method
......@@ -263,6 +287,7 @@ open class Editor: View {
prepareTextStorage()
prepareRegularExpression()
prepareTextView()
prepareKeyboardNotificationObservers()
}
}
......@@ -296,6 +321,52 @@ extension Editor {
fileprivate func prepareRegularExpression() {
textStorage.expression = try? NSRegularExpression(pattern: pattern, options: [])
}
/// Prepares the keyboard notification center observers.
fileprivate func prepareKeyboardNotificationObservers() {
NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardWillShow(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardWillHide(notification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
}
extension Editor {
/**
Handler for when the keyboard will open.
- Parameter notification: A Notification.
*/
@objc
fileprivate func handleKeyboardWillShow(notification: Notification) {
guard isKeyboardHidden else {
return
}
isKeyboardHidden = false
guard let v = notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue else {
return
}
delegate?.editor?(editor: self, willShowKeyboard: v)
}
/**
Handler for when the keyboard will close.
- Parameter notification: A Notification.
*/
@objc
fileprivate func handleKeyboardWillHide(notification: Notification) {
guard !isKeyboardHidden else {
return
}
isKeyboardHidden = true
guard let v = notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue else {
return
}
delegate?.editor?(editor: self, willHideKeyboard: v)
}
}
extension Editor: TextStorageDelegate {
......
......@@ -182,7 +182,7 @@ extension UIViewController {
- Returns: An optional UIViewControllerAnimatedTransitioning.
*/
open func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return isMotionEnabled ? Motion() : nil
return isMotionEnabled ? Motion(isPresenting: false, isContainer: false) : nil
}
/**
......@@ -309,8 +309,7 @@ open class MotionPresentationController: UIPresentationController {
presentedViewController.transitionCoordinator?.animate(alongsideTransition: { (context) in })
}
open override func presentationTransitionDidEnd(_ completed: Bool) {
}
open override func presentationTransitionDidEnd(_ completed: Bool) {}
open override func dismissalTransitionWillBegin() {
guard nil != containerView else {
......@@ -320,8 +319,7 @@ open class MotionPresentationController: UIPresentationController {
presentedViewController.transitionCoordinator?.animate(alongsideTransition: { (context) in })
}
open override func dismissalTransitionDidEnd(_ completed: Bool) {
}
open override func dismissalTransitionDidEnd(_ completed: Bool) {}
open override var frameOfPresentedViewInContainerView: CGRect {
return containerView?.bounds ?? .zero
......@@ -386,7 +384,7 @@ open class Motion: NSObject {
/// The view that is being transitioned to.
open var toView: UIView {
return transitionContext.view(forKey: .to)!
return toViewController.view
}
/// The subviews of the view being transitioned to.
......@@ -396,7 +394,7 @@ open class Motion: NSObject {
/// The view that is being transitioned from.
open var fromView: UIView {
return transitionContext.view(forKey: .from)!
return fromViewController.view
}
/// The subviews of the view being transitioned from.
......@@ -591,6 +589,7 @@ extension Motion {
toView.isHidden = isPresenting
containerView.insertSubview(toView, belowSubview: transitionView)
toView.frame = fromView.frame
toView.updateConstraints()
toView.setNeedsLayout()
toView.layoutIfNeeded()
......
......@@ -382,7 +382,8 @@ open class TextField: UITextField {
}
open override func becomeFirstResponder() -> Bool {
layoutSubviews()
setNeedsLayout()
layoutIfNeeded()
return super.becomeFirstResponder()
}
......@@ -506,7 +507,7 @@ extension TextField {
/// Layout the detailLabel.
fileprivate func layoutDetailLabel() {
let c = dividerContentEdgeInsets
detailLabel.height = detailLabel.sizeThatFits(CGSize(width: width, height: CGFloat.greatestFiniteMagnitude)).height
detailLabel.height = detailLabel.sizeThatFits(CGSize(width: width, height: .greatestFiniteMagnitude)).height
detailLabel.x = c.left
detailLabel.y = height + detailVerticalOffset
detailLabel.width = width - c.left - c.right
......
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