diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/Item Dropdown/BaseItemPickerEntryField.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/Item Dropdown/BaseItemPickerEntryField.swift index 65c4448b..22a18b94 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/Item Dropdown/BaseItemPickerEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/Dropdown Fields/Item Dropdown/BaseItemPickerEntryField.swift @@ -74,7 +74,7 @@ extension BaseItemPickerEntryField { @objc open override func setAccessibilityString(_ accessibilityString: String?) { - var accessibilityString = accessibilityString ?? "" + let accessibilityString = accessibilityString ?? "" textField.accessibilityTraits = .staticText textField.accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "textfield_picker_item") textField.accessibilityLabel = "\(accessibilityString) \(textField.isEnabled ? "" : MVMCoreUIUtility.hardcodedString(withKey: "textfield_disabled_state") ?? "")" diff --git a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/TextEntryField.swift b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/TextEntryField.swift index a3780846..9d030d0f 100644 --- a/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/TextEntryField.swift +++ b/MVMCoreUI/Atomic/Atoms/FormFields/TextFields/TextEntryField.swift @@ -397,7 +397,7 @@ extension TextEntryField { @objc open override func setAccessibilityString(_ accessibilityString: String?) { - var accessibilityString = accessibilityString ?? "" + let accessibilityString = accessibilityString ?? "" textField.accessibilityLabel = "\(accessibilityString) \(textField.isEnabled ? "" : MVMCoreUIUtility.hardcodedString(withKey: "textfield_disabled_state") ?? "")" } diff --git a/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicatorModel.swift b/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicatorModel.swift index 3631bfc0..11bcdd8d 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicatorModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/CarouselIndicator/CarouselIndicatorModel.swift @@ -26,7 +26,7 @@ open class CarouselIndicatorModel: CarouselPagingModelProtocol, MoleculeModelPro /// Sets the current Index to focus on. public var currentIndex: Int = 0 public var animated: Bool = true - public var hidesForSinglePage: Bool = false + public var hidesForSinglePage: Bool = true public var inverted: Bool = false /// Set true to make the accessibility value as "Slide #currentPage of #totalPage", otherwise will be "Page #currentPage of #totalPage", default is false public var accessibilityHasSlidesInsteadOfPage: Bool = false diff --git a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyModel.swift b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyModel.swift index 093528d1..c8c1a633 100644 --- a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyModel.swift +++ b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/HeadlineBodyModel.swift @@ -94,7 +94,7 @@ open class HeadlineBodyModel: ParentMoleculeModelProtocol { public extension HeadlineBodyModel { func createHeaderTitleLockupModel(defaultStyle: Style = .header) throws -> TitleLockupModel { guard let headline = headline else { throw ModelRegistry.Error.decoderOther(message: "headline is required for this use case.") } - var body = self.body + let body = self.body switch style ?? defaultStyle { case .landingHeader: headline.fontStyle = Styler.Font.RegularTitle2XLarge @@ -106,7 +106,7 @@ public extension HeadlineBodyModel { headline.fontStyle = Styler.Font.RegularTitleXLarge body?.fontStyle = Styler.Font.RegularTitleMedium } - let model = try TitleLockupModel(title: headline, subTitle: body) + let model = TitleLockupModel(title: headline, subTitle: body) model.id = id return model } diff --git a/MVMCoreUI/Atomic/Organisms/Carousel/Carousel.swift b/MVMCoreUI/Atomic/Organisms/Carousel/Carousel.swift index c4f7d825..18d65559 100644 --- a/MVMCoreUI/Atomic/Organisms/Carousel/Carousel.swift +++ b/MVMCoreUI/Atomic/Organisms/Carousel/Carousel.swift @@ -69,7 +69,7 @@ open class Carousel: View { public var delegateObject: MVMCoreUIDelegateObject? private var size: CGFloat? - + // Updates the model and index. public func updateModelIndex() { (model as? CarouselModel)?.index = pageIndex @@ -90,12 +90,29 @@ open class Carousel: View { showPeaking(false) // Go to current cell. layoutIfNeeded is needed otherwise cellForItem returns nil for peaking logic. The dispatch is a sad way to ensure the collection view is ready to be scrolled. - guard let model = model as? CarouselModel, !model.molecules.isEmpty, - (model.paging == true || loop == true) else { return } + guard let model = model as? CarouselModel, !model.molecules.isEmpty else { return } + guard (model.paging == true || loop == true) else { + DispatchQueue.main.async { [self] in + updatePagerVisibility() + } + return + } DispatchQueue.main.async { [self] in collectionView.scrollToItem(at: IndexPath(row: currentIndex, section: 0), at: itemAlignment, animated: false) collectionView.layoutIfNeeded() showPeaking(true) + updatePagerVisibility() + } + } + + /// Updates if the pager is visible or not. + private func updatePagerVisibility() { + guard let pagingView = pagingView else { return } + let shouldHidePager = collectionView.contentSize.width < bounds.width + if (shouldHidePager && !pagingView.isHidden) || (!shouldHidePager && pagingView.isHidden) { + pagingView.isHidden = shouldHidePager + pagingBottomPin?.isActive = !shouldHidePager + delegateObject?.moleculeDelegate?.moleculeLayoutUpdated(self) } } @@ -140,16 +157,6 @@ open class Carousel: View { (cell as? MVMCoreViewProtocol)?.updateView(size) } layoutCollection() - - // Check must be dispatched to main for the layout to complete in layoutCollection. - DispatchQueue.main.async { [self] in - let shouldHidePager = molecules?.count ?? 0 < 2 || collectionView.contentSize.width < bounds.width - if let pagingView = pagingView, shouldHidePager != pagingView.isHidden { - pagingView.isHidden = shouldHidePager - pagingBottomPin?.isActive = !shouldHidePager - delegateObject?.moleculeDelegate?.moleculeLayoutUpdated(self) - } - } } //-------------------------------------------------- @@ -244,7 +251,7 @@ open class Carousel: View { var pagingView: (MoleculeViewProtocol & CarouselPageControlProtocol)? = nil if let molecule = molecule, - (!molecule.hidesForSinglePage || numberOfPages > 1) { + (numberOfPages > 1 || !molecule.hidesForSinglePage) { pagingView = ModelRegistry.createMolecule(molecule, delegateObject: delegateObject) as? (MoleculeViewProtocol & CarouselPageControlProtocol) pagingMoleculeName = molecule.moleculeName } else { diff --git a/MVMCoreUI/Behaviors/GetContactBehavior.swift b/MVMCoreUI/Behaviors/GetContactBehavior.swift index 6f9a3cd4..755c5706 100644 --- a/MVMCoreUI/Behaviors/GetContactBehavior.swift +++ b/MVMCoreUI/Behaviors/GetContactBehavior.swift @@ -35,16 +35,16 @@ public class PageGetContactBehavior: PageVisibilityBehavior { CNContactStore().requestAccess(for: .contacts) { [weak self] (access, error) in guard access, error == nil, - let rootMolecules = self?.delegate?.moleculeDelegate?.getRootMolecules() else { return } + let rootMolecules = delegateObject?.moleculeDelegate?.getRootMolecules() else { return } // Iterate models and provide contact self?.getContacts(for: rootMolecules) // Tell template to update - MVMCoreDispatchUtility.performBlock(onMainThread: { + Task { @MainActor in // TODO: move to protocol function instead - guard let controller = self?.delegate?.moleculeDelegate as? ViewController else { return } + guard let controller = delegateObject?.moleculeDelegate as? ViewController else { return } controller.handleNewData() - }) + } } } diff --git a/MVMCoreUI/Categories/UIColor+Extension.swift b/MVMCoreUI/Categories/UIColor+Extension.swift index 6f994254..6ddd1da1 100644 --- a/MVMCoreUI/Categories/UIColor+Extension.swift +++ b/MVMCoreUI/Categories/UIColor+Extension.swift @@ -19,7 +19,7 @@ extension UIColor { /// Dictionary to access brand approved colors by name. public static let names: [String: ColorHexTuple] = ["black": (.mvmBlack, "#000000"), "white": (.mvmWhite, "#FFFFFF"), - "red": (.mvmRed, "#F50A23"), + "red": (.mvmRed, "#EE0000"), "pink": (.mvmPink, "#D90368"), "pink33": (.mvmPink33, "#F2ABCD"), "pink66": (.mvmPink66, "#E6589B"), @@ -88,7 +88,7 @@ extension UIColor { // MARK: - Red //-------------------------------------------------- - /// HEX: ##F50A23 + /// HEX: #EE0000 @objc public static let mvmRed = UIColor.assetColor(named: "red") @@ -256,6 +256,7 @@ extension UIColor { return UIColor(named: name, in: MVMCoreUIUtility.bundleForMVMCoreUI(), compatibleWith: nil)! } + /// Returns a color corresponding to the passed in color name. @objc public static func mvmCoreUIColor(with name: String) -> UIColor? { return UIColor.names[name]?.uiColor diff --git a/MVMCoreUI/Categories/UIColor+MFConvenience.m b/MVMCoreUI/Categories/UIColor+MFConvenience.m index 77700413..d10672a8 100644 --- a/MVMCoreUI/Categories/UIColor+MFConvenience.m +++ b/MVMCoreUI/Categories/UIColor+MFConvenience.m @@ -77,7 +77,7 @@ #pragma mark - legacy + (nonnull UIColor *)mfRedColor { - return [UIColor colorWithRed:.804 green:.016 blue:.043 alpha:1.0]; + return [UIColor mvmRed]; } + (nonnull UIColor *)mfDarkerRedColor { @@ -299,6 +299,10 @@ } + (nullable UIColor *)mfGetColorForString:(nullable NSString *)string { + if ([string hasPrefix:@"#"]) { + return [self mfGetColorForHex:string]; + } + static NSDictionary *stringColorMapping; static dispatch_once_t once; dispatch_once(&once, ^{ diff --git a/MVMCoreUI/Categories/UIStackView+Extension.swift b/MVMCoreUI/Categories/UIStackView+Extension.swift index b6bc1b05..e6ed0dda 100644 --- a/MVMCoreUI/Categories/UIStackView+Extension.swift +++ b/MVMCoreUI/Categories/UIStackView+Extension.swift @@ -7,6 +7,7 @@ // import Foundation +import MVMCore extension UIStackView: MVMCoreViewProtocol { public func updateView(_ size: CGFloat) { @@ -16,7 +17,7 @@ extension UIStackView: MVMCoreViewProtocol { } /// A convenience function for updating molecules. If model is nil, view is hidden. - open func updateContainedMolecules(with models: [MoleculeModelProtocol?], _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + public func updateContainedMolecules(with models: [MoleculeModelProtocol?], _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { for (index, item) in arrangedSubviews.enumerated() { if let model = models[index] { (item as? MoleculeViewProtocol)?.set(with: model, delegateObject, additionalData) diff --git a/MVMCoreUI/Categories/colors.xcassets/red.colorset/Contents.json b/MVMCoreUI/Categories/colors.xcassets/red.colorset/Contents.json index 5f3b4048..3a204689 100644 --- a/MVMCoreUI/Categories/colors.xcassets/red.colorset/Contents.json +++ b/MVMCoreUI/Categories/colors.xcassets/red.colorset/Contents.json @@ -5,9 +5,9 @@ "color-space" : "srgb", "components" : { "alpha" : "1.000", - "blue" : "0x23", - "green" : "0x0A", - "red" : "0xF5" + "blue" : "0x00", + "green" : "0x00", + "red" : "0xEE" } }, "idiom" : "universal" diff --git a/MVMCoreUI/Managers/SubNav/SubNavManagerController.swift b/MVMCoreUI/Managers/SubNav/SubNavManagerController.swift index 2c2e4ae7..2bde433a 100644 --- a/MVMCoreUI/Managers/SubNav/SubNavManagerController.swift +++ b/MVMCoreUI/Managers/SubNav/SubNavManagerController.swift @@ -404,7 +404,7 @@ open class SubNavManagerController: ViewController, MVMCoreViewManagerProtocol, public func update(percentage: CGFloat) { guard customInteractor?.interactive == true, - let index = index else { return } + let _ = index else { return } // tabs.progress(from: tabs.selectedIndex, toIndex: index, percentage: percentage) } } diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/externalLink.imageset/Contents.json b/MVMCoreUI/SupportingFiles/Media.xcassets/externalLink.imageset/Contents.json index 07a5a9f8..702db438 100644 --- a/MVMCoreUI/SupportingFiles/Media.xcassets/externalLink.imageset/Contents.json +++ b/MVMCoreUI/SupportingFiles/Media.xcassets/externalLink.imageset/Contents.json @@ -1,23 +1,15 @@ { "images" : [ { - "idiom" : "universal", - "filename" : "exportBlack.png", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "exportBlack@2x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "filename" : "exportBlack@3x.png", - "scale" : "3x" + "filename" : "Vector.svg", + "idiom" : "universal" } ], "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true } -} \ No newline at end of file +} diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/externalLink.imageset/Vector.svg b/MVMCoreUI/SupportingFiles/Media.xcassets/externalLink.imageset/Vector.svg new file mode 100644 index 00000000..bcdaef29 --- /dev/null +++ b/MVMCoreUI/SupportingFiles/Media.xcassets/externalLink.imageset/Vector.svg @@ -0,0 +1,3 @@ + + + diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/externalLink.imageset/exportBlack.png b/MVMCoreUI/SupportingFiles/Media.xcassets/externalLink.imageset/exportBlack.png deleted file mode 100644 index 34f6d7e9..00000000 Binary files a/MVMCoreUI/SupportingFiles/Media.xcassets/externalLink.imageset/exportBlack.png and /dev/null differ diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/externalLink.imageset/exportBlack@2x.png b/MVMCoreUI/SupportingFiles/Media.xcassets/externalLink.imageset/exportBlack@2x.png deleted file mode 100644 index c6de73e8..00000000 Binary files a/MVMCoreUI/SupportingFiles/Media.xcassets/externalLink.imageset/exportBlack@2x.png and /dev/null differ diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/externalLink.imageset/exportBlack@3x.png b/MVMCoreUI/SupportingFiles/Media.xcassets/externalLink.imageset/exportBlack@3x.png deleted file mode 100644 index 15f13e32..00000000 Binary files a/MVMCoreUI/SupportingFiles/Media.xcassets/externalLink.imageset/exportBlack@3x.png and /dev/null differ diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/nav_back.imageset/Contents.json b/MVMCoreUI/SupportingFiles/Media.xcassets/nav_back.imageset/Contents.json index 56ae55a3..702db438 100644 --- a/MVMCoreUI/SupportingFiles/Media.xcassets/nav_back.imageset/Contents.json +++ b/MVMCoreUI/SupportingFiles/Media.xcassets/nav_back.imageset/Contents.json @@ -1,23 +1,15 @@ { "images" : [ { - "filename" : "nav_back.png", - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "nav_back@2x.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "nav_back@3x.png", - "idiom" : "universal", - "scale" : "3x" + "filename" : "Vector.svg", + "idiom" : "universal" } ], "info" : { "author" : "xcode", "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true } } diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/nav_back.imageset/Vector.svg b/MVMCoreUI/SupportingFiles/Media.xcassets/nav_back.imageset/Vector.svg new file mode 100644 index 00000000..a0d9c7b8 --- /dev/null +++ b/MVMCoreUI/SupportingFiles/Media.xcassets/nav_back.imageset/Vector.svg @@ -0,0 +1,3 @@ + + + diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/nav_back.imageset/nav_back.png b/MVMCoreUI/SupportingFiles/Media.xcassets/nav_back.imageset/nav_back.png deleted file mode 100644 index 895fade7..00000000 Binary files a/MVMCoreUI/SupportingFiles/Media.xcassets/nav_back.imageset/nav_back.png and /dev/null differ diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/nav_back.imageset/nav_back@2x.png b/MVMCoreUI/SupportingFiles/Media.xcassets/nav_back.imageset/nav_back@2x.png deleted file mode 100644 index e699cb47..00000000 Binary files a/MVMCoreUI/SupportingFiles/Media.xcassets/nav_back.imageset/nav_back@2x.png and /dev/null differ diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/nav_back.imageset/nav_back@3x.png b/MVMCoreUI/SupportingFiles/Media.xcassets/nav_back.imageset/nav_back@3x.png deleted file mode 100644 index 96e839ed..00000000 Binary files a/MVMCoreUI/SupportingFiles/Media.xcassets/nav_back.imageset/nav_back@3x.png and /dev/null differ diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/nav_close.imageset/Close-1.png b/MVMCoreUI/SupportingFiles/Media.xcassets/nav_close.imageset/Close-1.png deleted file mode 100644 index dd579598..00000000 Binary files a/MVMCoreUI/SupportingFiles/Media.xcassets/nav_close.imageset/Close-1.png and /dev/null differ diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/nav_close.imageset/Close-2.png b/MVMCoreUI/SupportingFiles/Media.xcassets/nav_close.imageset/Close-2.png deleted file mode 100644 index 3cbe291b..00000000 Binary files a/MVMCoreUI/SupportingFiles/Media.xcassets/nav_close.imageset/Close-2.png and /dev/null differ diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/nav_close.imageset/Close.png b/MVMCoreUI/SupportingFiles/Media.xcassets/nav_close.imageset/Close.png deleted file mode 100644 index dac97806..00000000 Binary files a/MVMCoreUI/SupportingFiles/Media.xcassets/nav_close.imageset/Close.png and /dev/null differ diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/nav_close.imageset/Contents.json b/MVMCoreUI/SupportingFiles/Media.xcassets/nav_close.imageset/Contents.json index ffda34e6..702db438 100644 --- a/MVMCoreUI/SupportingFiles/Media.xcassets/nav_close.imageset/Contents.json +++ b/MVMCoreUI/SupportingFiles/Media.xcassets/nav_close.imageset/Contents.json @@ -1,23 +1,15 @@ { "images" : [ { - "filename" : "Close.png", - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "Close-1.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "filename" : "Close-2.png", - "idiom" : "universal", - "scale" : "3x" + "filename" : "Vector.svg", + "idiom" : "universal" } ], "info" : { "author" : "xcode", "version" : 1 + }, + "properties" : { + "preserves-vector-representation" : true } } diff --git a/MVMCoreUI/SupportingFiles/Media.xcassets/nav_close.imageset/Vector.svg b/MVMCoreUI/SupportingFiles/Media.xcassets/nav_close.imageset/Vector.svg new file mode 100644 index 00000000..1aece044 --- /dev/null +++ b/MVMCoreUI/SupportingFiles/Media.xcassets/nav_close.imageset/Vector.svg @@ -0,0 +1,3 @@ + + +