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 { ...@@ -137,7 +137,6 @@ open class Button: UIButton, Pulseable, PulseableLayer {
*/ */
public required init?(coder aDecoder: NSCoder) { public required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder) super.init(coder: aDecoder)
tintColor = Color.blue.base
prepare() prepare()
} }
......
...@@ -171,6 +171,22 @@ public protocol EditorDelegate { ...@@ -171,6 +171,22 @@ public protocol EditorDelegate {
@objc @objc
optional func editor(editor: Editor, textView: UITextView, shouldInteractWith textAttachment: NSTextAttachment, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool 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 { open class Editor: View {
...@@ -179,6 +195,9 @@ open class Editor: View { ...@@ -179,6 +195,9 @@ open class Editor: View {
return 0 < width && 0 < height && nil != superview return 0 < width && 0 < height && nil != superview
} }
/// Is the keyboard hidden.
open fileprivate(set) var isKeyboardHidden = true
/// TextStorage instance that is observed while editing. /// TextStorage instance that is observed while editing.
open fileprivate(set) var textStorage: TextStorage! open fileprivate(set) var textStorage: TextStorage!
...@@ -249,6 +268,11 @@ open class Editor: View { ...@@ -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) 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, Prepares the view instance when intialized. When subclassing,
it is recommended to override the prepare method it is recommended to override the prepare method
...@@ -263,6 +287,7 @@ open class Editor: View { ...@@ -263,6 +287,7 @@ open class Editor: View {
prepareTextStorage() prepareTextStorage()
prepareRegularExpression() prepareRegularExpression()
prepareTextView() prepareTextView()
prepareKeyboardNotificationObservers()
} }
} }
...@@ -296,6 +321,52 @@ extension Editor { ...@@ -296,6 +321,52 @@ extension Editor {
fileprivate func prepareRegularExpression() { fileprivate func prepareRegularExpression() {
textStorage.expression = try? NSRegularExpression(pattern: pattern, options: []) 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 { extension Editor: TextStorageDelegate {
......
...@@ -182,7 +182,7 @@ extension UIViewController { ...@@ -182,7 +182,7 @@ extension UIViewController {
- Returns: An optional UIViewControllerAnimatedTransitioning. - Returns: An optional UIViewControllerAnimatedTransitioning.
*/ */
open func animationController(forDismissed dismissed: UIViewController) -> 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 { ...@@ -309,8 +309,7 @@ open class MotionPresentationController: UIPresentationController {
presentedViewController.transitionCoordinator?.animate(alongsideTransition: { (context) in }) presentedViewController.transitionCoordinator?.animate(alongsideTransition: { (context) in })
} }
open override func presentationTransitionDidEnd(_ completed: Bool) { open override func presentationTransitionDidEnd(_ completed: Bool) {}
}
open override func dismissalTransitionWillBegin() { open override func dismissalTransitionWillBegin() {
guard nil != containerView else { guard nil != containerView else {
...@@ -320,8 +319,7 @@ open class MotionPresentationController: UIPresentationController { ...@@ -320,8 +319,7 @@ open class MotionPresentationController: UIPresentationController {
presentedViewController.transitionCoordinator?.animate(alongsideTransition: { (context) in }) presentedViewController.transitionCoordinator?.animate(alongsideTransition: { (context) in })
} }
open override func dismissalTransitionDidEnd(_ completed: Bool) { open override func dismissalTransitionDidEnd(_ completed: Bool) {}
}
open override var frameOfPresentedViewInContainerView: CGRect { open override var frameOfPresentedViewInContainerView: CGRect {
return containerView?.bounds ?? .zero return containerView?.bounds ?? .zero
...@@ -386,7 +384,7 @@ open class Motion: NSObject { ...@@ -386,7 +384,7 @@ open class Motion: NSObject {
/// The view that is being transitioned to. /// The view that is being transitioned to.
open var toView: UIView { open var toView: UIView {
return transitionContext.view(forKey: .to)! return toViewController.view
} }
/// The subviews of the view being transitioned to. /// The subviews of the view being transitioned to.
...@@ -396,7 +394,7 @@ open class Motion: NSObject { ...@@ -396,7 +394,7 @@ open class Motion: NSObject {
/// The view that is being transitioned from. /// The view that is being transitioned from.
open var fromView: UIView { open var fromView: UIView {
return transitionContext.view(forKey: .from)! return fromViewController.view
} }
/// The subviews of the view being transitioned from. /// The subviews of the view being transitioned from.
...@@ -591,6 +589,7 @@ extension Motion { ...@@ -591,6 +589,7 @@ extension Motion {
toView.isHidden = isPresenting toView.isHidden = isPresenting
containerView.insertSubview(toView, belowSubview: transitionView) containerView.insertSubview(toView, belowSubview: transitionView)
toView.frame = fromView.frame
toView.updateConstraints() toView.updateConstraints()
toView.setNeedsLayout() toView.setNeedsLayout()
toView.layoutIfNeeded() toView.layoutIfNeeded()
......
...@@ -382,7 +382,8 @@ open class TextField: UITextField { ...@@ -382,7 +382,8 @@ open class TextField: UITextField {
} }
open override func becomeFirstResponder() -> Bool { open override func becomeFirstResponder() -> Bool {
layoutSubviews() setNeedsLayout()
layoutIfNeeded()
return super.becomeFirstResponder() return super.becomeFirstResponder()
} }
...@@ -506,7 +507,7 @@ extension TextField { ...@@ -506,7 +507,7 @@ extension TextField {
/// Layout the detailLabel. /// Layout the detailLabel.
fileprivate func layoutDetailLabel() { fileprivate func layoutDetailLabel() {
let c = dividerContentEdgeInsets 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.x = c.left
detailLabel.y = height + detailVerticalOffset detailLabel.y = height + detailVerticalOffset
detailLabel.width = width - c.left - c.right 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