Permalink
Browse files

match ivar layout 1:1. Fixes #46.

  • Loading branch information...
1 parent f8d5cd1 commit dfdeb533829e52f4521b6de187c01f6831fa743b @steipete committed Oct 3, 2012
@@ -84,6 +84,7 @@ typedef NS_OPTIONS(NSUInteger, UICollectionViewScrollPosition) {
- (id)dequeueReusableCellWithReuseIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath;
- (id)dequeueReusableSupplementaryViewOfKind:(NSString *)elementKind withReuseIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath;
+
// These properties control whether items can be selected, and if so, whether multiple items can be simultaneously selected.
@property (nonatomic) BOOL allowsSelection; // default is YES
@property (nonatomic) BOOL allowsMultipleSelection; // default is NO
@@ -160,5 +161,4 @@ typedef NS_OPTIONS(NSUInteger, UICollectionViewScrollPosition) {
#define PSUICollectionViewFlowLayout UICollectionViewCell
#define PSUICollectionViewLayoutAttributes UICollectionViewLayoutAttributes
#define PSUICollectionViewController UICollectionViewController
-
#endif
@@ -21,47 +21,83 @@ @interface PSTCollectionViewLayout (Internal)
CGFloat PSTSimulatorAnimationDragCoefficient(void);
@interface PSTCollectionView() {
- id _nibObserverToken;
- PSTCollectionViewLayout *_nibLayout;
-
- BOOL _rotationActive;
- NSMutableDictionary *_allVisibleViewsDict;
+ // ivar layout needs to EQUAL to UICollectionView.
+ PSTCollectionViewLayout *_layout;
+ __unsafe_unretained id<PSTCollectionViewDataSource> _dataSource;
+ UIView *_backgroundView;
+ NSMutableSet *_indexPathsForSelectedItems;
NSMutableDictionary *_cellReuseQueues;
NSMutableDictionary *_supplementaryViewReuseQueues;
-
- NSMutableDictionary *_cellClassDict, *_cellNibDict;
- NSMutableDictionary *_supplementaryViewClassDict, *_supplementaryViewNibDict;
-
- NSUInteger _reloadingSuspendedCount;
- NSMutableSet *_indexPathsForSelectedItems;
NSMutableSet *_indexPathsForHighlightedItems;
-
+ int _reloadingSuspendedCount;
+ PSTCollectionReusableView *_firstResponderView;
+ UIView *_newContentView;
+ int _firstResponderViewType;
+ NSString *_firstResponderViewKind;
+ NSIndexPath *_firstResponderIndexPath;
+ NSMutableDictionary *_allVisibleViewsDict;
+ NSIndexPath *_pendingSelectionIndexPath;
+ NSMutableSet *_pendingDeselectionIndexPaths;
+ PSTCollectionViewData *_collectionViewData;
+ id _update;
+ CGRect _visibleBounds;
+ CGRect _preRotationBounds;
+ CGPoint _rotationBoundsOffset;
+ int _rotationAnimationCount;
+ int _updateCount;
+ NSMutableArray *_insertItems;
+ NSMutableArray *_deleteItems;
+ NSMutableArray *_reloadItems;
+ NSMutableArray *_moveItems;
+ NSArray *_originalInsertItems;
+ NSArray *_originalDeleteItems;
+ UITouch *_currentTouch;
+ id _updateCompletionHandler;
+ NSMutableDictionary *_cellClassDict;
+ NSMutableDictionary *_cellNibDict;
+ NSMutableDictionary *_supplementaryViewClassDict;
+ NSMutableDictionary *_supplementaryViewNibDict;
+ NSMutableDictionary *_cellNibExternalObjectsTables;
+ NSMutableDictionary *_supplementaryViewNibExternalObjectsTables;
struct {
- /*
- unsigned int reloadSkippedDuringSuspension : 1;
- unsigned int scheduledUpdateVisibleCells : 1;
- unsigned int scheduledUpdateVisibleCellLayoutAttributes : 1;
- unsigned int allowsSelection : 1;
- unsigned int allowsMultipleSelection : 1;
- unsigned int updating : 1;
- */
+ unsigned int delegateShouldHighlightItemAtIndexPath : 1;
+ unsigned int delegateDidHighlightItemAtIndexPath : 1;
+ unsigned int delegateDidUnhighlightItemAtIndexPath : 1;
+ unsigned int delegateShouldSelectItemAtIndexPath : 1;
+ unsigned int delegateShouldDeselectItemAtIndexPath : 1;
+ unsigned int delegateDidSelectItemAtIndexPath : 1;
+ unsigned int delegateDidDeselectItemAtIndexPath : 1;
+ unsigned int delegateSupportsMenus : 1;
+ unsigned int delegateDidEndDisplayingCell : 1;
+ unsigned int delegateDidEndDisplayingSupplementaryView : 1;
+ unsigned int dataSourceNumberOfSections : 1;
+ unsigned int dataSourceViewForSupplementaryElement : 1;
+ unsigned int reloadSkippedDuringSuspension : 1;
+ unsigned int scheduledUpdateVisibleCells : 1;
+ unsigned int scheduledUpdateVisibleCellLayoutAttributes : 1;
+ unsigned int allowsSelection : 1;
+ unsigned int allowsMultipleSelection : 1;
+ unsigned int updating : 1;
unsigned int fadeCellsForBoundsChange : 1;
- /*
- unsigned int updatingLayout : 1;
- unsigned int needsReload : 1;
- unsigned int reloading : 1;
- unsigned int skipLayoutDuringSnapshotting : 1;
- unsigned int layoutInvalidatedSinceLastCellUpdate : 1;
- */
+ unsigned int updatingLayout : 1;
+ unsigned int needsReload : 1;
+ unsigned int reloading : 1;
+ unsigned int skipLayoutDuringSnapshotting : 1;
+ unsigned int layoutInvalidatedSinceLastCellUpdate : 1;
+ unsigned int doneFirstLayout : 1;
} _collectionViewFlags;
+ CGPoint _lastLayoutOffset;
}
@property (nonatomic, strong) PSTCollectionViewData *collectionViewData;
-@property (nonatomic, strong) NSString *collectionViewClassString;
-
@end
+const char kPSTNibObserverToken;
+const char kPSTNibLayout;
+
@implementation PSTCollectionView
+@synthesize collectionViewLayout = _layout;
+
///////////////////////////////////////////////////////////////////////////////////////////
#pragma mark - NSObject
@@ -91,23 +127,24 @@ - (id)initWithCoder:(NSCoder *)inCoder {
PSTCollectionViewCommonSetup(self);
// add observer for nib deserialization.
- _nibObserverToken = [[NSNotificationCenter defaultCenter] addObserverForName:PSTCollectionViewLayoutAwokeFromNib object:nil queue:nil usingBlock:^(NSNotification *note) { _nibLayout = note.object; }];
+
+ id nibObserverToken = [[NSNotificationCenter defaultCenter] addObserverForName:PSTCollectionViewLayoutAwokeFromNib object:nil queue:nil usingBlock:^(NSNotification *note) { objc_setAssociatedObject(self, &kPSTNibLayout, note.object, OBJC_ASSOCIATION_RETAIN_NONATOMIC); }];
+ objc_setAssociatedObject(self, &kPSTNibObserverToken, nibObserverToken, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
return self;
}
- (void)awakeFromNib {
[super awakeFromNib];
- if (self.collectionViewClassString) {
- self.collectionViewLayout = [NSClassFromString(self.collectionViewClassString) new];
- }
-
// check if NIB deserialization found a layout.
// TODO: is there no better way for this???
- [[NSNotificationCenter defaultCenter] removeObserver:_nibObserverToken]; _nibObserverToken = nil;
- if (_nibLayout) {
- self.collectionViewLayout = _nibLayout; _nibLayout = nil;
+ id nibObserverToken = objc_getAssociatedObject(self, &kPSTNibObserverToken);
+ [[NSNotificationCenter defaultCenter] removeObserver:nibObserverToken]; objc_setAssociatedObject(self, &kPSTNibObserverToken, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+
+ PSTCollectionViewLayout *nibLayout = objc_getAssociatedObject(self, &kPSTNibLayout);
+ if (nibLayout) {
+ self.collectionViewLayout = nibLayout; objc_setAssociatedObject(self, &kPSTNibLayout, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
}
@@ -116,7 +153,8 @@ - (NSString *)description {
}
- (void)dealloc {
- if (_nibObserverToken) [[NSNotificationCenter defaultCenter] removeObserver:_nibObserverToken];
+ id nibObserverToken = objc_getAssociatedObject(self, &kPSTNibObserverToken);
+ if (nibObserverToken) [[NSNotificationCenter defaultCenter] removeObserver:nibObserverToken];
}
///////////////////////////////////////////////////////////////////////////////////////////
@@ -556,9 +594,9 @@ - (void)setBackgroundView:(UIView *)backgroundView {
}
- (void)setCollectionViewLayout:(PSTCollectionViewLayout *)layout animated:(BOOL)animated {
- if (layout != _collectionViewLayout) {
- _collectionViewLayout.collectionView = nil;
- _collectionViewLayout = layout;
+ if (layout != _layout) {
+ _layout.collectionView = nil;
+ _layout = layout;
layout.collectionView = self;
_collectionViewData = [[PSTCollectionViewData alloc] initWithCollectionView:self layout:layout];
[self reloadData];
@@ -569,6 +607,22 @@ - (void)setCollectionViewLayout:(PSTCollectionViewLayout *)layout {
[self setCollectionViewLayout:layout animated:NO];
}
+- (BOOL)allowsSelection {
+ return _collectionViewFlags.allowsSelection;
+}
+
+- (void)setAllowsSelection:(BOOL)allowsSelection {
+ _collectionViewFlags.allowsSelection = allowsSelection;
+}
+
+- (BOOL)allowsMultipleSelection {
+ return _collectionViewFlags.allowsMultipleSelection;
+}
+
+- (void)setAllowsMultipleSelection:(BOOL)allowsMultipleSelection {
+ _collectionViewFlags.allowsMultipleSelection = allowsMultipleSelection;
+}
+
///////////////////////////////////////////////////////////////////////////////////////////
#pragma mark - Private
@@ -815,3 +869,26 @@ CGFloat PSTSimulatorAnimationDragCoefficient(void) {
#endif
return UIAnimationDragCoefficient ? UIAnimationDragCoefficient() : 1.f;
}
+
+// helper to check for ivar layout
+#if 0
+static void PSTPrintIvarsForClass(Class aClass) {
+ unsigned int varCount;
+ Ivar *vars = class_copyIvarList(aClass, &varCount);
+ for (int i = 0; i < varCount; i++) {
+ NSLog(@"%s %s", ivar_getTypeEncoding(vars[i]), ivar_getName(vars[i]));
+ }
+ free(vars);
+}
+
+__attribute__((constructor)) static void PSTCheckIfIVarLayoutIsEqualSize(void) {
+ @autoreleasepool {
+ NSLog(@"PSTCollectionView size = %zd, UICollectionView size = %zd", class_getInstanceSize([PSTCollectionView class]),class_getInstanceSize([UICollectionView class]));
+ NSLog(@"PSTCollectionViewCell size = %zd, UICollectionViewCell size = %zd", class_getInstanceSize([PSTCollectionViewCell class]),class_getInstanceSize([UICollectionViewCell class]));
+ NSLog(@"PSTCollectionViewController size = %zd, UICollectionViewController size = %zd", class_getInstanceSize([PSTCollectionViewController class]),class_getInstanceSize([UICollectionViewController class]));
+ NSLog(@"PSTCollectionViewLayout size = %zd, UICollectionViewLayout size = %zd", class_getInstanceSize([PSTCollectionViewLayout class]),class_getInstanceSize([UICollectionViewLayout class]));
+ NSLog(@"PSTCollectionViewFlowLayout size = %zd, UICollectionViewFlowLayout size = %zd", class_getInstanceSize([PSTCollectionViewFlowLayout class]),class_getInstanceSize([UICollectionViewFlowLayout class]));
+ //PSTPrintIvarsForClass([PSTCollectionViewFlowLayout class]); NSLog(@"\n\n\n");PSTPrintIvarsForClass([UICollectionViewFlowLayout class]);
+ }
+}
+#endif
@@ -31,21 +31,7 @@
@end
-// We need to be careful and keep the same ivar layout as UICollectionViewCell,
-// else we might crash with after using class_setSuperclass if subclasses change the ivar layout.
-@interface PSTCollectionViewCell : PSTCollectionReusableView {
- UILongPressGestureRecognizer *_menuGesture; // unused
- id _selectionSegueTemplate; // unused.
- id _highlightingSupport; // Apple uses UICellHighlightingSupport. Currently unused.
- struct {
- unsigned int selected:1;
- unsigned int highlighted:1;
- // currently unused
- unsigned int showingMenu:1;
- unsigned int clearSelectionWhenMenuDisappears:1;
- unsigned int waitingForSelectionAnimationHalfwayPoint:1;
- } _collectionCellFlags;
-}
+@interface PSTCollectionViewCell : PSTCollectionReusableView
@property (nonatomic, readonly) UIView *contentView; // add custom subviews to the cell's contentView
@@ -10,8 +10,11 @@
#import "PSTCollectionViewLayout.h"
@interface PSTCollectionReusableView() {
+ PSTCollectionViewLayoutAttributes *_layoutAttributes;
+ NSString *_reuseIdentifier;
+ __unsafe_unretained PSTCollectionView *_collectionView;
struct {
- unsigned int inUpdateAnimation:1;
+ unsigned int inUpdateAnimation : 1;
} _reusableViewFlags;
}
@property (nonatomic, copy) NSString *reuseIdentifier;
@@ -78,7 +81,23 @@ - (void)setInUpdateAnimation:(BOOL)inUpdateAnimation {
@end
-@implementation PSTCollectionViewCell
+@implementation PSTCollectionViewCell {
+ UIView *_contentView;
+ UIView *_backgroundView;
+ UIView *_selectedBackgroundView;
+ UILongPressGestureRecognizer *_menuGesture;
+ id _selectionSegueTemplate;
+ id _highlightingSupport;
+ struct {
+ unsigned int selected : 1;
+ unsigned int highlighted : 1;
+ unsigned int showingMenu : 1;
+ unsigned int clearSelectionWhenMenuDisappears : 1;
+ unsigned int waitingForSelectionAnimationHalfwayPoint : 1;
+ } _collectionCellFlags;
+ BOOL _selected;
+ BOOL _highlighted;
+}
///////////////////////////////////////////////////////////////////////////////////////////
#pragma mark - NSObject
@@ -9,12 +9,14 @@
#import "PSTCollectionView.h"
@interface PSTCollectionViewController () {
+ PSTCollectionViewLayout *_layout;
+ PSTCollectionView *_collectionView;
struct {
- unsigned int clearsSelectionOnViewWillAppear:1;
+ unsigned int clearsSelectionOnViewWillAppear : 1;
+ unsigned int appearsFirstTime : 1; // PST exension!
} _collectionViewControllerFlags;
}
@property (nonatomic, strong) PSTCollectionViewLayout* layout;
-@property (nonatomic, assign) BOOL appearsFirstTime;
@end
@implementation PSTCollectionViewController
@@ -26,7 +28,7 @@ - (id)initWithCollectionViewLayout:(PSTCollectionViewLayout *)layout {
if((self = [super init])) {
self.layout = layout;
self.clearsSelectionOnViewWillAppear = YES;
- self.appearsFirstTime = YES;
+ _collectionViewControllerFlags.appearsFirstTime = YES;
}
return self;
}
@@ -61,9 +63,9 @@ - (void)loadView {
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
- if (_appearsFirstTime) {
+ if (_collectionViewControllerFlags.appearsFirstTime) {
[_collectionView reloadData];
- self.appearsFirstTime = NO;
+ _collectionViewControllerFlags.appearsFirstTime = NO;
}
if (_collectionViewControllerFlags.clearsSelectionOnViewWillAppear) {
@@ -36,39 +36,7 @@ typedef NS_ENUM(NSInteger, UICollectionViewScrollDirection) {
@class PSTGridLayoutInfo;
-@interface PSTCollectionViewFlowLayout : PSTCollectionViewLayout {
- // class needs to have same iVar layout as UICollectionViewLayout
- struct {
- unsigned int delegateSizeForItem : 1;
- unsigned int delegateReferenceSizeForHeader : 1;
- unsigned int delegateReferenceSizeForFooter : 1;
- unsigned int delegateInsetForSection : 1;
- unsigned int delegateInteritemSpacingForSection : 1;
- unsigned int delegateLineSpacingForSection : 1;
- unsigned int delegateAlignmentOptions : 1;
- unsigned int keepDelegateInfoWhileInvalidating : 1;
- unsigned int keepAllDataWhileInvalidating : 1;
- unsigned int layoutDataIsValid : 1;
- unsigned int delegateInfoIsValid : 1;
- } _gridLayoutFlags;
- float _interitemSpacing;
- float _lineSpacing;
- CGSize _itemSize;
- CGSize _headerReferenceSize;
- CGSize _footerReferenceSize;
- UIEdgeInsets _sectionInset;
- PSTGridLayoutInfo *_data;
- CGSize _currentLayoutSize;
- NSMutableDictionary *_insertedItemsAttributesDict;
- NSMutableDictionary *_insertedSectionHeadersAttributesDict;
- NSMutableDictionary *_insertedSectionFootersAttributesDict;
- NSMutableDictionary *_deletedItemsAttributesDict;
- NSMutableDictionary *_deletedSectionHeadersAttributesDict;
- NSMutableDictionary *_deletedSectionFootersAttributesDict;
- PSTCollectionViewScrollDirection _scrollDirection;
- NSDictionary *_rowAlignmentsOptionsDictionary;
- CGRect _visibleBounds;
-}
+@interface PSTCollectionViewFlowLayout : PSTCollectionViewLayout
@property (nonatomic) CGFloat minimumLineSpacing;
@property (nonatomic) CGFloat minimumInteritemSpacing;
@@ -90,6 +58,7 @@ typedef NS_ENUM(NSInteger, UICollectionViewScrollDirection) {
rowAlign[@"UIFlowLayoutLastRowHorizontalAlignmentKey"] = @(3);
[flowLayout setValue:rowAlign forKey:@"_rowAlignmentsOptionsDictionary"];
*/
+
@property (nonatomic, strong) NSDictionary *rowAlignmentOptions;
@end
Oops, something went wrong.

0 comments on commit dfdeb53

Please sign in to comment.