From 211d9f6c3b39541272286a6f239db6bf52a82ecc Mon Sep 17 00:00:00 2001 From: "Christiano, Kevin" Date: Fri, 3 May 2019 11:28:25 -0400 Subject: [PATCH] More functionality for label. --- MVMCoreUI/Atoms/Views/Label.swift | 96 +++++++++++++++++++++++++++++-- 1 file changed, 92 insertions(+), 4 deletions(-) diff --git a/MVMCoreUI/Atoms/Views/Label.swift b/MVMCoreUI/Atoms/Views/Label.swift index d6f0a5ed..255fa342 100644 --- a/MVMCoreUI/Atoms/Views/Label.swift +++ b/MVMCoreUI/Atoms/Views/Label.swift @@ -156,7 +156,7 @@ public typealias ActionBlock = () -> Void } //------------------------------------------------------ - // MARK: - Functions + // MARK: - Tappable Methods //------------------------------------------------------ /** @@ -182,12 +182,47 @@ public typealias ActionBlock = () -> Void Label.setGestureInteraction(for: self) } + /** + Provides an actionable range of text. + + - Attention: This method expects text to be set first. Otherwise, it will do nothing. + - Parameters: + - range: The range of text to be tapped. + - actionMap: + - delegate: + - additionalData: + */ + @objc public func addTappableLinkAttribute(range: NSRange, actionMap: [AnyHashable: Any]?, delegate: DelegateObject?, additionalData: [AnyHashable: Any]?) { + + guard let text = self.text, + let subStringRange = Range(range, in: text) + else { return } + + clauses.append(ActionableClause(labelView: self, + location: range.location, + length: range.length, + actionText: String(text[subStringRange]), + actionBlock: { [weak self, weak delegate] in + var willPerform = true + + if let wSelf = self, let buttonDelegate = (delegate as? MVMCoreUIDelegateObject)?.buttonDelegate, + buttonDelegate.responds(to: #selector(ButtonObjectDelegate.button(_:shouldPerformActionWithMap:additionalData:))) { + willPerform = buttonDelegate.button?(wSelf, shouldPerformActionWithMap: actionMap, additionalData: additionalData) ?? false + } + + if willPerform { + MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegate) + } })) + + Label.setGestureInteraction(for: self) + } + /** Provides an actionable range of text. Allows actionable range to be established by a particular substring of the containing label text. - - Attention: This method expects text to be set first. Otherwise, it will do nothing. + - Attention: This method expects text to be set first. Otherwise, it will do nothing. Do not use if actionText is not unique in the Label's text. - Parameters: - actionText: The actionable text contained witin the label's text. - actionBlock: The code triggered when tapping the range of text. @@ -207,6 +242,42 @@ public typealias ActionBlock = () -> Void Label.setGestureInteraction(for: self) } + /** + Provides an actionable range of text. + + - Attention: This method expects text to be set first. Otherwise, it will do nothing. Do not use if actionText is not unique in the Label's text. + - Parameters: + - actionText: The actionable text contained witin the label's text. + - actionMap: + - delegate: + - additionalData: + */ + @objc public func addTappableLinkAttribute(actionText: String, actionMap: [AnyHashable: Any]?, delegate: DelegateObject?, additionalData: [AnyHashable: Any]?) { + + guard let text = self.text else { return } + let string = text as NSString + let range = string.range(of: actionText) + + clauses.append(ActionableClause(labelView: self, location: range.location, length: range.length, actionText: actionText, + actionBlock: { [weak self, weak delegate] in + var willPerform = true + + if let wSelf = self, let buttonDelegate = (delegate as? MVMCoreUIDelegateObject)?.buttonDelegate, + buttonDelegate.responds(to: #selector(ButtonObjectDelegate.button(_:shouldPerformActionWithMap:additionalData:))) { + willPerform = buttonDelegate.button?(wSelf, shouldPerformActionWithMap: actionMap, additionalData: additionalData) ?? false + } + + if willPerform { + MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegate) + } })) + + Label.setGestureInteraction(for: self) + } + + //------------------------------------------------------ + // MARK: - Functions + //------------------------------------------------------ + /** Makes the view interactive and applies the gesture recognizer. @@ -224,6 +295,13 @@ public typealias ActionBlock = () -> Void } } + /** + Makes the view interactive and applies the gesture recognizer. + + - Parameters: + - label: The label to be set. + - html: The url link to be applied as an attributed link. + */ @objc public static func setLabel(_ label: UILabel?, with html: String?) { guard let data = html?.data(using: .utf8) else { return } @@ -240,6 +318,15 @@ public typealias ActionBlock = () -> Void } } + /** + Makes the view interactive and applies the gesture recognizer. + + - Parameters: + - label: The current label view that will have an actionable range of text. + - json: Contains values which det the values of Label. + - delegate: + - additionalData: + */ @objc public static func setUILabel(_ label: UILabel?, withJSON json: [AnyHashable: Any]?, delegate: DelegateObject?, additionalData: [AnyHashable: Any]?) { guard let label = label as? Label else { return } @@ -326,7 +413,7 @@ public typealias ActionBlock = () -> Void } if willPerform { - MVMCoreActionHandler.shared()?.handleAction(with: attribute, additionalData: additionalData, delegateObject: delegate) + MVMCoreActionHandler.shared()?.handleAction(with: json, additionalData: additionalData, delegateObject: delegate) } })) Label.setGestureInteraction(for: label) } @@ -436,7 +523,7 @@ extension Label { // MARK: - UIControl functionality Override extension Label { - @objc func textLinkTapped(_ gesture: UITapGestureRecognizer) { + @objc private func textLinkTapped(_ gesture: UITapGestureRecognizer) { for clause in clauses { if gesture.didTapAttributedTextInLabel(self, inRange: clause.range) { @@ -516,6 +603,7 @@ extension Label { // MARK: - UITapGestureRecognizer Override extension UITapGestureRecognizer { + func didTapAttributedTextInLabel(_ label: Label, inRange targetRange: NSRange) -> Bool { guard let attributedText = label.attributedText else { return false }