Commit 08ec50d1 by Orkhan Alikhanov

Added DialogDelegate

parent 7f72f648
...@@ -32,19 +32,92 @@ ...@@ -32,19 +32,92 @@
*/ */
import UIKit import UIKit
import Motion
@objc
public protocol DialogDelegate {
/**
A delegation method that is executed when the Dialog is cancelled through tapping background.
- Parameter _ dialog: A Dialog.
*/
@objc
optional func dialogDidCancel(_ dialog: Dialog)
/**
A delegation method that is executed when the Dialog will appear.
- Parameter _ dialog: A Dialog.
*/
@objc
optional func dialogWillAppear(_ dialog: Dialog)
/**
A delegation method that is executed when the Dialog did disappear.
- Parameter _ dialog: A Dialog.
*/
@objc
optional func dialogDidDisappear(_ dialog: Dialog)
/**
A delegation method that is executed to determine if the Dialog should be dismissed.
- Parameter _ dialog: A Dialog.
- Parameter shouldDismiss button: The tapped button. nil if dialog is being
cancelled through tapping background.
- Returns: A Boolean.
*/
@objc
optional func dialog(_ dialog: Dialog, shouldDismiss button: Button?) -> Bool
/**
A delegation method that is executed when the positive button of Dialog is tapped.
- Parameter _ dialog: A Dialog.
- Parameter didTapPositive button: A Button.
*/
@objc
optional func dialog(_ dialog: Dialog, didTapPositive button: Button)
/**
A delegation method that is executed when the negative button of Dialog is tapped.
- Parameter _ dialog: A Dialog.
- Parameter didTapNegative button: A Button.
*/
@objc
optional func dialog(_ dialog: Dialog, didTapNegative button: Button)
/**
A delegation method that is executed when the neutral button of Dialog is tapped.
- Parameter _ dialog: A Dialog.
- Parameter didTapNeutral button: A Button.
*/
@objc
optional func dialog(_ dialog: Dialog, didTapNeutral button: Button)
}
/// A builder for DialogController. /// A builder for DialogController.
open class Dialog { open class Dialog: NSObject {
/// A reference to dialog controller. /// A reference to dialog controller.
public let controller = DialogController<DialogView>() public let controller = DialogController<DialogView>()
/// A weak reference to DialogDelegate.
open weak var delegate: DialogDelegate?
/// An empty initializer. /// An empty initializer.
public init() { } public override init() {
super.init()
/// Set callbacks for delegate.
_ = shouldDismiss(handler: nil)
.positive(nil, handler: nil)
.negative(nil, handler: nil)
.neutral(nil, handler: nil)
.isCancelable(controller.isCancelable, handler: nil)
.willAppear(handler: nil)
.didDisappear(handler: nil)
}
/** /**
Sets title of the dialog. Sets title of the dialog.
- Parameter _ text: A string. - Parameter _ text: A string.
- Returns: DialogBuilder itself to allow chaining. - Returns: Dialog itself to allow chaining.
*/ */
open func title(_ text: String?) -> Dialog { open func title(_ text: String?) -> Dialog {
dialogView.titleLabel.text = text dialogView.titleLabel.text = text
...@@ -54,7 +127,7 @@ open class Dialog { ...@@ -54,7 +127,7 @@ open class Dialog {
/** /**
Sets details of the dialog. Sets details of the dialog.
- Parameter _ text: A string. - Parameter _ text: A string.
- Returns: DialogBuilder itself to allow chaining. - Returns: Dialog itself to allow chaining.
*/ */
open func details(_ text: String?) -> Dialog { open func details(_ text: String?) -> Dialog {
dialogView.detailsLabel.text = text dialogView.detailsLabel.text = text
...@@ -65,11 +138,14 @@ open class Dialog { ...@@ -65,11 +138,14 @@ open class Dialog {
Sets title and handler for positive button of dialog. Sets title and handler for positive button of dialog.
- Parameter _ title: A string. - Parameter _ title: A string.
- Parameter handler: A closure handling tap. - Parameter handler: A closure handling tap.
- Returns: DialogBuilder itself to allow chaining. - Returns: Dialog itself to allow chaining.
*/ */
open func positive(_ title: String?, handler: (() -> Void)?) -> Dialog { open func positive(_ title: String?, handler: (() -> Void)?) -> Dialog {
dialogView.positiveButton.title = title dialogView.positiveButton.title = title
controller.didTapPositiveButtonHandler = handler controller.didTapPositiveButtonHandler = { [unowned self] in
self.delegate?.dialog?(self, didTapPositive: self.controller.dialogView.positiveButton)
handler?()
}
return self return self
} }
...@@ -77,11 +153,14 @@ open class Dialog { ...@@ -77,11 +153,14 @@ open class Dialog {
Sets title and handler for negative button of dialog. Sets title and handler for negative button of dialog.
- Parameter _ title: A string. - Parameter _ title: A string.
- Parameter handler: A closure handling tap. - Parameter handler: A closure handling tap.
- Returns: DialogBuilder itself to allow chaining. - Returns: Dialog itself to allow chaining.
*/ */
open func negative(_ title: String?, handler: (() -> Void)?) -> Dialog { open func negative(_ title: String?, handler: (() -> Void)?) -> Dialog {
dialogView.negativeButton.title = title dialogView.negativeButton.title = title
controller.didTapNegativeButtonHandler = handler controller.didTapNegativeButtonHandler = { [unowned self] in
self.delegate?.dialog?(self, didTapNegative: self.controller.dialogView.negativeButton)
handler?()
}
return self return self
} }
...@@ -89,11 +168,14 @@ open class Dialog { ...@@ -89,11 +168,14 @@ open class Dialog {
Sets title and handler for neutral button of dialog. Sets title and handler for neutral button of dialog.
- Parameter _ title: A string. - Parameter _ title: A string.
- Parameter handler: A closure handling tap. - Parameter handler: A closure handling tap.
- Returns: DialogBuilder itself to allow chaining. - Returns: Dialog itself to allow chaining.
*/ */
open func neutral(_ title: String?, handler: (() -> Void)?) -> Dialog { open func neutral(_ title: String?, handler: (() -> Void)?) -> Dialog {
dialogView.neutralButton.title = title dialogView.neutralButton.title = title
controller.didTapNeutralButtonHandler = handler controller.didTapNeutralButtonHandler = { [unowned self] in
self.delegate?.dialog?(self, didTapNeutral: self.controller.dialogView.neutralButton)
handler?()
}
return self return self
} }
...@@ -101,11 +183,14 @@ open class Dialog { ...@@ -101,11 +183,14 @@ open class Dialog {
Sets cancelability of dialog and handler for when it's cancelled. Sets cancelability of dialog and handler for when it's cancelled.
- Parameter _ value: A Bool. - Parameter _ value: A Bool.
- Parameter handler: A closure handling cancellation. - Parameter handler: A closure handling cancellation.
- Returns: DialogBuilder itself to allow chaining. - Returns: Dialog itself to allow chaining.
*/ */
open func isCancelable(_ value: Bool, handler: (() -> Void)? = nil) -> Dialog { open func isCancelable(_ value: Bool, handler: (() -> Void)? = nil) -> Dialog {
controller.isCancelable = value controller.isCancelable = value
controller.didCancelHandler = handler controller.didCancelHandler = { [unowned self] in
self.delegate?.dialogDidCancel?(self)
handler?()
}
return self return self
} }
...@@ -113,20 +198,62 @@ open class Dialog { ...@@ -113,20 +198,62 @@ open class Dialog {
Sets should-dismiss handler of dialog which takes dialogView and tapped Sets should-dismiss handler of dialog which takes dialogView and tapped
button and returns a boolean indicating if dialog should be dismissed. button and returns a boolean indicating if dialog should be dismissed.
- Parameter handler: A closure handling if dialog can be dismissed. - Parameter handler: A closure handling if dialog can be dismissed.
- Returns: DialogBuilder itself to allow chaining. - Returns: Dialog itself to allow chaining.
*/ */
open func shouldDismiss(handler: ((DialogView, Button?) -> Bool)?) -> Dialog { open func shouldDismiss(handler: ((DialogView, Button?) -> Bool)?) -> Dialog {
controller.shouldDismissHandler = handler controller.shouldDismissHandler = { [unowned self] dialogView, button in
let d = self.delegate?.dialog?(self, shouldDismiss: button) ?? true
let h = handler?(dialogView, button) ?? true
return d && h
}
return self
}
/**
Sets handler for when view controller will appear.
- Parameter handler: A closure handling the event.
- Returns: Dialog itself to allow chaining.
*/
open func willAppear(handler: (() -> Void)?) -> Dialog {
controller.willAppear = { [unowned self] in
self.delegate?.dialogWillAppear?(self)
handler?()
}
return self
}
/**
Sets handler for when view controller did disappear.
- Parameter handler: A closure handling the event.
- Returns: Dialog itself to allow chaining.
*/
open func didDisappear(handler: (() -> Void)?) -> Dialog {
controller.didDisappear = { [unowned self] in
self.delegate?.dialogDidDisappear?(self)
handler?()
self.controller.dialog = nil
}
return self
}
/**
Sets dialog delegate.
- Parameter delegate: A DialogDelegate.
- Returns: Dialog itself to allow chaining.
*/
open func delegate(_ delegate: DialogDelegate) -> Dialog {
self.delegate = delegate
return self return self
} }
/** /**
Presents dialog modally from given viewController. Presents dialog modally from given viewController.
- Parameter _ viewController: A UIViewController. - Parameter _ viewController: A UIViewController.
- Returns: DialogBuilder itself to allow chaining. - Returns: Dialog itself to allow chaining.
*/ */
@discardableResult @discardableResult
open func show(_ viewController: UIViewController) -> Dialog { open func show(_ viewController: UIViewController) -> Dialog {
controller.dialog = self
viewController.present(controller, animated: true, completion: nil) viewController.present(controller, animated: true, completion: nil)
return self return self
} }
...@@ -138,3 +265,24 @@ private extension Dialog { ...@@ -138,3 +265,24 @@ private extension Dialog {
return controller.dialogView return controller.dialogView
} }
} }
/// A memory reference to companion Dialog instance.
private var DialogKey: UInt8 = 0
private extension DialogController {
/**
A Dialog instance attached to the dialog controller.
This is used to keep Dialog alive throughout the lifespan
of the controller.
*/
var dialog: Dialog? {
get {
return AssociatedObject.get(base: self, key: &DialogKey) {
return nil
}
}
set(value) {
AssociatedObject.set(base: self, key: &DialogKey, value: value)
}
}
}
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