Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //
- // UIKitPagingScrollView.m
- // DotsView
- //
- // Created by SveDo on 12/01/2018.
- // Copyright © 2018 SveDo. All rights reserved.
- //
- #import "UIKitPagingView.h"
- #import "MagicScrollView.h"
- #import "UIKitScrollViewsSynchronizer.h"
- #import "Taptic.h"
- #define kUIKitPagingViewIsUsingRunLoop NO
- @interface UIKitPagingView ()
- {
- MagicScrollView *mScrollView;
- NSMutableArray *mArrayOfScrollSubviews;
- Class mClassElement;
- void(^mConfigureElementBlock)(NSUInteger mUIntegerElementIndex, UIView *mReuseView);
- CFRunLoopObserverRef mRunLoopObserver;
- BOOL mBoolIsNeedPose;
- CGRect mCGRectBufferFrame;
- NSMutableDictionary *mMutableDictionaryPosedViews;
- NSMutableSet *mSetOfReusableViews;
- CGFloat mCGFloatStartXPosition;
- UIView *mViewContent;
- }
- @end
- @interface UIKitPagingView (UIScrollViewDelegate) <UIScrollViewDelegate>
- @end
- @implementation UIKitPagingView
- - (instancetype)initWithFrame:(CGRect)frame
- {
- self = [super initWithFrame:frame];
- if (self)
- {
- self.translatesAutoresizingMaskIntoConstraints = NO;
- mMutableDictionaryPosedViews = [[NSMutableDictionary alloc] init];
- mSetOfReusableViews = [[NSMutableSet alloc] init];
- mViewContent = [[UIView alloc] init];
- [mViewContent setBackgroundColor:[UIColor clearColor]];
- mViewContent.layer.masksToBounds = YES;
- [self addSubview:mViewContent];
- mScrollView = [[MagicScrollView alloc] init];
- mScrollView.directionalLockEnabled = YES;
- [mViewContent addSubview:mScrollView];
- mScrollView.delegate = self;
- mScrollView.clipsToBounds = NO;
- mScrollView.showsHorizontalScrollIndicator = NO;
- mScrollView.showsVerticalScrollIndicator = NO;
- mScrollView.pagingEnabled = YES;
- if (kUIKitPagingViewIsUsingRunLoop)
- {
- __weak UIKitPagingView *weakSelf = self;
- mRunLoopObserver = CFRunLoopObserverCreateWithHandler(NULL, kCFRunLoopBeforeWaiting, YES, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity)
- {
- __strong UIKitPagingView *strongSelf = weakSelf;
- if (strongSelf->mBoolIsNeedPose == YES)
- {
- [strongSelf poseViews];
- }
- });
- CFRunLoopAddObserver(CFRunLoopGetMain(), mRunLoopObserver, kCFRunLoopCommonModes);
- }
- }
- return self;
- }
- - (UIView *)getReusableView
- {
- if ([mSetOfReusableViews count] > 0)
- {
- UIView *view = [mSetOfReusableViews anyObject];
- [mSetOfReusableViews removeObject:view];
- return view;
- }
- return [[mClassElement alloc] init];
- }
- - (void)reloadElements
- {
- [[mMutableDictionaryPosedViews allValues] makeObjectsPerformSelector:@selector(removeFromSuperview)];
- [mSetOfReusableViews addObjectsFromArray:[mMutableDictionaryPosedViews allValues]];
- [mMutableDictionaryPosedViews removeAllObjects];
- [self poseViews];
- }
- - (void)poseViews
- {
- if (mScrollView.bounds.size.width == 0)
- {
- return;
- }
- NSMutableIndexSet *mIndexSetShowedIndexes = [NSMutableIndexSet indexSet];
- for (NSUInteger index = (int)(mScrollView.contentOffset.x/self.bounds.size.width); index < [self mUIntegerNumberOfPages]; index++)
- {
- if (mScrollView.bounds.size.width * index - mScrollView.contentOffset.x > [self mViewContent].bounds.size.width)
- {
- break;
- }
- [mIndexSetShowedIndexes addIndex:index];
- }
- for (NSNumber *index in [[mMutableDictionaryPosedViews allKeys] filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id _Nullable evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings)
- {
- return [mIndexSetShowedIndexes containsIndex:[evaluatedObject unsignedIntegerValue]] ? NO : YES;
- }]])
- {
- UIView *view = [mMutableDictionaryPosedViews objectForKey:index];
- [view removeFromSuperview];
- [mMutableDictionaryPosedViews removeObjectForKey:index];
- [mSetOfReusableViews addObject:view];
- }
- if (mClassElement == nil)
- {
- return;
- }
- [mIndexSetShowedIndexes enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL * _Nonnull stop)
- {
- UIView *view;
- if (!(view = [mMutableDictionaryPosedViews objectForKey:[NSNumber numberWithUnsignedInteger:idx]]))
- {
- view = [self getReusableView];
- view.frame = CGRectMake(self.mCGFloatInsetBettweenPages/2.0 + mScrollView.bounds.size.width * idx, 0, mScrollView.bounds.size.width - self.mCGFloatInsetBettweenPages, mScrollView.bounds.size.height);
- mConfigureElementBlock(idx, view);
- [mScrollView addSubview:view];
- [mMutableDictionaryPosedViews setObject:view forKey:[NSNumber numberWithUnsignedInteger:idx]];
- }
- }];
- CGSize targetContentSize = CGSizeMake(mScrollView.bounds.size.width * self.mUIntegerNumberOfPages, mScrollView.bounds.size.height);
- if (!CGSizeEqualToSize(mScrollView.contentSize, targetContentSize))
- {
- mScrollView.contentSize = targetContentSize;
- }
- NSUInteger selectedIndex = MIN((int)((mScrollView.contentOffset.x + (mScrollView.bounds.size.width/2.0))/ mScrollView.bounds.size.width), self.mUIntegerNumberOfPages-1);
- if (selectedIndex != self.mUIntegerSelectedIndex)
- {
- mScrollView.contentOffset = CGPointMake(mScrollView.bounds.size.width * self.mUIntegerSelectedIndex, 0);
- if (self.selectedIndexOffsetChangeBlock != nil)
- {
- self.selectedIndexOffsetChangeBlock(_mDoubleSelectedIndexOffset, YES);
- }
- }
- if (kUIKitPagingViewIsUsingRunLoop)
- {
- mBoolIsNeedPose = NO;
- }
- }
- - (void)setMUIEdgeInsetsPagePositionInsets:(UIEdgeInsets)mUIEdgeInsetsPagePositionInsets
- {
- _mUIEdgeInsetsPagePositionInsets = mUIEdgeInsetsPagePositionInsets;
- mCGRectBufferFrame = CGRectZero;
- [self setNeedsLayout];
- }
- - (void)layoutSubviews
- {
- [super layoutSubviews];
- if (!CGRectEqualToRect(mCGRectBufferFrame, self.bounds))
- {
- mViewContent.frame = self.bounds;
- mScrollView.frame = CGRectMake(0 + _mUIEdgeInsetsPagePositionInsets.left, 0 + _mUIEdgeInsetsPagePositionInsets.top, self.bounds.size.width - _mUIEdgeInsetsPagePositionInsets.left - _mUIEdgeInsetsPagePositionInsets.right, self.bounds.size.height - _mUIEdgeInsetsPagePositionInsets.top - _mUIEdgeInsetsPagePositionInsets.bottom);
- mCGRectBufferFrame = self.bounds;
- if (kUIKitPagingViewIsUsingRunLoop)
- {
- mBoolIsNeedPose = YES;
- }
- else
- {
- [self poseViews];
- }
- }
- }
- - (UIView *)mViewContent
- {
- return mViewContent;
- }
- - (void)setMUIntegerNumberOfPages:(NSUInteger)mUIntegerNumberOfPages
- {
- if (_mUIntegerNumberOfPages != mUIntegerNumberOfPages)
- {
- _mUIntegerNumberOfPages = mUIntegerNumberOfPages;
- if (kUIKitPagingViewIsUsingRunLoop)
- {
- mBoolIsNeedPose = YES;
- }
- else
- {
- [self poseViews];
- }
- }
- }
- - (void)setClass:(Class)elementsClass forConfigureElementBlock:(void (^)(NSUInteger, UIView *))block
- {
- mClassElement = elementsClass;
- mConfigureElementBlock = block;
- if (kUIKitPagingViewIsUsingRunLoop)
- {
- mBoolIsNeedPose = YES;
- }
- else
- {
- [self poseViews];
- }
- }
- - (void)setMUIntegerSelectedIndex:(NSUInteger)mUIntegerSelectedIndex
- {
- if (_mUIntegerSelectedIndex != mUIntegerSelectedIndex)
- {
- [self willChangeValueForKey:@"mUIntegerSelectedIndex"];
- _mUIntegerSelectedIndex = mUIntegerSelectedIndex;
- if (kUIKitPagingViewIsUsingRunLoop)
- {
- mBoolIsNeedPose = YES;
- }
- else
- {
- [self poseViews];
- }
- if (self.selectedIndexChangeBlock != nil)
- {
- self.selectedIndexChangeBlock(_mUIntegerSelectedIndex, mScrollView.contentOffset.x > mCGFloatStartXPosition);
- }
- [self didChangeValueForKey:@"mUIntegerSelectedIndex"];
- }
- }
- - (void)setMDoubleSelectedIndexOffset:(double)mDoubleSelectedIndexOffset
- {
- if (_mDoubleSelectedIndexOffset != mDoubleSelectedIndexOffset)
- {
- [self willChangeValueForKey:@"mDoubleSelectedIndexOffset"];
- _mDoubleSelectedIndexOffset = mDoubleSelectedIndexOffset;
- if (kUIKitPagingViewIsUsingRunLoop)
- {
- mBoolIsNeedPose = YES;
- }
- else
- {
- [self poseViews];
- }
- if (self.selectedIndexOffsetChangeBlock != nil)
- {
- self.selectedIndexOffsetChangeBlock(_mDoubleSelectedIndexOffset, mScrollView.contentOffset.x > mCGFloatStartXPosition);
- }
- [self didChangeValueForKey:@"mDoubleSelectedIndexOffset"];
- }
- }
- - (void)dealloc
- {
- if (mRunLoopObserver != NULL)
- {
- CFRunLoopRemoveObserver(CFRunLoopGetMain(), mRunLoopObserver, kCFRunLoopCommonModes);
- CFRunLoopObserverInvalidate(mRunLoopObserver);
- CFRelease(mRunLoopObserver);
- }
- }
- @end
- @implementation UIKitPagingView (UIScrollViewDelegate)
- - (void)scrollViewDidScroll:(UIScrollView *)scrollView
- {
- [UIKitScrollViewsSynchronizer scrollViewDidScroll:scrollView];
- NSUInteger selectedIndex = MIN((int)((MAX(scrollView.contentOffset.x, 0) + (scrollView.bounds.size.width/2.0))/ scrollView.bounds.size.width), self.mUIntegerNumberOfPages-1);
- if ( self.mUIntegerSelectedIndex != selectedIndex )
- {
- self.mUIntegerSelectedIndex = selectedIndex;
- [Taptic object:self requestTapticWithType:TapticTypeSelect];
- }
- self.mDoubleSelectedIndexOffset = (scrollView.contentOffset.x - (scrollView.bounds.size.width * selectedIndex))/(scrollView.bounds.size.width);
- }
- - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
- {
- [Taptic object:self willRequestTapticWithType:TapticTypeSelect];
- mCGFloatStartXPosition = scrollView.contentOffset.x;
- [UIKitScrollViewsSynchronizer scrollViewWillBeginDragging:scrollView];
- }
- - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
- {
- if (!decelerate)
- {
- [Taptic object:self didRequestTapticWithType:TapticTypeSelect];
- }
- [UIKitScrollViewsSynchronizer scrollViewDidEndDragging:scrollView willDecelerate:decelerate];
- }
- - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
- {
- [Taptic object:self didRequestTapticWithType:TapticTypeSelect];
- [UIKitScrollViewsSynchronizer scrollViewDidEndDecelerating:scrollView];
- }
- @end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement