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
public typealias ActionBlock = () -> Void
private typealias ActionIndiciesTuple = (startIndex: String.Index?, endIndex: String.Index?, revisedText: String?)
public typealias ActionObjectDelegate = (NSObject & MVMCoreActionDelegateProtocol)
public typealias ButtonObjectDelegate = (NSObject & ButtonDelegateProtocol)
public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProtocol & MVMCoreLoadDelegateProtocol & MVMCorePresentationDelegateProtocol & NSObjectProtocol
@ -23,15 +24,18 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
public var actionBlock: ActionBlock?
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? {
didSet(newAttributedText) {
if newAttributedText != nil {
let mutableAttributedText = newAttributedText as? NSMutableAttributedString
if let newAttribText = newAttributedText, !newAttribText.string.isEmpty {
let mutableAttributedText = newAttribText as? NSMutableAttributedString
let paragraphStyle = NSMutableParagraphStyle()
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 {
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
public var normalTextFont: UIFont?
public var actionTextFont: UIFont?
public var normalTextColor: UIColor?
public var actionTextColor: UIColor?
public var normalTextFont: UIFont? = MFStyler.fontB2()
public var actionTextFont: UIFont? = MFStyler.fontB2()
public var normalTextColor: UIColor = .black
public var actionTextColor: UIColor = .black
public var makeWholeViewClickable = false
@ -89,13 +93,7 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
setup()
}
public init(frontText: String?,
actionText: String?,
backText: String?,
actionMap: [AnyHashable: Any]?,
additionalData: [AnyHashable: Any]?,
actionDelegate delegate: ActionObjectDelegate?,
buttonDelegate: ButtonObjectDelegate?) {
public init(frontText: String?, actionText: String?, backText: String?, actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, actionDelegate delegate: ActionObjectDelegate?, buttonDelegate: ButtonObjectDelegate?) {
super.init(frame: CGRect.zero)
setFrontText(frontText, actionText: actionText, actionMap: actionMap, backText: backText, additionalData: additionalData, delegate: delegate, buttonDelegate: buttonDelegate)
@ -103,6 +101,7 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
// MARK: - legacy
public init(frontText: String?, actionText: String?, backText: String?, actionBlock block: ActionBlock?) {
super.init(frame: CGRect.zero)
self.frontText = frontText
self.actionText = actionText
@ -112,18 +111,9 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
setup()
}
public convenience init(actionMap: [AnyHashable: Any]?,
additionalData: [AnyHashable: Any]?,
actionDelegate delegate: ActionObjectDelegate?,
buttonDelegate: ButtonObjectDelegate?) {
public convenience init(actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, actionDelegate delegate: ActionObjectDelegate?, buttonDelegate: ButtonObjectDelegate?) {
self.init(frontText: actionMap?.optionalStringForKey(KeyTitlePrefix),
actionText: actionMap?.optionalStringForKey(KeyTitle),
backText: actionMap?.optionalStringForKey(KeyTitlePostfix),
actionMap: actionMap,
additionalData: additionalData,
actionDelegate: delegate,
buttonDelegate: buttonDelegate)
self.init(frontText: actionMap?.optionalStringForKey(KeyTitlePrefix), 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?) {
@ -187,22 +177,6 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
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
setAlternateActionTextAttributes([NSAttributedString.Key.underlineStyle: NSNumber(value: NSUnderlineStyle.single.rawValue)])
@ -210,7 +184,8 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
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 weakDelegate: ActionObjectDelegate? = delegate
@ -303,7 +278,7 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
@objc public func updateView(_ size: CGFloat) {
//reset font for app size change
// Reset font for app size change
normalTextFont = MFStyler.fontB2()
actionTextFont = MFStyler.fontB2()
label?.attributedText = attributedText
@ -364,7 +339,7 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
frontText?.append(" ")
}
if let actionTxt = actionText, !actionTxt.isEmpty {
if let actionTxt = actionText, !actionTxt.isEmpty, let backTxt = backText, !backTxt.isEmpty {
actionText?.append(" ")
}
@ -376,16 +351,6 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
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]? {
var index = index
@ -427,54 +392,42 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
private func setText(_ text: String?, startTag: String?, endTag: String?) {
let _text = text
let actionRange: NSRange = rangeOfText(_text, startTag: startTag, endTag: endTag)
guard let actionRange: ActionIndiciesTuple = rangeOfText(text, startTag: startTag, endTag: endTag) else { return }
frontText = (_text as NSString?)?.substring(with: NSRange(location: 0, length: actionRange.location))
actionText = (_text as NSString?)?.substring(with: actionRange)
if let frontTextCount = frontText?.count, let actiontextCount = actionText?.count {
backText = (_text as NSString?)?.substring(with: NSRange(location: frontTextCount + actiontextCount, length: (_text?.count ?? 0) - frontTextCount - actiontextCount))
if let revisedText = actionRange.revisedText, let startBraceIndex = actionRange.startIndex, let endBraceIndex = actionRange.endIndex {
frontText = String(revisedText[revisedText.startIndex..<startBraceIndex]).trimmingCharacters(in: .whitespaces)
actionText = String(revisedText[startBraceIndex..<endBraceIndex]).trimmingCharacters(in: .whitespaces)
backText = String(revisedText[endBraceIndex...]).trimmingCharacters(in: .whitespaces)
}
self.text = getTextFromStringComponents()
setup()
}
// Not used
private func rangeOfCurlyBracedText(_ text: String?) -> NSRange {
private func rangeOfText(_ text: String?, startTag: String?, endTag: String?) -> ActionIndiciesTuple? {
return rangeOfText(text, startTag: "{", endTag: "}")
}
// TODO: Review this
private func rangeOfText(_ text: String?, startTag: String?, endTag: String?) -> NSRange {
var fullText = text ?? ""
var fullText = text
var range = NSRange(location: 0, length: 0)
let rangeOfLeftBrace: NSRange? = (fullText as NSString?)?.range(of: startTag ?? "")
guard let start = startTag, let end = endTag else { return nil }
if rangeOfLeftBrace?.location != NSNotFound {
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: "")
}
}
}
if !fullText.contains(Character(start)) && !fullText.contains(Character(end)) {
return nil
}
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?) {
@ -520,21 +473,38 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
if let theseAttributes = attributes as? [NSAttributedString.Key: Any], let thisAttributedText = attributedText {
let attributedString = NSMutableAttributedString(attributedString: thisAttributedText)
attributedString.addAttributes(theseAttributes, range: getActionRange())
if !attributedString.string.isEmpty {
attributedString.addAttributes(theseAttributes, range: getActionRange())
}
attributedText = attributedString
}
}
@objc public func setAlternateNormalTextAttributes(_ attributes: [AnyHashable: Any]?) {
if let thisAttributedText = attributedText, let theseAttributes = attributes as? [NSAttributedString.Key: Any] {
let attributedString = NSMutableAttributedString(attributedString: thisAttributedText)
attributedString.addAttributes(theseAttributes, range: getFrontRange())
attributedString.addAttributes(theseAttributes, range: getBackRange())
if let _attributedText = attributedText, let _attributes = attributes as? [NSAttributedString.Key: Any] {
let attributedString = NSMutableAttributedString(attributedString: _attributedText)
if !attributedString.string.isEmpty {
attributedString.addAttributes(_attributes, range: getFrontRange())
attributedString.addAttributes(_attributes, range: getBackRange())
}
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?) {
self.actionText = actionText
@ -588,10 +558,8 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
return UIAccessibilityCustomAction()
}
}
extension LabelWithInternalButton: MVMCoreUIMoleculeViewProtocol {
//------------------------------------------------------
// MARK: - Atomization
@ -600,48 +568,70 @@ extension LabelWithInternalButton: MVMCoreUIMoleculeViewProtocol {
// Default values for view.
@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]?) {
// 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 {
backgroundColor = UIColor.mfGet(forHex: backgroundColorHex)
if let backgroundColorHex = dictionary[KeyBackgroundColor] as? String {
self.backgroundColor = UIColor.mfGet(forHex: backgroundColorHex)
}
// if let strokeColorHex = jsonDictionary["strokeColor"] as? String {
// strokeColor = UIColor.mfGet(forHex: strokeColorHex)
// }
//
// 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 normalTextFont = dictionary["normalTextFont"] as? String, let normalSize = dictionary["normalSize"] as? CGFloat {
self.normalTextFont = UIFont(name: normalTextFont, size: normalSize)
}
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
}
*/