From efbb68b4cd5c7cdb5aab4ee2a301389cbcdc19a2 Mon Sep 17 00:00:00 2001 From: Kevin G Christiano Date: Thu, 19 Sep 2019 14:09:51 -0400 Subject: [PATCH] latest. not perfect. --- MVMCoreUI/Atoms/Views/Label.swift | 63 ++++++++++++++----- .../Atoms/Views/LabelWithInternalButton.swift | 4 +- 2 files changed, 49 insertions(+), 18 deletions(-) diff --git a/MVMCoreUI/Atoms/Views/Label.swift b/MVMCoreUI/Atoms/Views/Label.swift index c9fa1b06..aa677cd1 100644 --- a/MVMCoreUI/Atoms/Views/Label.swift +++ b/MVMCoreUI/Atoms/Views/Label.swift @@ -42,6 +42,7 @@ public typealias ActionBlock = () -> () // MARK: - Multi-Action Text //------------------------------------------------------ + /// Data store of the tappable ranges of the text. public var clauses: [ActionableClause] = [] { didSet { isUserInteractionEnabled = !clauses.isEmpty @@ -114,6 +115,29 @@ public typealias ActionBlock = () -> () standardFontSize = size } + /// Convenience to init Label as a TextButton. All text will behave as a link. + @objc convenience public init(text: String, actionBlock: @escaping ActionBlock) { + self.init() + self.text = text + setTextLinkState(range: getRange, actionBlock: actionBlock) + } + + /// Convenience to init Label where the provided text will be marked as tappable by the given range. + @objc convenience public init(text: String, range: NSRange, actionBlock: @escaping ActionBlock) { + self.init() + self.text = text + setTextLinkState(range: range, actionBlock: actionBlock) + } + + /// Convenience to init Label with the link comprised of range, actionMap and delegateObject + @objc convenience public init(text: String, range: NSRange, actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) { + self.init() + self.text = text + if let actionBlock = Label.createActionBlockFor(label: self, actionMap: actionMap, additionalData: additionalData, delegateObject: delegateObject) { + setTextLinkState(range: range, actionBlock: actionBlock) + } + } + //------------------------------------------------------ // MARK: - Factory Functions //------------------------------------------------------ @@ -309,8 +333,9 @@ public typealias ActionBlock = () -> () guard let actionLabel = label as? Label else { continue } actionLabel.addActionAttributes(range: range, string: attributedString) - let actionBlock = actionLabel.createActionBlockFrom(actionMap: json, additionalData: additionalData, delegateObject: delegate) - actionLabel.appendActionableClause(range: range, actionBlock: actionBlock) + if let actionBlock = Label.createActionBlockFor(label: actionLabel, actionMap: json, additionalData: additionalData, delegateObject: delegate) { + actionLabel.appendActionableClause(range: range, actionBlock: actionBlock) + } default: continue @@ -563,9 +588,10 @@ extension Label { clauses = [] } - public func createActionBlockFrom(actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) -> ActionBlock { - return { [weak self] in - if let wSelf = self, (delegateObject as? MVMCoreUIDelegateObject)?.buttonDelegate?.button?(wSelf, shouldPerformActionWithMap: actionMap, additionalData: additionalData) ?? true { + public static func createActionBlockFor(label: Label?, actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) -> ActionBlock? { + guard let label = label else { return nil } + return { + if (delegateObject as? MVMCoreUIDelegateObject)?.buttonDelegate?.button?(label, shouldPerformActionWithMap: actionMap, additionalData: additionalData) ?? true { MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject) } } @@ -595,8 +621,7 @@ extension Label { */ @objc public func addTappableLinkAttribute(range: NSRange, actionBlock: @escaping ActionBlock) { - setActionAttributes(range: range) - appendActionableClause(range: range, actionBlock: actionBlock) + setTextLinkState(range: range, actionBlock: actionBlock) } /** @@ -610,22 +635,28 @@ extension Label { */ @objc public func addTappableLinkAttribute(range: NSRange, actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) { - setActionAttributes(range: range) - let actionBlock = createActionBlockFrom(actionMap: actionMap, additionalData: additionalData, delegateObject: delegateObject) - appendActionableClause(range: range, actionBlock: actionBlock) + if let actionBlock = Label.createActionBlockFor(label: self, actionMap: actionMap, additionalData: additionalData, delegateObject: delegateObject) { + setTextLinkState(range: range, actionBlock: actionBlock) + } } @objc public func makeAllTextLinkable(actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) { - - setActionAttributes(range: getRange) - let actionBlock = createActionBlockFrom(actionMap: actionMap, additionalData: additionalData, delegateObject: delegateObject) - appendActionableClause(range: getRange, actionBlock: actionBlock) + + if let actionBlock = Label.createActionBlockFor(label: self, actionMap: actionMap, additionalData: additionalData, delegateObject: delegateObject) { + setTextLinkState(range: getRange, actionBlock: actionBlock) + } } @objc public func makeAllTextLinkable(actionBlock: @escaping ActionBlock) { - setActionAttributes(range: getRange) - appendActionableClause(range: getRange, actionBlock: actionBlock) + setTextLinkState(range: getRange, actionBlock: actionBlock) + } + + /// Underlines the tappable region and stores the tap logic for interation. + private func setTextLinkState(range: NSRange, actionBlock: @escaping ActionBlock) { + + setActionAttributes(range: range) + appendActionableClause(range: range, actionBlock: actionBlock) } @objc private func textLinkTapped(_ gesture: UITapGestureRecognizer) { diff --git a/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift b/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift index ff2e751d..44f254f4 100644 --- a/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift +++ b/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift @@ -207,7 +207,7 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt @objc public func setActionMap(_ actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) { - actionBlock = label?.createActionBlockFrom(actionMap: actionMap, additionalData: additionalData, delegateObject: delegateObject) + actionBlock = Label.createActionBlockFor(label: label, actionMap: actionMap, additionalData: additionalData, delegateObject: delegateObject) } //------------------------------------------------------ @@ -377,7 +377,7 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt actionText = actionMap?.optionalStringForKey(KeyTitle) backText = actionMap?.optionalStringForKey(KeyTitlePostfix) text = getTextFromStringComponents() - actionBlock = label?.createActionBlockFrom(actionMap: actionMap, additionalData: additionalData, delegateObject: delegateObject) + actionBlock = Label.createActionBlockFor(label: label, actionMap: actionMap, additionalData: additionalData, delegateObject: delegateObject) setLabelAttributes() }