Working with ranges. Overall improvement of swift code.

This commit is contained in:
Christiano, Kevin 2019-03-29 16:37:51 -04:00
parent 00ebbc5b70
commit c791d78671

View File

@ -10,6 +10,7 @@
import MVMCore import MVMCore
public typealias ActionBlock = () -> Void public typealias ActionBlock = () -> Void
private typealias ActionIndiciesTuple = (startIndex: String.Index?, endIndex: String.Index?, revisedText: String?)
public typealias ActionObjectDelegate = (NSObject & MVMCoreActionDelegateProtocol) public typealias ActionObjectDelegate = (NSObject & MVMCoreActionDelegateProtocol)
public typealias ButtonObjectDelegate = (NSObject & ButtonDelegateProtocol) public typealias ButtonObjectDelegate = (NSObject & ButtonDelegateProtocol)
public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProtocol & MVMCoreLoadDelegateProtocol & MVMCorePresentationDelegateProtocol & NSObjectProtocol public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProtocol & MVMCoreLoadDelegateProtocol & MVMCorePresentationDelegateProtocol & NSObjectProtocol
@ -23,15 +24,18 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
public var actionBlock: ActionBlock? public var actionBlock: ActionBlock?
public weak var label: MFLabel? public weak var label: MFLabel?
public var alternateAttributeForActionText: String? // FIXME: I think there are scenarios where attributed text is being set with attributes but there is no text to set.
public var attributedText: NSAttributedString? { public var attributedText: NSAttributedString? {
didSet(newAttributedText) { didSet(newAttributedText) {
if newAttributedText != nil { if let newAttribText = newAttributedText, !newAttribText.string.isEmpty {
let mutableAttributedText = newAttributedText as? NSMutableAttributedString let mutableAttributedText = newAttribText as? NSMutableAttributedString
let paragraphStyle = NSMutableParagraphStyle() let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = CGFloat(LabelWithInternalButtonLineSpace) paragraphStyle.lineSpacing = CGFloat(LabelWithInternalButtonLineSpace)
mutableAttributedText?.addAttribute(.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: newAttributedText?.length ?? 0))
if newAttribText.length > 0 {
mutableAttributedText?.addAttribute(.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: newAttribText.length))
}
if let mutableAttText = mutableAttributedText { if let mutableAttText = mutableAttributedText {
label?.attributedText = mutableAttText label?.attributedText = mutableAttText
@ -41,10 +45,10 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
} }
// By default, it will follow most of the font standard in zepplin, and should need to be changed // By default, it will follow most of the font standard in zepplin, and should need to be changed
public var normalTextFont: UIFont? public var normalTextFont: UIFont? = MFStyler.fontB2()
public var actionTextFont: UIFont? public var actionTextFont: UIFont? = MFStyler.fontB2()
public var normalTextColor: UIColor? public var normalTextColor: UIColor = .black
public var actionTextColor: UIColor? public var actionTextColor: UIColor = .black
public var makeWholeViewClickable = false public var makeWholeViewClickable = false
@ -89,13 +93,7 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
setup() setup()
} }
public init(frontText: String?, public init(frontText: String?, actionText: String?, backText: String?, actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, actionDelegate delegate: ActionObjectDelegate?, buttonDelegate: ButtonObjectDelegate?) {
actionText: String?,
backText: String?,
actionMap: [AnyHashable: Any]?,
additionalData: [AnyHashable: Any]?,
actionDelegate delegate: ActionObjectDelegate?,
buttonDelegate: ButtonObjectDelegate?) {
super.init(frame: CGRect.zero) super.init(frame: CGRect.zero)
setFrontText(frontText, actionText: actionText, actionMap: actionMap, backText: backText, additionalData: additionalData, delegate: delegate, buttonDelegate: buttonDelegate) setFrontText(frontText, actionText: actionText, actionMap: actionMap, backText: backText, additionalData: additionalData, delegate: delegate, buttonDelegate: buttonDelegate)
@ -103,6 +101,7 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
// MARK: - legacy // MARK: - legacy
public init(frontText: String?, actionText: String?, backText: String?, actionBlock block: ActionBlock?) { public init(frontText: String?, actionText: String?, backText: String?, actionBlock block: ActionBlock?) {
super.init(frame: CGRect.zero) super.init(frame: CGRect.zero)
self.frontText = frontText self.frontText = frontText
self.actionText = actionText self.actionText = actionText
@ -112,18 +111,9 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
setup() setup()
} }
public convenience init(actionMap: [AnyHashable: Any]?, public convenience init(actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, actionDelegate delegate: ActionObjectDelegate?, buttonDelegate: ButtonObjectDelegate?) {
additionalData: [AnyHashable: Any]?,
actionDelegate delegate: ActionObjectDelegate?,
buttonDelegate: ButtonObjectDelegate?) {
self.init(frontText: actionMap?.optionalStringForKey(KeyTitlePrefix), self.init(frontText: actionMap?.optionalStringForKey(KeyTitlePrefix), actionText: actionMap?.optionalStringForKey(KeyTitle), backText: actionMap?.optionalStringForKey(KeyTitlePostfix), actionMap: actionMap, additionalData: additionalData, actionDelegate: delegate, buttonDelegate: buttonDelegate)
actionText: actionMap?.optionalStringForKey(KeyTitle),
backText: actionMap?.optionalStringForKey(KeyTitlePostfix),
actionMap: actionMap,
additionalData: additionalData,
actionDelegate: delegate,
buttonDelegate: buttonDelegate)
} }
public convenience init(frontText: String?, backText: String?, actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, actionDelegate delegate: ActionObjectDelegate?, buttonDelegate: ButtonObjectDelegate?) { public convenience init(frontText: String?, backText: String?, actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, actionDelegate delegate: ActionObjectDelegate?, buttonDelegate: ButtonObjectDelegate?) {
@ -187,22 +177,6 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
label.sizeToFit() label.sizeToFit()
} }
if normalTextColor == nil {
normalTextColor = .black
}
if actionTextColor == nil {
actionTextColor = .black
}
if normalTextFont == nil {
normalTextFont = MFStyler.fontB2()
}
if actionTextFont == nil {
actionTextFont = MFStyler.fontB2()
}
//adding the underline //adding the underline
setAlternateActionTextAttributes([NSAttributedString.Key.underlineStyle: NSNumber(value: NSUnderlineStyle.single.rawValue)]) setAlternateActionTextAttributes([NSAttributedString.Key.underlineStyle: NSNumber(value: NSUnderlineStyle.single.rawValue)])
@ -210,7 +184,8 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
self.label?.accessibilityTraits = .button self.label?.accessibilityTraits = .button
} }
private func setActionMap(_ actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, actionDelegate delegate: ActionObjectDelegate?, buttonDelegate: ButtonObjectDelegate?) { private func
setActionMap(_ actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, actionDelegate delegate: ActionObjectDelegate?, buttonDelegate: ButtonObjectDelegate?) {
weak var weakSelf: LabelWithInternalButton? = self weak var weakSelf: LabelWithInternalButton? = self
weak var weakDelegate: ActionObjectDelegate? = delegate weak var weakDelegate: ActionObjectDelegate? = delegate
@ -303,7 +278,7 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
@objc public func updateView(_ size: CGFloat) { @objc public func updateView(_ size: CGFloat) {
//reset font for app size change // Reset font for app size change
normalTextFont = MFStyler.fontB2() normalTextFont = MFStyler.fontB2()
actionTextFont = MFStyler.fontB2() actionTextFont = MFStyler.fontB2()
label?.attributedText = attributedText label?.attributedText = attributedText
@ -364,7 +339,7 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
frontText?.append(" ") frontText?.append(" ")
} }
if let actionTxt = actionText, !actionTxt.isEmpty { if let actionTxt = actionText, !actionTxt.isEmpty, let backTxt = backText, !backTxt.isEmpty {
actionText?.append(" ") actionText?.append(" ")
} }
@ -376,16 +351,6 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
return NSRange(location: frontText?.count ?? 0, length: actionText?.count ?? 0) return NSRange(location: frontText?.count ?? 0, length: actionText?.count ?? 0)
} }
private func getFrontRange() -> NSRange {
return NSRange(location: 0, length: frontText?.count ?? 0)
}
private func getBackRange() -> NSRange {
return NSRange(location: (frontText?.count ?? 0) + (actionText?.count ?? 0), length: backText?.count ?? 0)
}
private func getRangeArrayOfWords(in string: String?, withInitalIndex index: Int) -> [Any]? { private func getRangeArrayOfWords(in string: String?, withInitalIndex index: Int) -> [Any]? {
var index = index var index = index
@ -427,54 +392,42 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
private func setText(_ text: String?, startTag: String?, endTag: String?) { private func setText(_ text: String?, startTag: String?, endTag: String?) {
let _text = text guard let actionRange: ActionIndiciesTuple = rangeOfText(text, startTag: startTag, endTag: endTag) else { return }
let actionRange: NSRange = rangeOfText(_text, startTag: startTag, endTag: endTag)
frontText = (_text as NSString?)?.substring(with: NSRange(location: 0, length: actionRange.location)) if let revisedText = actionRange.revisedText, let startBraceIndex = actionRange.startIndex, let endBraceIndex = actionRange.endIndex {
actionText = (_text as NSString?)?.substring(with: actionRange)
frontText = String(revisedText[revisedText.startIndex..<startBraceIndex]).trimmingCharacters(in: .whitespaces)
if let frontTextCount = frontText?.count, let actiontextCount = actionText?.count { actionText = String(revisedText[startBraceIndex..<endBraceIndex]).trimmingCharacters(in: .whitespaces)
backText = (_text as NSString?)?.substring(with: NSRange(location: frontTextCount + actiontextCount, length: (_text?.count ?? 0) - frontTextCount - actiontextCount)) backText = String(revisedText[endBraceIndex...]).trimmingCharacters(in: .whitespaces)
} }
self.text = getTextFromStringComponents() self.text = getTextFromStringComponents()
setup() setup()
} }
// Not used private func rangeOfText(_ text: String?, startTag: String?, endTag: String?) -> ActionIndiciesTuple? {
private func rangeOfCurlyBracedText(_ text: String?) -> NSRange {
return rangeOfText(text, startTag: "{", endTag: "}") var fullText = text ?? ""
}
// TODO: Review this
private func rangeOfText(_ text: String?, startTag: String?, endTag: String?) -> NSRange {
var fullText = text guard let start = startTag, let end = endTag else { return nil }
var range = NSRange(location: 0, length: 0)
let rangeOfLeftBrace: NSRange? = (fullText as NSString?)?.range(of: startTag ?? "")
if rangeOfLeftBrace?.location != NSNotFound { if !fullText.contains(Character(start)) && !fullText.contains(Character(end)) {
return nil
if let rangeOfLeftBrace = rangeOfLeftBrace {
fullText = (fullText as NSString?)?.replacingCharacters(in: rangeOfLeftBrace, with: "")
}
let rangeOfRightBrace: NSRange? = (fullText as NSString?)?.range(of: endTag ?? "")
if rangeOfRightBrace?.location != NSNotFound {
let length: Int = (rangeOfRightBrace?.location ?? 0) - (rangeOfLeftBrace?.location ?? 0)
if length > 0 {
range = NSRange(location: rangeOfLeftBrace?.location ?? 0, length: length)
if let rangeOfRightBrace = rangeOfRightBrace {
fullText = (fullText as NSString?)?.replacingCharacters(in: rangeOfRightBrace, with: "")
}
}
}
} }
return range var actionRange: ActionIndiciesTuple
if let leftBrace = startTag, let rightBrace = endTag {
actionRange.startIndex = fullText.firstIndex(of: Character(leftBrace))
fullText = fullText.replacingOccurrences(of: leftBrace, with: "")
actionRange.endIndex = fullText.firstIndex(of: Character(rightBrace))
fullText = fullText.replacingOccurrences(of: rightBrace, with: "")
}
self.text = fullText
actionRange.revisedText = fullText
return actionRange
} }
@objc public func setActionMap(_ actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, actionDelegate delegate: ActionObjectDelegate?) { @objc public func setActionMap(_ actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, actionDelegate delegate: ActionObjectDelegate?) {
@ -520,21 +473,38 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
if let theseAttributes = attributes as? [NSAttributedString.Key: Any], let thisAttributedText = attributedText { if let theseAttributes = attributes as? [NSAttributedString.Key: Any], let thisAttributedText = attributedText {
let attributedString = NSMutableAttributedString(attributedString: thisAttributedText) let attributedString = NSMutableAttributedString(attributedString: thisAttributedText)
attributedString.addAttributes(theseAttributes, range: getActionRange()) if !attributedString.string.isEmpty {
attributedString.addAttributes(theseAttributes, range: getActionRange())
}
attributedText = attributedString attributedText = attributedString
} }
} }
@objc public func setAlternateNormalTextAttributes(_ attributes: [AnyHashable: Any]?) { @objc public func setAlternateNormalTextAttributes(_ attributes: [AnyHashable: Any]?) {
if let thisAttributedText = attributedText, let theseAttributes = attributes as? [NSAttributedString.Key: Any] { if let _attributedText = attributedText, let _attributes = attributes as? [NSAttributedString.Key: Any] {
let attributedString = NSMutableAttributedString(attributedString: thisAttributedText) let attributedString = NSMutableAttributedString(attributedString: _attributedText)
attributedString.addAttributes(theseAttributes, range: getFrontRange()) if !attributedString.string.isEmpty {
attributedString.addAttributes(theseAttributes, range: getBackRange()) attributedString.addAttributes(_attributes, range: getFrontRange())
attributedString.addAttributes(_attributes, range: getBackRange())
}
attributedText = attributedString attributedText = attributedString
} }
} }
private func getFrontRange() -> NSRange {
return NSRange(location: 0, length: frontText?.count ?? 0)
}
private func getBackRange() -> NSRange {
let textLocation: Int = (frontText?.count ?? 0) + (actionText?.count ?? 0)
let rangeLength: Int = backText?.count ?? 0
return NSRange(location: textLocation, length: rangeLength)
}
@objc public func setActionTextString(_ actionText: String?) { @objc public func setActionTextString(_ actionText: String?) {
self.actionText = actionText self.actionText = actionText
@ -588,10 +558,8 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
return UIAccessibilityCustomAction() return UIAccessibilityCustomAction()
} }
} }
extension LabelWithInternalButton: MVMCoreUIMoleculeViewProtocol { extension LabelWithInternalButton: MVMCoreUIMoleculeViewProtocol {
//------------------------------------------------------ //------------------------------------------------------
// MARK: - Atomization // MARK: - Atomization
@ -600,48 +568,70 @@ extension LabelWithInternalButton: MVMCoreUIMoleculeViewProtocol {
// Default values for view. // Default values for view.
@objc open func setAsMolecule() { @objc open func setAsMolecule() {
/*
var frontText: String?
var actionText: String?
var backText: String?
var attributedText: NSAttributedString?
// By default, it will follow most of the font standard in zepplin, and should need to be changed
var normalTextFont: UIFont?
var actionTextFont: UIFont?
var normalTextColor: UIColor?
var actionTextColor: UIColor?
var alternateAttributeForActionText: String?
var makeWholeViewClickable = false
*/
} }
@objc open func setWithJSON(_ json: [AnyHashable: Any]?, delegate: NSObject?, additionalData: [AnyHashable: Any]?) { @objc open func setWithJSON(_ json: [AnyHashable: Any]?, delegate: NSObject?, additionalData: [AnyHashable: Any]?) {
// Configure class properties with JSON values // Configure class properties with JSON values
guard let jsonDictionary = json else { return } guard let dictionary = json else { return }
if let backgroundColorHex = jsonDictionary[KeyBackgroundColor] as? String { if let backgroundColorHex = dictionary[KeyBackgroundColor] as? String {
backgroundColor = UIColor.mfGet(forHex: backgroundColorHex) self.backgroundColor = UIColor.mfGet(forHex: backgroundColorHex)
} }
// if let strokeColorHex = jsonDictionary["strokeColor"] as? String { if let normalTextFont = dictionary["normalTextFont"] as? String, let normalSize = dictionary["normalSize"] as? CGFloat {
// strokeColor = UIColor.mfGet(forHex: strokeColorHex) self.normalTextFont = UIFont(name: normalTextFont, size: normalSize)
// } }
//
// if let isHiddenValue = jsonDictionary[KeyIsHidden] as? Bool {
// isHidden = isHiddenValue
// }
//
// if let isOpaqueValue = jsonDictionary[KeyIsOpaque] as? Bool {
// isOpaque = isOpaqueValue
// }
//
// if let lineWidthValue = jsonDictionary["lineWidth"] as? CGFloat {
// lineWidth = lineWidthValue
// }
if let actionTextFont = dictionary["actionTextFont"] as? String, let actionSize = dictionary["actionSize"] as? CGFloat {
self.actionTextFont = UIFont(name: actionTextFont, size: actionSize)
}
if let normalTextColorHex = dictionary["normalTextColor"] as? String {
self.normalTextColor = UIColor.mfGet(forHex: normalTextColorHex)
}
if let actionTextColorHex = dictionary["actionTextColor"] as? String {
self.actionTextColor = UIColor.mfGet(forHex: actionTextColorHex)
}
if let makeWholeViewClickable = dictionary["makeWholeViewClickable"] as? Bool {
self.makeWholeViewClickable = makeWholeViewClickable
}
if let frontText = dictionary["frontText"] as? String {
self.frontText = frontText
}
if let backText = dictionary["backText"] as? String {
self.backText = backText
}
if let actionText = dictionary["actionText"] as? String {
self.actionText = actionText
}
// Want this to be last because it has a didSet feature.
if let text = dictionary["text"] as? String {
self.text = text
}
} }
} }
/*
public var actionBlock: ActionBlock?
public var alternateAttributeForActionText: String?
let mutableAttributedText = newAttributedText as? NSMutableAttributedString
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = CGFloat(LabelWithInternalButtonLineSpace)
mutableAttributedText?.addAttribute(.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: newAttributedText?.length ?? 0))
override open var isEnabled: Bool {
didSet {
alpha = isEnabled ? 1 : DisableOppacity
}
*/