diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 40733e65..a3219890 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -152,6 +152,7 @@ D2C5001921F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m in Sources */ = {isa = PBXBuildFile; fileRef = D2C5001721F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m */; }; D2C5001D21F8EE67001DA659 /* LabelWithInternalButton.h in Headers */ = {isa = PBXBuildFile; fileRef = D2C5001B21F8EE66001DA659 /* LabelWithInternalButton.h */; settings = {ATTRIBUTES = (Public, ); }; }; D2C5001E21F8EE67001DA659 /* LabelWithInternalButton.m in Sources */ = {isa = PBXBuildFile; fileRef = D2C5001C21F8EE66001DA659 /* LabelWithInternalButton.m */; }; + DB891E832253FA8500022516 /* Label.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB891E822253FA8500022516 /* Label.swift */; }; DBC4391822442197001AB423 /* CaretView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391622442196001AB423 /* CaretView.swift */; }; DBC4391922442197001AB423 /* DashLine.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391722442197001AB423 /* DashLine.swift */; }; DBC4391B224421A0001AB423 /* CaretButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391A224421A0001AB423 /* CaretButton.swift */; }; @@ -307,6 +308,7 @@ D2C5001721F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUIViewControllerMappingObject.m; sourceTree = ""; }; D2C5001B21F8EE66001DA659 /* LabelWithInternalButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LabelWithInternalButton.h; sourceTree = ""; }; D2C5001C21F8EE66001DA659 /* LabelWithInternalButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LabelWithInternalButton.m; sourceTree = ""; }; + DB891E822253FA8500022516 /* Label.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Label.swift; sourceTree = ""; }; DBC4391622442196001AB423 /* CaretView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CaretView.swift; sourceTree = ""; }; DBC4391722442197001AB423 /* DashLine.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DashLine.swift; sourceTree = ""; }; DBC4391A224421A0001AB423 /* CaretButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CaretButton.swift; sourceTree = ""; }; @@ -566,6 +568,7 @@ D22D1F19220341F50077CEC0 /* MVMCoreUICheckBox.m */, D22D1F44220496A30077CEC0 /* MVMCoreUISwitch.h */, D22D1F45220496A30077CEC0 /* MVMCoreUISwitch.m */, + DB891E822253FA8500022516 /* Label.swift */, ); path = Views; sourceTree = ""; @@ -867,6 +870,7 @@ D29DF2EF21ECEAE1003B2FB9 /* MFFonts.m in Sources */, D282AACB2243C61700C46919 /* ButtonView.swift in Sources */, D29DF2AE21E7B3A4003B2FB9 /* MFTextView.m in Sources */, + DB891E832253FA8500022516 /* Label.swift in Sources */, D29DF18121E69E50003B2FB9 /* MFView.m in Sources */, D29DF18321E69E54003B2FB9 /* SeparatorView.m in Sources */, D29DF17A21E69E1F003B2FB9 /* MFCustomButton.m in Sources */, diff --git a/MVMCoreUI/Atoms/Views/Label.swift b/MVMCoreUI/Atoms/Views/Label.swift new file mode 100644 index 00000000..1f48273a --- /dev/null +++ b/MVMCoreUI/Atoms/Views/Label.swift @@ -0,0 +1,388 @@ +// +// Label.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 3/22/17. +// Converted by Christiano, Kevin on 4/2/19. +// Copyright © 2019 Verizon Wireless. All rights reserved. +// + +import MVMCore +import MVMCoreUI + + +class Label: UILabel, MVMCoreViewProtocol, MVMCoreUIMoleculeViewProtocol { + //------------------------------------------------------ + // MARK: - Properties + //------------------------------------------------------ + + // Set this property if you want updateView to update the font based on this standard and the size passed in. + var standardFontSize: CGFloat = 0.0 + + // Set this to use a custom sizing object during updateView instead of the standard. + var sizeObject: MFSizeObject? + + private var scaleSize: NSNumber? + + // Used for scaling the font in updateView. + private var originalAttributedString: NSAttributedString? + + override var accessibilityTraits: UIAccessibilityTraits { + get { + return super.accessibilityTraits + } + set(accessibilityTraits) { + if accessibilityTraits.rawValue & UIAccessibilityTraits.header.rawValue != 0 { + let noHeaderTraits: UIAccessibilityTraits = UIAccessibilityTraits(rawValue: accessibilityTraits.rawValue - UIAccessibilityTraits.header.rawValue) + super.accessibilityTraits = noHeaderTraits + } else { + super.accessibilityTraits = accessibilityTraits + } + } + } + + var hasText: Bool { + return text.length > 0 || (attributedText?.length ?? 0) > 0 + } + + //------------------------------------------------------ + // MARK: - Initialization + //------------------------------------------------------ + + func setupView() { + backgroundColor = UIColor.clear + numberOfLines = 0 + lineBreakMode = NSLineBreakMode.byWordWrapping + translatesAutoresizingMaskIntoConstraints = false + } + + init() { + setupView() + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + setupView() + } + + override init(frame: CGRect) { + super.init(frame: frame) + setupView() + } + + convenience init(standardFontSize size: CGFloat) { + self.init() + standardFontSize = size + } + + func updateView(_ size: CGFloat) { + + scaleSize = NSNumber(value: Float(size)) + + if originalAttributedString { + var attributedString = NSMutableAttributedString(attributedString: originalAttributedString) + attributedString.removeAttribute(.font, range: NSRange(location: 0, length: attributedString.length)) + originalAttributedString.enumerateAttribute(.font, in: NSRange(location: 0, length: originalAttributedString.length), options: [], using: { value, range, stop in + // Loop the original attributed string, resize the fonts. + let font: UIFont? = value?.withSize(MFStyler.sizeObjectGeneric(forCurrentDevice: value?.pointSize).getValueBased(onSize: size)) + attributedString.addAttribute(.font, value: font, range: range) + }) + attributedText = attributedString + } else if !fequal(standardFontSize, 0) { + var sizeObject: MFSizeObject? = self.sizeObject + if sizeObject == nil { + sizeObject = MFStyler.sizeObjectGeneric(forCurrentDevice: standardFontSize) + } + self.font = self.font.withSize(sizeObject?.getValueBased(onSize: size) ?? 0.0) + } + } + + func setFont(_ font: UIFont, scale: Bool) { + self.font = font + setScale(scale) + } + + func setScale(_ scale: Bool) { + if scale { + standardFontSize = font.pointSize + updateView((scaleSize ? CGFloat(scaleSize?.floatValue ?? 0) : MVMCoreUISplitViewController.getApplicationViewWidth())) + } else { + standardFontSize = 0 + } + } + + class func label() -> Label { + return Label(frame: CGRect.zero) + } + + class func commonLabelB2(_ scale: Bool) -> Label { + let label = Label.label() + label.styleB2(scale) + return label + } + + class func commonLabelBody(withSize size: CGFloat, scale: Bool) -> Label { + let label = Label.label() + label.styleBody(withSize: size, scale: scale) + return label + } + + class func commonLabelBodyBold(_ scale: Bool) -> Label { + let label = Label() + label.styleBodyBold(scale) + return label + } + + class func commonLabelBodyLighter(_ scale: Bool) -> Label { + let label = Label() + label.styleBodyLighter(scale) + return label + } + + class func commonLabelBodyLarge(_ scale: Bool) -> Label { + let label = Label() + label.styleBodyLarge(scale) + return label + } + + class func commonLabelH1(_ scale: Bool) -> Label { + let label = Label() + label.styleH1(scale) + return label + } + + class func commonLabelH2(_ scale: Bool) -> Label { + let label = Label() + label.styleH2(scale) + return label + } + + class func commonLabelHeadlineSmall(_ scale: Bool) -> Label { + let label = Label() + label.styleHeadlineSmall(scale) + return label + } + + class func commonLabelHeadline(withSize size: CGFloat, scale: Bool) -> Label { + let label = Label() + label.styleHeadline(withSize: size, scale: scale) + return label + } + + class func commonLabelHeadlineBlack(withSize size: CGFloat, scale: Bool) -> Label { + let label = Label() + label.styleHeadlineBlack(withSize: size, scale: scale) + return label + } + + class func commonLabelH3(_ scale: Bool) -> Label { + let label = Label() + label.styleH3(scale) + return label + } + + class func commonLabelSubheadBold(_ scale: Bool) -> Label { + let label = Label() + label.styleSubheadBold(scale) + return label + } + + class func commonLabelSubheadBoldLarge(_ scale: Bool) -> Label { + let label = Label() + label.styleSubheadBoldLarge(scale) + return label + } + + class func commonLabelB3(_ scale: Bool) -> Label { + let label = Label() + label.styleB3(scale) + return label + } + + class func commonLabelFeedMessage(_ scale: Bool) -> Label { + let label = Label() + label.styleFeedMessage(scale) + return label + } + + class func commonLabelFeedSubMessage(_ scale: Bool) -> Label { + let label = Label() + label.styleFeedSubMessage(scale) + return label + } + + class func commonLabelFeedHeadline(_ scale: Bool) -> Label { + let label = Label() + label.styleFeedHeadline(scale) + return label + } + + class func commonLabelFeedTitle(_ scale: Bool) -> Label { + let label = Label() + label.styleFeedTitle(scale) + return label + } + + class func commonLabelPlanCardTitle(_ scale: Bool) -> Label { + let label = Label() + label.stylePlanCardTitle(scale) + return label + } + + class func commonLabelB1(_ scale: Bool) -> Label { + let label = Label() + label.styleB1(scale) + return label + } + + class func commonLabelTopAlert(_ scale: Bool) -> Label { + let label = Label() + label.styleTopAlert(scale) + return label + } + + class func setLabel(_ label: UILabel?, withHTML html: String?) { + let data: Data? = html?.data(using: .utf8) + if data != nil { + var error: Error? = nil + if let data = data { + label?.attributedText = try? NSAttributedString(data: data, + options: [NSAttributedString.DocumentAttributeKey.documentType: NSAttributedString.DocumentType.html.rawValue as Any], + documentAttributes: nil) + } + if let labelError = error { + try? MVMCoreUILoggingHandler.shared()?.addError(toLog: MVMCoreErrorObject.createErrorObject(for: labelError, location: "LabelHTMLParse")) + } + } + } + + class func setUILabel(_ label: UILabel?, withJSON json: [AnyHashable: Any]?, delegate: NSObject?, additionalData: [AnyHashable: Any]?) { + + // TODO: !!! + } + + func setWithJSON(_ json: [AnyHashable: Any]?, delegate: NSObject?, additionalData: [AnyHashable: Any]?) { + Label.setUILabel(self, withJSON: json, delegate: delegate, additionalData: additionalData) + originalAttributedString = attributedText + } + + func styleB2(_ scale: Bool) { + MFStyler.styleLabelB2(self, genericScaling: false) + setScale(scale) + } + + func styleBody(withSize size: CGFloat, scale: Bool) { + MFStyler.styleLabelB2(self, size: size, genericScaling: false) + setScale(scale) + } + + func styleBodyBold(_ scale: Bool) { + MFStyler.styleLabelBodyBold(self, genericScaling: false) + setScale(scale) + } + + func styleBodyLighter(_ scale: Bool) { + MFStyler.styleLabelBodyLighter(self, genericScaling: false) + setScale(scale) + } + + func styleBodyLarge(_ scale: Bool) { + MFStyler.styleLabelBodyLarge(self, genericScaling: false) + setScale(scale) + } + + func styleH1(_ scale: Bool) { + MFStyler.styleLabelH1(self, genericScaling: false) + setScale(scale) + } + + func styleH2(_ scale: Bool) { + MFStyler.styleLabelH2(self, genericScaling: false) + setScale(scale) + } + + func styleHeadlineLarge(_ scale: Bool) { + MFStyler.styleLabelHeadlineLarge(self, genericScaling: false) + setScale(scale) + } + + func styleHeadlineSmall(_ scale: Bool) { + MFStyler.styleLabelHeadlineSmall(self, genericScaling: false) + setScale(scale) + } + + func styleHeadline(withSize size: CGFloat, scale: Bool) { + MFStyler.styleLabelH2(self, size: size, genericScaling: false) + setScale(scale) + } + + func styleHeadlineBlack(withSize size: CGFloat, scale: Bool) { + MFStyler.styleLabelHeadlineBlack(self, size: size, genericScaling: false) + setScale(scale) + } + + func styleH3(_ scale: Bool) { + MFStyler.styleLabelH3(self, genericScaling: false) + setScale(scale) + } + + func styleSubheadBold(_ scale: Bool) { + MFStyler.styleLabelSubheadBold(self, genericScaling: false) + setScale(scale) + } + + func styleSubheadBoldLarge(_ scale: Bool) { + MFStyler.styleLabelSubheadBoldLarge(self, genericScaling: false) + setScale(scale) + } + + func styleB3(_ scale: Bool) { + MFStyler.styleLabelB3(self, genericScaling: false) + setScale(scale) + } + + func styleFeedMessage(_ scale: Bool) { + MFStyler.styleLabelFeedMessage(self, genericScaling: false) + setScale(scale) + } + + func styleFeedSubMessage(_ scale: Bool) { + MFStyler.styleLabelFeedSubMessage(self, genericScaling: false) + setScale(scale) + } + + func styleFeedHeadline(_ scale: Bool) { + MFStyler.styleLabelHeadlineFeed(self, genericScaling: false) + setScale(scale) + } + + func styleFeedTitle(_ scale: Bool) { + MFStyler.styleFeedCardTitleLabel(self, genericScaling: false) + setScale(scale) + } + + func stylePlanCardTitle(_ scale: Bool) { + font = MFStyler.font(forPlanCardTitle: false) + setScale(scale) + } + + func styleB1(_ scale: Bool) { + MFStyler.styleLabelB1(self, genericScaling: false) + setScale(scale) + } + + func styleTableRow(_ scale: Bool) { + MFStyler.styleLabelB1(self, genericScaling: false) + setScale(scale) + } + + func styleTopAlert(_ scale: Bool) { + font = MFStyler.fontB1(false) + setScale(scale) + } + + func setFontH1(_ scale: Bool) { + font = MFStyler.fontH1(false) + setScale(scale) + } +}