diff --git a/MVMCoreUI/Atoms/Views/ViewConstrainingView.h b/MVMCoreUI/Atoms/Views/ViewConstrainingView.h index 9ec6c193..acf451a8 100644 --- a/MVMCoreUI/Atoms/Views/ViewConstrainingView.h +++ b/MVMCoreUI/Atoms/Views/ViewConstrainingView.h @@ -85,4 +85,7 @@ /// Convenience function for getting the alignment from a map. + (UIStackViewAlignment)getAlignmentForString:(nullable NSString *)alignmentString defaultAlignment:(UIStackViewAlignment)defaultAlignment; +/// Makes the view isAccessibilityElement false and adds molecule elements to accessbilityElements. +- (void)setMoleculeAccessibility; + @end diff --git a/MVMCoreUI/Atoms/Views/ViewConstrainingView.m b/MVMCoreUI/Atoms/Views/ViewConstrainingView.m index 093e1ecc..c6152bcc 100644 --- a/MVMCoreUI/Atoms/Views/ViewConstrainingView.m +++ b/MVMCoreUI/Atoms/Views/ViewConstrainingView.m @@ -27,6 +27,7 @@ [self addConstrainedView:molecule alignment:alignment]; [self setAsMolecule]; } + [self setMoleculeAccessibility]; self.molecule = molecule; } return self; @@ -327,6 +328,17 @@ #pragma mark - MVMCoreUIMoleculeViewProtocol +- (void)setMoleculeAccessibility { + if (self.molecule) { + self.isAccessibilityElement = NO; + if (self.molecule.accessibilityElements) { + self.accessibilityElements = self.molecule.accessibilityElements; + } else { + self.accessibilityElements = @[self.molecule]; + } + } +} + - (void)reset { if ([self.molecule respondsToSelector:@selector(reset)]) { [self.molecule performSelector:@selector(reset)]; @@ -350,6 +362,7 @@ [self pinViewToSuperView:molecule]; } } + [self setMoleculeAccessibility]; } if (self.molecule) { if ([self.molecule respondsToSelector:@selector(copyBackgroundColor)] && [self.molecule performSelector:@selector(copyBackgroundColor)]) { diff --git a/MVMCoreUI/Molecules/Carousel.swift b/MVMCoreUI/Molecules/Carousel.swift index 27cc59f6..082fcd6d 100644 --- a/MVMCoreUI/Molecules/Carousel.swift +++ b/MVMCoreUI/Molecules/Carousel.swift @@ -68,7 +68,8 @@ open class Carousel: ViewConstrainingView { open override func updateView(_ size: CGFloat) { super.updateView(size) collectionView.collectionViewLayout.invalidateLayout() - + 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. DispatchQueue.main.async { self.collectionView.scrollToItem(at: IndexPath(row: self.currentIndex, section: 0), at: self.itemAlignment, animated: false) @@ -141,7 +142,6 @@ open class Carousel: ViewConstrainingView { var pagingView: (UIView & MVMCoreUIPagingProtocol)? = nil if let json = json { pagingView = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: json, delegateObject: delegateObject, constrainIfNeeded: true) as? (UIView & MVMCoreUIPagingProtocol) - pagingView?.isAccessibilityElement = true } addPaging(view: pagingView, position: (json?.optionalCGFloatForKey("position") ?? 20)) } @@ -205,7 +205,7 @@ open class Carousel: ViewConstrainingView { } open func showPeaking(_ peaking: Bool) { - if peaking { + if peaking && !UIAccessibility.isVoiceOverRunning { // Show overlay and arrow in peaking Cell let visibleItemsPaths = collectionView.indexPathsForVisibleItems.sorted { $0.row < $1.row } if let firstItem = visibleItemsPaths.first, firstItem.row != currentIndex { @@ -221,6 +221,26 @@ open class Carousel: ViewConstrainingView { } } } + + func setAccessiblity(_ cell: UICollectionViewCell?, index: Int) { + guard let cell = cell else { + return + } + if index == currentIndex { + cell.accessibilityElementsHidden = false + var array = cell.accessibilityElements + + if let acc = pagingView?.accessibilityElements { + array?.append(contentsOf: acc) + } else { + array?.append(pagingView!) + } + + self.accessibilityElements = array + } else { + cell.accessibilityElementsHidden = true + } + } } extension Carousel: UICollectionViewDelegateFlowLayout { @@ -246,14 +266,7 @@ extension Carousel: UICollectionViewDataSource { protocolCell.setWithJSON(moleculeInfo.molecule, delegateObject: nil, additionalData: nil) protocolCell.updateView(collectionView.bounds.width) } - - if indexPath.row == currentIndex { - cell.accessibilityElementsHidden = false -// self.accessibilityElements = @[cell.containerView, self.pageControl]; - } else { - cell.accessibilityElementsHidden = true - } - + setAccessiblity(cell, index: indexPath.row) return cell } } @@ -261,10 +274,14 @@ extension Carousel: UICollectionViewDataSource { extension Carousel: UIScrollViewDelegate { func goTo(_ index: Int, animated: Bool) { - collectionView.cellForItem(at: IndexPath(row: self.currentIndex, section: 0))?.accessibilityElementsHidden = true + showPeaking(false) + setAccessiblity(collectionView.cellForItem(at: IndexPath(row: self.currentIndex, section: 0)), index: index) self.currentIndex = index - collectionView.cellForItem(at: IndexPath(row: self.currentIndex, section: 0))?.accessibilityElementsHidden = false self.collectionView.scrollToItem(at: IndexPath(row: self.currentIndex, section: 0), at: self.itemAlignment, animated: animated) + if let cell = collectionView.cellForItem(at: IndexPath(row: self.currentIndex, section: 0)) { + setAccessiblity(collectionView.cellForItem(at: IndexPath(row: self.currentIndex, section: 0)), index: index) + UIAccessibility.post(notification: .layoutChanged, argument: cell) + } } func handleUserOnBufferCell() { @@ -353,7 +370,5 @@ extension Carousel: UIScrollViewDelegate { pagingView?.setPage(pageIndex) showPeaking(true) - - //UIAccessibility.post(notification: .layoutChanged, argument: currentIndex) UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification,currentCell.containerView); } } diff --git a/MVMCoreUI/Molecules/MVMCoreUIPageControl.m b/MVMCoreUI/Molecules/MVMCoreUIPageControl.m index cbfe0300..16783ca9 100644 --- a/MVMCoreUI/Molecules/MVMCoreUIPageControl.m +++ b/MVMCoreUI/Molecules/MVMCoreUIPageControl.m @@ -241,6 +241,8 @@ static CGFloat const IndicatorRectangleHeight = 4; - (void)setupView { if (!self.containerView) { + self.isAccessibilityElement = YES; + // Create a container view that keeps everything centered UIView *containerView = [MVMCoreUICommonViewsUtility commonView]; [self addSubview:containerView]; diff --git a/MVMCoreUI/Molecules/ModuleMolecule.swift b/MVMCoreUI/Molecules/ModuleMolecule.swift index 7781021f..c993b0c2 100644 --- a/MVMCoreUI/Molecules/ModuleMolecule.swift +++ b/MVMCoreUI/Molecules/ModuleMolecule.swift @@ -31,6 +31,13 @@ open class ModuleMolecule: ViewConstrainingView { addSubview(moleculeView) NSLayoutConstraint.activate(Array(NSLayoutConstraint.pinView(toSuperview: moleculeView, useMargins: false).values)) moduleMolecule = moleculeView + + isAccessibilityElement = false + if moleculeView.accessibilityElements != nil { + accessibilityElements = moleculeView.accessibilityElements + } else { + accessibilityElements = [moleculeView] + } } } else { moduleMolecule?.setWithJSON(module, delegateObject: delegateObject, additionalData: additionalData) diff --git a/MVMCoreUI/Molecules/MoleculeCollectionViewCell.swift b/MVMCoreUI/Molecules/MoleculeCollectionViewCell.swift index 82d7f4a2..5f18d454 100644 --- a/MVMCoreUI/Molecules/MoleculeCollectionViewCell.swift +++ b/MVMCoreUI/Molecules/MoleculeCollectionViewCell.swift @@ -73,13 +73,7 @@ open class MoleculeCollectionViewCell: UICollectionViewCell, MVMCoreUIMoleculeVi if molecule == nil { if let moleculeView = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: moleculeJSON, delegateObject: delegateObject, constrainIfNeeded: true) { contentView.insertSubview(moleculeView, at: 0) - let standardConstraints = (moleculeView as? MVMCoreUIViewConstrainingProtocol)?.useStandardConstraints?() ?? true - NSLayoutConstraint.activate(Array(NSLayoutConstraint.pinView(toSuperview: moleculeView, useMargins: standardConstraints).values)) - if standardConstraints { - let constraint = contentView.heightAnchor.constraint(equalToConstant: 80) - constraint.priority = .defaultLow - constraint.isActive = true - } + NSLayoutConstraint.activate(Array(NSLayoutConstraint.pinView(toSuperview: moleculeView, useMargins: false).values)) molecule = moleculeView } } else { @@ -91,6 +85,7 @@ open class MoleculeCollectionViewCell: UICollectionViewCell, MVMCoreUIMoleculeVi castView.shouldSetVerticalMargins?(standardConstraints) } backgroundColor = molecule?.backgroundColor + accessibilityElements = molecule?.subviews } public static func name(forReuse molecule: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?) -> String? { diff --git a/MVMCoreUI/Molecules/MoleculeStackView.swift b/MVMCoreUI/Molecules/MoleculeStackView.swift index 3183800f..f769bb05 100644 --- a/MVMCoreUI/Molecules/MoleculeStackView.swift +++ b/MVMCoreUI/Molecules/MoleculeStackView.swift @@ -175,13 +175,8 @@ public class MoleculeStackView: ViewConstrainingView { spacing = json?.optionalCGFloatForKey("spacing") ?? 16 // Set the alignment for the stack in the containing view. The json driven value is for the axis direction alignment. - if axis == .vertical { - alignHorizontal(.fill) - alignVertical(ViewConstrainingView.getAlignmentFor(json?.optionalStringForKey("alignment"), defaultAlignment: .fill)) - } else { - alignHorizontal(ViewConstrainingView.getAlignmentFor(json?.optionalStringForKey("alignment"), defaultAlignment: .fill)) - alignVertical(.fill) - } + alignHorizontal(ViewConstrainingView.getAlignmentFor(json?.optionalStringForKey("horizontalAlignment"), defaultAlignment: .fill)) + alignVertical(ViewConstrainingView.getAlignmentFor(json?.optionalStringForKey("verticalAlignment"), defaultAlignment: .fill)) // Adds the molecules and sets the json. for (index, map) in molecules.enumerated() {