diff --git a/KKGridView/Definitions.h b/KKGridView/Definitions.h index ffdd3b5..dbd5c0b 100755 --- a/KKGridView/Definitions.h +++ b/KKGridView/Definitions.h @@ -22,12 +22,16 @@ #define __kk_weak __unsafe_unretained #endif -static inline bool KKCGRectIntersectsRectVertically(CGRect rect1, CGRect rect2) +#if !defined(KKInline) +#define KKInline static __inline__ __attribute__((always_inline)) +#endif + +KKInline BOOL KKCGRectIntersectsRectVertically(CGRect rect1, CGRect rect2) { return (CGRectGetMinY(rect2) < CGRectGetMaxY(rect1)) && (CGRectGetMaxY(rect2) > CGRectGetMinY(rect1)); } -static inline bool KKCGRectIntersectsRectVerticallyWithPositiveNegativeMargin(CGRect rect1, CGRect rect2, CGFloat margin) +KKInline BOOL KKCGRectIntersectsRectVerticallyWithPositiveNegativeMargin(CGRect rect1, CGRect rect2, CGFloat margin) { return (CGRectGetMinY(rect2) - margin < CGRectGetMaxY(rect1)) && (CGRectGetMaxY(rect2) + margin > CGRectGetMinY(rect1)); } diff --git a/KKGridView/KKGridView.h b/KKGridView/KKGridView.h index dda7cb0..5c36c4a 100755 --- a/KKGridView/KKGridView.h +++ b/KKGridView/KKGridView.h @@ -104,6 +104,7 @@ typedef enum { - (CGFloat)gridView:(KKGridView *)gridView heightForFooterInSection:(NSUInteger)section; - (UIView *)gridView:(KKGridView *)gridView viewForHeaderInSection:(NSUInteger)section; - (UIView *)gridView:(KKGridView *)gridView viewForFooterInSection:(NSUInteger)section; +- (UIView *)gridView:(KKGridView *)gridView viewForRow:(NSUInteger)row inSection:(NSUInteger)section; // a row is compromised of however many cells fit in a column of a given section - (NSArray *)sectionIndexTitlesForGridView:(KKGridView *)gridView; - (NSInteger)gridView:(KKGridView *)gridView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index; @end diff --git a/KKGridView/KKGridView.m b/KKGridView/KKGridView.m index 9db7bce..59a29c8 100755 --- a/KKGridView/KKGridView.m +++ b/KKGridView/KKGridView.m @@ -19,6 +19,7 @@ struct KKSectionMetrics { CGFloat footerHeight; CGFloat headerHeight; + CGFloat rowHeight; CGFloat sectionHeight; NSUInteger itemCount; }; @@ -26,6 +27,7 @@ @interface KKGridView () { // View-wrapper containers NSMutableArray *_footerViews; + NSMutableArray *_rowViews; NSMutableArray *_headerViews; // Metrics @@ -59,6 +61,7 @@ @interface KKGridView () { unsigned int heightForFooter:1; unsigned int viewForHeader:1; unsigned int viewForFooter:1; + unsigned int viewForRow:1; unsigned int sectionIndexTitles:1; unsigned int sectionForSectionIndexTitle:1; } _dataSourceRespondsTo; @@ -181,10 +184,8 @@ - (void)_sharedInitialization self.delaysContentTouches = YES; self.canCancelContentTouches = YES; - self.delegate = self; - _selectionRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(_handleSelection:)]; - _selectionRecognizer.minimumPressDuration = 0.01; + _selectionRecognizer.minimumPressDuration = 0.015; _selectionRecognizer.delegate = self; _selectionRecognizer.cancelsTouchesInView = NO; [self addGestureRecognizer:_selectionRecognizer]; @@ -196,12 +197,18 @@ - (void)_sharedInitialization self.cellPadding = CGSizeMake(4.f, 4.f); self.allowsMultipleSelection = NO; self.backgroundColor = [UIColor whiteColor]; + + + [self addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:NULL]; + [self addObserver:self forKeyPath:@"tracking" options:NSKeyValueObservingOptionNew context:NULL]; } #pragma mark - Cleanup - (void)dealloc { + [self removeObserver:self forKeyPath:@"contentOffset"]; + [self removeObserver:self forKeyPath:@"tracking"]; [self removeGestureRecognizer:_selectionRecognizer]; [self _cleanupMetrics]; } @@ -227,6 +234,7 @@ - (void)setDataSource:(id)dataSource _dataSourceRespondsTo.heightForFooter = [_dataSource respondsToSelector:@selector(gridView:heightForFooterInSection:)]; _dataSourceRespondsTo.viewForHeader = [_dataSource respondsToSelector:@selector(gridView:viewForHeaderInSection:)]; _dataSourceRespondsTo.viewForFooter = [_dataSource respondsToSelector:@selector(gridView:viewForFooterInSection:)]; + _dataSourceRespondsTo.viewForRow = [_dataSource respondsToSelector:@selector(gridView:viewForRow:inSection:)]; _dataSourceRespondsTo.sectionIndexTitles = [_dataSource respondsToSelector:@selector(sectionIndexTitlesForGridView:)]; _dataSourceRespondsTo.sectionForSectionIndexTitle = [_dataSource respondsToSelector:@selector(gridView:sectionForSectionIndexTitle:atIndex:)]; [self reloadData]; @@ -285,16 +293,22 @@ - (void)setAllowsMultipleSelection:(BOOL)allowsMultipleSelection - (void)setCellPadding:(CGSize)cellPadding { - _cellPadding = cellPadding; - if (_cellSize.width != 0.f && _cellSize.height != 0.f) { + if (!CGSizeEqualToSize(_cellPadding, cellPadding)) { + _cellPadding = cellPadding; + + [self _layoutModelCells]; + [self reloadData]; } } - (void)setCellSize:(CGSize)cellSize { - _cellSize = cellSize; - if (_cellPadding.width != 0.f && _cellPadding.height != 0.f) { + if (!CGSizeEqualToSize(_cellSize, cellSize)) { + _cellSize = cellSize; + + [self _layoutModelCells]; + [self reloadData]; } } @@ -592,8 +606,10 @@ - (void)_cleanupCells KKGridViewCell *cell = pair.cell; [self _enqueueCell:cell withIdentifier:cell.reuseIdentifier]; - cell.frame = (CGRect){.size = _cellSize}; - [cell removeFromSuperview]; + if (!CGSizeEqualToSize(_cellSize, cell.frame.size)) + cell.frame = (CGRect){.size = _cellSize}; + cell.hidden = YES; + cell.alpha = 0.; [_visibleCells removeObjectForKey:pair.path]; } @@ -643,6 +659,20 @@ - (CGFloat)_sectionHeightsCombinedUpToSection:(NSUInteger)section return height; } +- (CGFloat)_sectionHeightsCombinedUpToRow:(NSUInteger)row inSection:(NSUInteger)section +{ + CGFloat height = 0.f; + for (NSUInteger index = 0; index < section && index < _metrics.count; index++) { + height += _metrics.sections[index].sectionHeight; + } + + for (NSUInteger index = 0; index < row; index++) { + height += _metrics.sections[section].rowHeight; + } + return height; +} + + #pragma mark - Cell Management - (void)_displayCell:(KKGridViewCell *)cell atIndexPath:(KKIndexPath *)indexPath withAnimation:(KKGridViewAnimation)animation @@ -666,10 +696,15 @@ - (void)_displayCell:(KKGridViewCell *)cell atIndexPath:(KKIndexPath *)indexPath break; } - if (_backgroundView) - [self insertSubview:cell aboveSubview:_backgroundView]; - else - [self insertSubview:cell atIndex:0]; + if (cell.superview) { + cell.hidden = NO; + cell.alpha = 1.; + } else { + if (_backgroundView) + [self insertSubview:cell atIndex:(_rowViews.count + 1)]; + else + [self insertSubview:cell atIndex:_rowViews.count]; + } switch (animation) { case KKGridViewAnimationExplode: { @@ -769,13 +804,13 @@ - (CGRect)rectForCellAtIndexPath:(KKIndexPath *)indexPath point.y += _metrics.sections[indexPath.section].headerHeight; } - NSInteger row = floor(indexPath.index / _numberOfColumns); + NSInteger row = indexPath.index / _numberOfColumns; NSInteger column = indexPath.index - (row * _numberOfColumns); point.y += (row * (_cellSize.height + _cellPadding.height)); point.x += (column * (_cellSize.width + _cellPadding.width)); - return (CGRect){point, _cellSize}; + return CGRectIntegral((CGRect){point, _cellSize}); } - (KKGridViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier @@ -800,7 +835,7 @@ - (NSArray *)visibleIndexPaths const CGRect visibleBounds = {self.contentOffset, self.bounds.size}; NSMutableArray *indexPaths = [[NSMutableArray alloc] initWithCapacity:12]; - KKIndexPath *indexPath = [KKIndexPath indexPathForIndex:0 inSection:0]; + KKIndexPath *indexPath = [KKIndexPath zeroIndexPath]; for (NSUInteger section = 0; section < _metrics.count; section++) { indexPath.section = section; @@ -820,7 +855,7 @@ - (NSArray *)visibleIndexPaths return indexPaths; } -#pragma mark - Model Modifiers +#pragma mark - Public Setters - (void)_incrementCellsAtIndexPath:(KKIndexPath *)fromPath toIndexPath:(KKIndexPath *)toPath byAmount:(NSUInteger)amount negative:(BOOL)isNegative { @@ -840,7 +875,7 @@ - (void)_incrementCellsAtIndexPath:(KKIndexPath *)fromPath toIndexPath:(KKIndexP [UIView animateWithDuration:KKGridViewDefaultAnimationDuration animations:^{ cell.alpha = 0.f; } completion:^(BOOL finished) { - [cell removeFromSuperview]; + cell.hidden = YES; }]; } if (!indexPathIsLessOrEqual || !lastPathIsGreatorOrEqual) { @@ -974,7 +1009,8 @@ - (void)reloadItemsAtIndexPaths:(NSArray *)indexPaths for (KKIndexPath *path in indexPaths) { KKGridViewCell *cell = [_visibleCells objectForKey:path]; if (cell) { - [cell removeFromSuperview]; + cell.hidden = YES; + cell.alpha = 0.; [_visibleCells removeObjectForKey:path]; } @@ -989,7 +1025,7 @@ - (void)_commonReload { [self reloadContentSize]; - void (^clearSectionViews)(NSMutableArray *) = ^(NSMutableArray *views) { + void (^clearViewsInArray)(NSMutableArray *) = ^(NSMutableArray *views) { for (id view in [views valueForKey:@"view"]) { if (view != [NSNull null]) [view removeFromSuperview]; @@ -999,7 +1035,7 @@ - (void)_commonReload }; if (_dataSourceRespondsTo.viewForHeader || _dataSourceRespondsTo.titleForHeader) { - clearSectionViews(_headerViews); + clearViewsInArray(_headerViews); if (!_headerViews) { _headerViews = [[NSMutableArray alloc] initWithCapacity:_metrics.count]; @@ -1017,8 +1053,45 @@ - (void)_commonReload } } + if (_dataSourceRespondsTo.viewForRow) { + clearViewsInArray(_rowViews); + if (!_rowViews) + { + _rowViews = [[NSMutableArray alloc] initWithCapacity:_metrics.count]; + } + + for (NSUInteger section = 0; section < _metrics.count; section++) { + NSInteger previouslyCheckedRow = -1; + + for (NSUInteger index = 0; index < _metrics.sections[section].itemCount; index++) { + NSInteger row = index / _numberOfColumns; + + if (row <= previouslyCheckedRow) + continue; + + previouslyCheckedRow = row; + + UIView *view = [_dataSource gridView:self viewForRow:row inSection:section]; + if (!view) { + continue; + } + + KKGridViewRowBackground *rowBackground = [[KKGridViewRowBackground alloc] initWithView:view]; + [_rowViews addObject:rowBackground]; + + CGFloat rowHeight = _cellSize.height + _cellPadding.height; + CGFloat position = [self _sectionHeightsCombinedUpToRow:row inSection:section] + _gridHeaderView.frame.size.height; + [self _configureSectionView:rowBackground inSection:section withStickPoint:position height:rowHeight]; + + if (_backgroundView) + [self insertSubview:rowBackground.view aboveSubview:_backgroundView]; + else [self insertSubview:rowBackground.view atIndex:0]; + } + } + } + if (_dataSourceRespondsTo.viewForFooter || _dataSourceRespondsTo.titleForFooter) { - clearSectionViews(_footerViews); + clearViewsInArray(_footerViews); if (!_footerViews) { _footerViews = [[NSMutableArray alloc] initWithCapacity:_metrics.count]; @@ -1077,7 +1150,8 @@ - (void)reloadData for (KKGridViewCell *cell in [_visibleCells allValues]) { NSMutableSet *set = [self _reusableCellSetForIdentifier:cell.reuseIdentifier]; [set addObject:cell]; - [cell removeFromSuperview]; + cell.hidden = YES; + cell.alpha = 0.; } [_visibleCells removeAllObjects]; @@ -1110,12 +1184,12 @@ - (void)reloadContentSize CGFloat heightForSection = 0.f; struct KKSectionMetrics sectionMetrics = _metrics.sections[i]; + _metrics.sections[i].rowHeight = (_cellSize.height + _cellPadding.height); heightForSection += sectionMetrics.headerHeight + sectionMetrics.footerHeight; NSUInteger numberOfRows = ceilf(sectionMetrics.itemCount / (float)_numberOfColumns); - - heightForSection += numberOfRows * (_cellSize.height + _cellPadding.height); + heightForSection += numberOfRows * _metrics.sections[i].rowHeight; heightForSection += (numberOfRows? _cellPadding.height:0.f); _metrics.sections[i].sectionHeight = heightForSection; @@ -1429,7 +1503,10 @@ - (void)_handleSelection:(UILongPressGestureRecognizer *)recognizer KKIndexPath *indexPath = [self indexPathForItemAtPoint:locationInSelf]; - if (indexPath.index == NSNotFound || indexPath.section == NSNotFound) { + if (state == UIGestureRecognizerStateEnded && _delegateRespondsTo.willSelectItem) + indexPath = [_gridDelegate gridView:self willSelectItemAtIndexPath:indexPath]; + + if (!indexPath || indexPath.index == NSNotFound || indexPath.section == NSNotFound) { [self _cancelHighlighting]; return; } @@ -1458,19 +1535,21 @@ - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecogni return (gestureRecognizer == _selectionRecognizer || otherGestureRecognizer == _selectionRecognizer); } +#pragma mark - KVO -#pragma mark - UIScrollViewDelegate - -- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView +- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { - [self _cancelHighlighting]; -} - -- (void)scrollViewDidScroll:(UIScrollView *)scrollView { - _indexView.frame = (CGRect) { - {_indexView.frame.origin.x, scrollView.contentOffset.y}, - _indexView.frame.size - }; + if ([keyPath isEqualToString:@"contentOffset"]) { + _indexView.frame = (CGRect) { + {_indexView.frame.origin.x, self.contentOffset.y}, + _indexView.frame.size + }; + [self _cancelHighlighting]; + } else if ([keyPath isEqualToString:@"tracking"]) { + if (self.tracking && !self.dragging) { + [self _cancelHighlighting]; + } + } } #pragma mark - Animation Helpers diff --git a/KKGridView/KKGridViewCell.m b/KKGridView/KKGridViewCell.m index 4148dc7..c9ff13c 100755 --- a/KKGridView/KKGridViewCell.m +++ b/KKGridView/KKGridViewCell.m @@ -57,18 +57,14 @@ + (id)cellForGridView:(KKGridView *)gridView - (id)initWithFrame:(CGRect)frame reuseIdentifier:(NSString *)reuseIdentifier { if ((self = [super initWithFrame:frame])) { - self.reuseIdentifier = reuseIdentifier; + _reuseIdentifier = reuseIdentifier; _backgroundView = [[UIView alloc] initWithFrame:self.bounds]; _backgroundView.backgroundColor = [UIColor whiteColor]; [self addSubview:_backgroundView]; - - _selectedBackgroundView = [[UIView alloc] initWithFrame:self.bounds]; - _selectedBackgroundView.hidden = YES; - _selectedBackgroundView.alpha = 0.f; + _highlightAlpha = 1.0f; - - + _contentView = [[UIView alloc] initWithFrame:self.bounds]; _contentView.backgroundColor = [UIColor whiteColor]; [self addSubview:_contentView]; @@ -92,16 +88,8 @@ - (void)awakeFromNib { _backgroundView.backgroundColor = [UIColor whiteColor]; } - if (!_selectedBackgroundView) { - _selectedBackgroundView = [[UIView alloc] initWithFrame:self.bounds]; - } - - _selectedBackgroundView.hidden = YES; - _selectedBackgroundView.alpha = 0.f; - - [self addSubview:_contentView]; [self addSubview:_backgroundView]; - [self addSubview:_selectedBackgroundView]; + [self addSubview:_contentView]; [self bringSubviewToFront:_contentView]; [self bringSubviewToFront:_badgeView]; @@ -126,6 +114,19 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N } } +#pragma mark - Getters + +- (UIView *)selectedBackgroundView +{ + if (!_selectedBackgroundView) + _selectedBackgroundView = [[UIView alloc] initWithFrame:self.bounds]; + + _selectedBackgroundView.hidden = YES; + _selectedBackgroundView.alpha = 0.f; + + return _selectedBackgroundView; +} + #pragma mark - Setters - (void)setAccessoryType:(KKGridViewCellAccessoryType)accessoryType @@ -149,14 +150,33 @@ - (void)setEditing:(BOOL)editing animated:(BOOL)animated [UIView commitAnimations]; } +- (void)setPressedState:(BOOL)pressedState +{ + if (pressedState) { + if (!_selectedBackgroundView) + _selectedBackgroundView = [[UIView alloc] initWithFrame:self.bounds]; + + if (!_selectedBackgroundView.superview) + [self addSubview:_selectedBackgroundView]; + + if (!_selectedBackgroundView.backgroundColor) + _selectedBackgroundView.backgroundColor = [UIColor colorWithPatternImage:[self _defaultBlueBackgroundRendition]]; + + _selectedBackgroundView.hidden = NO; + _selectedBackgroundView.alpha = 1.f; + } else { + _selectedBackgroundView.hidden = YES; + _selectedBackgroundView.alpha = 0.f; + } + + [self setNeedsLayout]; +} + - (void)setSelected:(BOOL)selected { if (_selected != selected) { _selected = selected; - [self setNeedsLayout]; - - if (selected && !_selectedBackgroundView.backgroundColor) - _selectedBackgroundView.backgroundColor = [UIColor colorWithPatternImage:[self _defaultBlueBackgroundRendition]]; + [self setPressedState:selected]; } } @@ -164,14 +184,10 @@ - (void)setHighlighted:(BOOL)highlighted { if (_highlighted != highlighted) { _highlighted = highlighted; - [self setNeedsLayout]; - - if (highlighted && !_selectedBackgroundView.backgroundColor) - _selectedBackgroundView.backgroundColor = [UIColor colorWithPatternImage:[self _defaultBlueBackgroundRendition]]; + [self setPressedState:highlighted]; } } - - (void)setSelected:(BOOL)selected animated:(BOOL)animated { if (_selected != selected) { @@ -179,8 +195,8 @@ - (void)setSelected:(BOOL)selected animated:(BOOL)animated UIViewAnimationOptions opts = UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionAllowAnimatedContent; [UIView animateWithDuration:duration delay:0 options:opts animations:^{ - _selected = selected; - _selectedBackgroundView.alpha = selected ? self.highlightAlpha : 0.f; + self.selected = selected; // use property access to go through the setter + _selectedBackgroundView.alpha = selected ? _highlightAlpha : 0.f; } completion:^(BOOL finished) { [self setNeedsLayout]; }]; @@ -214,27 +230,36 @@ - (void)layoutSubviews { [self _updateSubviewSelectionState]; - _contentView.frame = self.bounds; - _backgroundView.frame = self.bounds; - _selectedBackgroundView.frame = self.bounds; + CGRect bounds = self.bounds; + _contentView.frame = bounds; + + if (!_backgroundView.hidden) + _backgroundView.frame = bounds; + else _selectedBackgroundView.frame = bounds; + + if (_selectedBackgroundView) + [self sendSubviewToBack:_selectedBackgroundView]; [self sendSubviewToBack:_backgroundView]; [self bringSubviewToFront:_contentView]; [self bringSubviewToFront:_selectedBackgroundView]; [self bringSubviewToFront:_badgeView]; - if (_selected || _highlighted) { _contentView.backgroundColor = [UIColor clearColor]; _contentView.opaque = NO; + + _backgroundView.hidden = YES; + _selectedBackgroundView.hidden = NO; + _selectedBackgroundView.alpha = _highlightAlpha; } else { _contentView.backgroundColor = _userContentViewBackgroundColor ? _userContentViewBackgroundColor : [UIColor whiteColor]; + + _backgroundView.hidden = NO; + _selectedBackgroundView.hidden = YES; + _selectedBackgroundView.alpha = 0.f; } - _selectedBackgroundView.hidden = !_selected && !_highlighted; - _backgroundView.hidden = _selected || _highlighted; - _selectedBackgroundView.alpha = (_selected || _highlighted) ? self.highlightAlpha : 0.f; - [self _layoutAccessories]; } @@ -345,7 +370,7 @@ - (UIImage *)_defaultBlueBackgroundRendition - (void)prepareForReuse { - + self.selected = NO; } @end diff --git a/KKGridView/KKGridViewSectionInfo.h b/KKGridView/KKGridViewSectionInfo.h index 93e36a4..b9fdcd9 100755 --- a/KKGridView/KKGridViewSectionInfo.h +++ b/KKGridView/KKGridViewSectionInfo.h @@ -20,8 +20,6 @@ @end -@interface KKGridViewFooter : KKGridViewSectionInfo -@end - -@interface KKGridViewHeader : KKGridViewSectionInfo -@end +@compatibility_alias KKGridViewFooter KKGridViewSectionInfo; +@compatibility_alias KKGridViewHeader KKGridViewSectionInfo; +@compatibility_alias KKGridViewRowBackground KKGridViewSectionInfo; diff --git a/KKGridView/KKGridViewSectionInfo.m b/KKGridView/KKGridViewSectionInfo.m index 7f965a7..fe0fa8b 100755 --- a/KKGridView/KKGridViewSectionInfo.m +++ b/KKGridView/KKGridViewSectionInfo.m @@ -22,9 +22,3 @@ - (id)initWithView:(UIView *)view } @end - -@implementation KKGridViewFooter -@end - -@implementation KKGridViewHeader -@end \ No newline at end of file diff --git a/KKGridView/KKGridViewUpdateStack.m b/KKGridView/KKGridViewUpdateStack.m index 55e0c65..48c45d0 100755 --- a/KKGridView/KKGridViewUpdateStack.m +++ b/KKGridView/KKGridViewUpdateStack.m @@ -9,9 +9,12 @@ #import #import -@interface KKGridViewUpdateStack () +@interface KKGridViewUpdateStack () { + CFMutableDictionaryRef _availableUpdates; +} - (void)_sortItems; +- (BOOL)addUpdate:(KKGridViewUpdate *)update sortingAfterAdd:(BOOL) sortAfterAdd; @end @@ -23,6 +26,7 @@ - (id)init { if ((self = [super init])) { _itemsToUpdate = [[NSMutableArray alloc] init]; + _availableUpdates = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); } return self; @@ -31,14 +35,21 @@ - (id)init - (void)addUpdates:(NSArray *)updates { for (KKGridViewUpdate *update in updates) { - [self addUpdate:update]; + [self addUpdate:update sortingAfterAdd:NO]; } + [self _sortItems]; } - (BOOL)addUpdate:(KKGridViewUpdate *)update +{ + return [self addUpdate:update sortingAfterAdd:YES]; +} + +- (BOOL)addUpdate:(KKGridViewUpdate *)update sortingAfterAdd:(BOOL) sortAfterAdd { if (![_itemsToUpdate containsObject:update]) { [_itemsToUpdate addObject:update]; + CFDictionaryAddValue(_availableUpdates, objc_unretainedPointer(update.indexPath), objc_unretainedPointer(update)); [self _sortItems]; return YES; } @@ -54,6 +65,7 @@ - (void)removeUpdateForIndexPath:(KKIndexPath *)indexPath - (void)removeUpdate:(KKGridViewUpdate *)update { + CFDictionaryRemoveValue(_availableUpdates, objc_unretainedPointer(update.indexPath)); [_itemsToUpdate removeObject:update]; } @@ -64,24 +76,15 @@ - (void)_sortItems - (KKGridViewUpdate *)updateForIndexPath:(KKIndexPath *)indexPath { - NSPredicate *sameIndexPath = [NSPredicate predicateWithFormat:@"indexPath = %@", indexPath]; - return [[_itemsToUpdate filteredArrayUsingPredicate:sameIndexPath] objectAtIndex:0]; + return objc_unretainedObject(CFDictionaryGetValue(_availableUpdates, objc_unretainedPointer(indexPath))); } - (BOOL)hasUpdateForIndexPath:(KKIndexPath *)indexPath { - NSUInteger count = _itemsToUpdate.count; + KKGridViewUpdate *update = objc_unretainedObject(CFDictionaryGetValue(_availableUpdates, objc_unretainedPointer(indexPath))); + if (update && !update.animating) + return YES; - if (count == 0) - return NO; - - for (NSUInteger i = 0; i < count; i++) { - KKGridViewUpdate *update = [_itemsToUpdate objectAtIndex:i]; - if (!update.animating && [update.indexPath isEqual:indexPath]) { - return YES; - } - } - return NO; } diff --git a/KKGridView/KKIndexPath.h b/KKGridView/KKIndexPath.h index 67c4270..0a5bf8c 100755 --- a/KKGridView/KKIndexPath.h +++ b/KKGridView/KKIndexPath.h @@ -7,6 +7,7 @@ // @interface KKIndexPath : NSObject ++ (KKIndexPath *) zeroIndexPath; + (NSArray *) indexPathsWithNSIndexPaths:(NSArray *) indexPaths; - (id)initWithIndex:(NSUInteger)index section:(NSUInteger)section; diff --git a/KKGridView/KKIndexPath.m b/KKGridView/KKIndexPath.m index 4ca94e8..7e830f7 100755 --- a/KKGridView/KKIndexPath.m +++ b/KKGridView/KKIndexPath.m @@ -115,4 +115,13 @@ - (NSIndexPath *)NSIndexPath { return [NSIndexPath indexPathForRow:_index inSection:_section]; } +#pragma mark - Convenience + ++ (KKIndexPath *) zeroIndexPath { + static KKIndexPath *indexPath = nil; + if (!indexPath) + indexPath = [[KKIndexPath alloc] initWithIndex:0 section:0]; + return indexPath; +} + @end