add peaking logic

This commit is contained in:
Pfeil, Scott Robert 2019-07-11 16:11:58 -04:00
parent 33020844dc
commit 8866e91caa
8 changed files with 115 additions and 104 deletions

View File

@ -45,7 +45,6 @@ open class Carousel: ViewConstrainingView {
/// If the carousel should loop after scrolling past the first and final cells.
var loop = false
private var dragging = false
private var previousContentOffsetX: CGFloat = 0
// MARK: - MVMCoreViewProtocol
open override func setupView() {
@ -73,6 +72,7 @@ open class Carousel: ViewConstrainingView {
DispatchQueue.main.async {
self.collectionView.scrollToItem(at: IndexPath(row: self.currentIndex, section: 0), at: self.itemAlignment, animated: false)
self.collectionView.layoutIfNeeded()
self.showPeaking(true)
}
}
@ -201,6 +201,24 @@ open class Carousel: ViewConstrainingView {
}
self.pagingView = pagingView
}
open func showPeaking(_ peaking: Bool) {
if peaking {
// Show overlay and arrow in peaking Cell
let visibleItemsPaths = collectionView.indexPathsForVisibleItems.sorted { $0.row < $1.row }
if let firstItem = visibleItemsPaths.first, firstItem.row != currentIndex {
(collectionView.cellForItem(at: firstItem) as? MoleculeCollectionViewCell)?.setPeaking(true, animated: true)
}
if let lastItem = visibleItemsPaths.last, lastItem.row != currentIndex {
(collectionView.cellForItem(at: lastItem) as? MoleculeCollectionViewCell)?.setPeaking(true, animated: true)
}
} else {
// Hide peaking.
for item in collectionView.visibleCells {
(item as? MoleculeCollectionViewCell)?.setPeaking(false, animated: true)
}
}
}
}
extension Carousel: UICollectionViewDelegateFlowLayout {
@ -232,68 +250,6 @@ extension Carousel: UICollectionViewDataSource {
}
extension Carousel: UIScrollViewDelegate {
/*// For getting the scroll progress to set the page control color progress.
- (CGFloat)getPageControlPercentBasedOnScrollView:(UIScrollView *)scrollView {
CGFloat cardWidth = ((UICollectionViewFlowLayout *)self.collectionView.collectionViewLayout).itemSize.width;
CGFloat separatorWidth = ((UICollectionViewFlowLayout *)self.collectionView.collectionViewLayout).minimumLineSpacing;
CGFloat contentOfsetInCard = fmodf(scrollView.contentOffset.x, cardWidth + separatorWidth);
CGFloat endThresholdPageControl = cardWidth + separatorWidth - CGRectGetMaxX(self.pageControl.frame);
CGFloat progress = contentOfsetInCard - endThresholdPageControl;
CGFloat width = CGRectGetWidth(self.pageControl.bounds);
CGFloat percent = (width - progress)/width;
CGFloat cappedPercent = MAX(MIN(percent, 1), 0);
return cappedPercent;
}
- (void)setPageControlColorsBasedOnScrollView:(UIScrollView *)scrollView {
// Check if we will need to change colors.
BOOL needToShiftColors = NO;
NSInteger nextCardIndex = 0;
CGFloat cardWidth = ((UICollectionViewFlowLayout *)self.collectionView.collectionViewLayout).itemSize.width;
CGFloat separatorWidth = ((UICollectionViewFlowLayout *)self.collectionView.collectionViewLayout).minimumLineSpacing;
NSInteger currentCard = scrollView.contentOffset.x / (cardWidth + separatorWidth);
CGFloat cardStart = currentCard * (cardWidth + separatorWidth);
CGFloat cardEnd = cardStart + cardWidth + separatorWidth;
NSInteger pageIndicator = currentCard;
if ((self.previousContentOffsetX == NSNotFound || self.previousContentOffsetX <= cardStart) && scrollView.contentOffset.x >= cardStart) {
// We are passed the threshold and moving right, change to right card color.
needToShiftColors = YES;
nextCardIndex = currentCard + 1;
pageIndicator = currentCard - 1;
} else if ((self.previousContentOffsetX == NSNotFound || self.previousContentOffsetX >= cardEnd) && scrollView.contentOffset.x < cardEnd) {
// We are passed the threshold and moving left, change to left card color.
needToShiftColors = YES;
nextCardIndex = currentCard - 1;
}
if (needToShiftColors) {
// Only shift the page control if we are dragging still, otherwise end animation will control.
if (self.dragging) {
[self.pageControl setCurrentPage:pageIndicator];
}
// Get the current page color
NSString *colorString = [[self.feedModules objectAtIndex:currentCard] string:KeyPageIndicatorColor];
UIColor *currentCardPageControlColor = colorString ? [UIColor mfGetColorForHex:colorString] : [UIColor blackColor];
// Get the next page color and set accordingly.
colorString = [[self.feedModules dictionaryAtIndex:nextCardIndex] string:KeyPageIndicatorColor];
UIColor *nextCardPageControlColor = colorString ? [UIColor mfGetColorForHex:colorString] : [UIColor blackColor];
// Which color needs to be on top or bottom depends on which direction we are moving.
if (nextCardIndex > currentCard) {
[self setPageControlColor:nextCardPageControlColor progressColor:currentCardPageControlColor];
} else {
[self setPageControlColor:currentCardPageControlColor progressColor:nextCardPageControlColor];
}
}
}
*/
func handleUserOnBufferCell() {
guard loop else {
return
@ -302,7 +258,6 @@ extension Carousel: UIScrollViewDelegate {
let lastPageIndex = numberOfPages + 1
let goToIndex = {(index: Int) in
self.currentIndex = index
self.previousContentOffsetX = CGFloat(NSNotFound)
self.collectionView.scrollToItem(at: IndexPath(row: self.currentIndex, section: 0), at: self.itemAlignment, animated: false)
self.collectionView.layoutIfNeeded()
self.pagingView?.setPage(self.pageIndex)
@ -337,24 +292,17 @@ extension Carousel: UIScrollViewDelegate {
}
public func scrollViewDidScroll(_ scrollView: UIScrollView) {
// Check if the user is dragging the card even further past the next card.
checkForDraggingOutOfBounds(scrollView)
// Set the page control direction colors if needed.
//[self setPageControlColorsBasedOnScrollView:scrollView];
// Set the percent of progress.
//self.pageControl.progressView.progress = [self getPageControlPercentBasedOnScrollView:scrollView];
previousContentOffsetX = scrollView.contentOffset.x;
// Let the pager know our progress if needed.
pagingView?.scrollViewDidScroll?(collectionView)
}
public func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
dragging = true
// // Hide coverview and arrow.
// FeedBaseCollectionViewCell *peakingCell = (FeedBaseCollectionViewCell *)[self.collectionView cellForItemAtIndexPath:[NSIndexPath indexPathForItem:self.currentIndex + 1 inSection:0]];
// [peakingCell setPeaking:NO animated:YES];
showPeaking(false)
}
public func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
@ -363,7 +311,7 @@ extension Carousel: UIScrollViewDelegate {
// This is for setting up smooth custom paging. (Since UICollectionView only handles paging based on collection view size and not cell size).
guard let separatorWidth = (collectionView.collectionViewLayout as? UICollectionViewFlowLayout)?.minimumLineSpacing else {
return
return
}
// We switch cards if we pass the velocity threshold or position threshold (currently 50%).
@ -381,11 +329,6 @@ extension Carousel: UIScrollViewDelegate {
currentIndex = min(max(cellToSwipeTo, 0), lastCellIndex)
collectionView.scrollToItem(at: IndexPath(row: currentIndex, section: 0), at: itemAlignment, animated: true)
// Notify that card changed
/*if (self.cardChanged) {
self.cardChanged(self.currentIndex, [self.module string:[MFBaseHomeViewController getFeedContainerNameKey]]);
}*/
}
// To give the illusion of endless scrolling. Since we are always calling scrollToItem we can assume finished paging in here.
@ -394,27 +337,7 @@ extension Carousel: UIScrollViewDelegate {
handleUserOnBufferCell()
pagingView?.setPage(pageIndex)
/*
// Update to the new page in the control if needed.
if (self.currentIndex - 1 != self.pageControl.currentPage) {
[self.pageControl setCurrentPage:self.currentIndex - 1];
}
// Show overlay and arrow in next Cell
FeedBaseCollectionViewCell *nextCell = (FeedBaseCollectionViewCell *)[self.collectionView cellForItemAtIndexPath:[NSIndexPath indexPathForItem:self.currentIndex + 1 inSection:0]];
[nextCell setPeaking:YES animated:YES];
FeedBaseCollectionViewCell *currentCell = (FeedBaseCollectionViewCell *)[self.collectionView cellForItemAtIndexPath:[NSIndexPath indexPathForItem:self.currentIndex inSection:0]];
if (currentCell) {
self.accessibilityElements = @[currentCell.containerView, self.pageControl];
currentCell.containerView.isAccessibilityElement = YES;
currentCell.accessibilityElementsHidden = NO;
UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification,currentCell.containerView);
}
// Set the page control again if pageControl is tapped or voice over is using.
[self setPageControlColorsBasedOnScrollView:scrollView];
// send adobe tracker action
[self sendAdobeTrackerAction];*/
showPeaking(true)
}
}

View File

@ -18,5 +18,8 @@ typedef void (^PagingTouchBlock)(NSObject<MVMCoreUIPagingProtocol>* _Nonnull sen
- (void)setPage:(NSInteger)page;
- (void)setPagingTouchBlock:(nullable PagingTouchBlock)pagingTouchBlock;
@optional
- (void)scrollViewDidScroll:(nonnull UICollectionView *)collectionView;
@end

View File

@ -11,6 +11,11 @@ import UIKit
open class MoleculeCollectionViewCell: UICollectionViewCell, MVMCoreUIMoleculeViewProtocol, MoleculeListCellProtocol {
open var molecule: (UIView & MVMCoreUIMoleculeViewProtocol)?
open var allowsPeaking = false
var peakingLeftArrow = UIImageView(image: MVMCoreUIUtility.imageNamed("peakingRightArrow")?.withRenderingMode(.alwaysTemplate))
var peakingRightArrow = UIImageView(image: MVMCoreUIUtility.imageNamed("peakingRightArrow")?.withRenderingMode(.alwaysTemplate))
var peakingCover = MVMCoreUICommonViewsUtility.commonView()
public override init(frame: CGRect) {
super.init(frame: .zero)
setupView()
@ -22,15 +27,49 @@ open class MoleculeCollectionViewCell: UICollectionViewCell, MVMCoreUIMoleculeVi
}
public func setupView() {
guard peakingCover.superview == nil else {
return
}
// Covers the card when peaking.
peakingCover.backgroundColor = .white
peakingCover.alpha = 0
contentView.addSubview(peakingCover)
NSLayoutConstraint.constraintPinSubview(toSuperview: peakingCover)
// A small arrow on the next card for when peaking.
let ratio: CGFloat = 0.015
peakingLeftArrow.translatesAutoresizingMaskIntoConstraints = false
peakingLeftArrow.alpha = 0
peakingLeftArrow.tintColor = .black
contentView.addSubview(peakingLeftArrow)
peakingLeftArrow.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true
NSLayoutConstraint.scalingPinViewLeft(toSuper: peakingLeftArrow, ratio: ratio, anchor: contentView.widthAnchor)
peakingRightArrow.translatesAutoresizingMaskIntoConstraints = false
peakingRightArrow.transform = CGAffineTransform(scaleX: -1, y: 1) // Flip
peakingRightArrow.alpha = 0
peakingRightArrow.tintColor = .black
contentView.addSubview(peakingRightArrow)
peakingRightArrow.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true
NSLayoutConstraint.scalingPinViewRight(toSuper: peakingRightArrow, ratio: ratio, anchor: contentView.widthAnchor)
}
public func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) {
guard let json = json, let moleculeJSON = json.optionalDictionaryForKey(KeyMolecule) else {
// Handles peaking.
allowsPeaking = json?.optionalBoolForKey("peakingUI") ?? true
if let peakingArrowColor = json?.optionalStringForKey("peakingArrowColor") {
let color = UIColor.mfGet(forHex: peakingArrowColor)
peakingLeftArrow.tintColor = color
peakingRightArrow.tintColor = color
}
guard let moleculeJSON = json?.optionalDictionaryForKey(KeyMolecule) else {
return
}
if molecule == nil {
if let moleculeView = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: moleculeJSON, delegateObject: delegateObject, constrainIfNeeded: true) {
contentView.addSubview(moleculeView)
contentView.insertSubview(moleculeView, at: 0)
let standardConstraints = (moleculeView as? MVMCoreUIViewConstrainingProtocol)?.useStandardConstraints?() ?? true
NSLayoutConstraint.activate(Array(NSLayoutConstraint.pinView(toSuperview: moleculeView, useMargins: standardConstraints).values))
if standardConstraints {
@ -61,4 +100,21 @@ open class MoleculeCollectionViewCell: UICollectionViewCell, MVMCoreUIMoleculeVi
public func updateView(_ size: CGFloat) {
molecule?.updateView(size)
}
public func setPeaking(_ peaking: Bool, animated: Bool) {
guard allowsPeaking else {
return
}
let animation = {() in
self.peakingRightArrow.alpha = peaking ? 1 : 0
self.peakingLeftArrow.alpha = peaking ? 1 : 0
self.peakingCover.alpha = peaking ? 0.5 : 0
print("\(self.peakingCover.alpha)")
}
if animated {
UIView.animate(withDuration: 0.4, animations: animation)
} else {
animation()
}
}
}

View File

@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@ -0,0 +1,23 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "E_UBI_003_G.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "E_UBI_003_G@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "E_UBI_003_G@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 275 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 379 B