Closed Goles closed 11 years ago
If you change theValue(10)
to theValue(11)
, does the counter stay the same? :)
[dataSourceMock stub:@selector(collectionView:numberOfItemsInSection:) andReturn:theValue(10)];
HILayoutAttributes is my own sub-class of UICollectionViewLayoutAttributes, I tested setting theValue(10)
to 15
and the number remained the same... so I went to the extreme and did theValue(1500)
. At that point I did:
NSArray *attributes = [layout layoutAttributesForElementsInRect:windowFrame];
NSLog(@"%@", attributes);
And got the following output (of 18 items)
"<HILayoutAttributes: 0x1753820> index path: (<NSIndexPath 0x1751aa0> 2 indexes [0, 0]); frame = (1.43053e-35 6.16571e-44; 200 200); ",
"<HILayoutAttributes: 0x1753d90> index path: (<NSIndexPath 0x1752450> 2 indexes [0, 1]); frame = (1.43053e-35 285; 200 200); ",
"<HILayoutAttributes: 0x1761d60> index path: (<NSIndexPath 0x1755a40> 2 indexes [0, 2]); frame = (1.43053e-35 569.999; 200 200); ",
"<HILayoutAttributes: 0x1761c00> index path: (<NSIndexPath 0x1750bc0> 2 indexes [0, 3]); frame = (200 6.16571e-44; 200 200); ",
"<HILayoutAttributes: 0x177f5d0> index path: (<NSIndexPath 0x17621f0> 2 indexes [0, 4]); frame = (200 285; 200 200); ",
"<HILayoutAttributes: 0x1132b930> index path: (<NSIndexPath 0x176f9c0> 2 indexes [0, 5]); frame = (200 569.999; 200 200); ",
"<HILayoutAttributes: 0x1132b9b0> index path: (<NSIndexPath 0x1776530> 2 indexes [0, 6]); frame = (371.8 -28.2; 256.4 256.4); transform = [1.282, 0, 0, 1.282, 0, 0]; zIndex = 1; ",
"<HILayoutAttributes: 0x1132ba30> index path: (<NSIndexPath 0x1763740> 2 indexes [0, 7]); frame = (371.8 256.8; 256.4 256.4); transform = [1.282, 0, 0, 1.282, 0, 0]; zIndex = 1; ",
"<HILayoutAttributes: 0x1132bab0> index path: (<NSIndexPath 0x1753910> 2 indexes [0, 8]); frame = (371.8 541.799; 256.4 256.4); transform = [1.282, 0, 0, 1.282, 0, 0]; zIndex = 1; ",
"<HILayoutAttributes: 0x1132bb30> index path: (<NSIndexPath 0x1761920> 2 indexes [0, 9]); frame = (598.2 -1.8; 203.6 203.6); transform = [1.018, 0, 0, 1.018, 0, 0]; zIndex = 1; ",
"<HILayoutAttributes: 0x1132b6d0> index path: (<NSIndexPath 0x1753470> 2 indexes [0, 10]); frame = (598.2 283.2; 203.6 203.6); transform = [1.018, 0, 0, 1.018, 0, 0]; zIndex = 1; ",
"<HILayoutAttributes: 0x1132b650> index path: (<NSIndexPath 0x17623a0> 2 indexes [0, 11]); frame = (598.2 568.199; 203.6 203.6); transform = [1.018, 0, 0, 1.018, 0, 0]; zIndex = 1; ",
"<HILayoutAttributes: 0x1132b5d0> index path: (<NSIndexPath 0x1788b40> 2 indexes [0, 12]); frame = (800 6.16571e-44; 200 200); ",
"<HILayoutAttributes: 0x1132b550> index path: (<NSIndexPath 0x17553e0> 2 indexes [0, 13]); frame = (800 285; 200 200); ",
"<HILayoutAttributes: 0x1132b4d0> index path: (<NSIndexPath 0x1753a90> 2 indexes [0, 14]); frame = (800 569.999; 200 200); ",
"<HILayoutAttributes: 0x1132b450> index path: (<NSIndexPath 0x1753770> 2 indexes [0, 15]); frame = (1000 6.16571e-44; 200 200); ",
"<HILayoutAttributes: 0x1132b3d0> index path: (<NSIndexPath 0x1754de0> 2 indexes [0, 16]); frame = (1000 285; 200 200); ",
"<HILayoutAttributes: 0x1132b350> index path: (<NSIndexPath 0x1752da0> 2 indexes [0, 17]); frame = (1000 569.999; 200 200); "
It's very strange though, don't know what could be going on, there should be 5 items on the screen (like the above picture shows...) maybe I'm missing some method call in my CollectionView? I tried to do [collectionView reloadData]
thinking that in that way my layout could somehow be applied, but no luck.
I could even send you the project if that could help you to see the issue :)
you can just expose your sublclass here as a comment, maybe that could tell us something more helpful
@mneorr Here's my UICollectionViewFlowLayout SubClass
#import "HICollectionViewLineLayout.h"
#import "HILayoutAttributes.h"
static const NSInteger ITEM_SIZE = 200;
static const NSInteger INSET_HEIGHT_SIZE = 200;
static const CGFloat ACTIVE_DISTANCE = 200.0f;
static const CGFloat ZOOM_FACTOR = 0.3f;
@implementation HICollectionViewLineLayout
- (id)init
{
if(self = [super init]) {
self.itemSize = CGSizeMake(ITEM_SIZE, ITEM_SIZE);
self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
self.sectionInset = UIEdgeInsetsMake(200.0f, 0.0f, 200.0f, 0.0f);
self.minimumLineSpacing = 50.0f;
}
return self;
}
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
return YES;
}
+ (Class)layoutAttributesClass
{
return [HILayoutAttributes class];
}
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
NSArray *attributes = [super layoutAttributesForElementsInRect:rect];
CGRect visibleRect;
visibleRect.origin = self.collectionView.contentOffset;
visibleRect.size = self.collectionView.bounds.size;
for (UICollectionViewLayoutAttributes *attribute in attributes) {
HILayoutAttributes *atr = (HILayoutAttributes *) attribute;
atr.isCenterCell = NO;
if (CGRectIntersectsRect(attribute.frame, rect)) {
[self setLineAttributes:attribute visibleRect:visibleRect];
}
}
NSIndexPath *path = [self indexPathForCenterCellInRect:visibleRect];
NSInteger centerCellIndex = [attributes indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
HILayoutAttributes *atr = (HILayoutAttributes *)obj;
if ([atr.indexPath isEqual:path]) {
return YES;
}
return NO;
}];
if (centerCellIndex != NSNotFound) {
((HILayoutAttributes *)[attributes objectAtIndex:centerCellIndex]).isCenterCell = YES;
}
return attributes;
}
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
{
CGFloat offsetAdjustment = MAXFLOAT;
CGFloat horizontalCenter = proposedContentOffset.x + (CGRectGetWidth(self.collectionView.bounds) / 2.0f);
CGRect targetRect = CGRectMake(proposedContentOffset.x, 0.0f, self.collectionView.bounds.size.width, self.collectionView.bounds.size.height);
// Find the element which is closest to the center and calculate the offset
// To move that element to the center.
NSArray *attributes = [super layoutAttributesForElementsInRect:targetRect];
for (UICollectionViewLayoutAttributes *attribute in attributes) {
if (attribute.representedElementCategory != UICollectionElementCategoryCell)
continue; // skip headers
CGFloat itemHorizontalCenter = attribute.center.x;
CGFloat distanceToCenter = itemHorizontalCenter - horizontalCenter;
if (ABS(distanceToCenter) < ABS(offsetAdjustment)) {
offsetAdjustment = distanceToCenter;
}
}
return CGPointMake(proposedContentOffset.x + offsetAdjustment, proposedContentOffset.y);
}
#pragma mark - Private
- (void)setLineAttributes:(UICollectionViewLayoutAttributes *)attributes visibleRect:(CGRect)visibleRect
{
CGFloat distance = CGRectGetMidX(visibleRect) - attributes.center.x;
CGFloat normalizedDistance = distance / ACTIVE_DISTANCE;
// Apply a zoom factor to cells within ACTIVE_DISTANCE
if (ABS(distance) < ACTIVE_DISTANCE) {
CGFloat zoom = 1.0f + ZOOM_FACTOR * (1.0f - ABS(normalizedDistance));
attributes.transform3D = CATransform3DMakeScale(zoom, zoom, 1.0);
attributes.zIndex = round(zoom);
}
}
- (NSIndexPath *)indexPathForCenterCellInRect:(CGRect)visibleRect
{
CGFloat horizontalCenter = visibleRect.origin.x + (CGRectGetWidth(self.collectionView.bounds) / 2.0f);
CGFloat offsetAdjustment = MAXFLOAT;
UICollectionViewLayoutAttributes *previousAttribute = nil;
NSArray *attributes = [super layoutAttributesForElementsInRect:visibleRect];
for (UICollectionViewLayoutAttributes *atr in attributes) {
CGFloat itemHorizontalCenter = atr.center.x;
CGFloat distanceToCenter = itemHorizontalCenter - horizontalCenter;
if (ABS(distanceToCenter) < ABS(offsetAdjustment)) {
offsetAdjustment = distanceToCenter;
} else {
// This means that the previous index belongs to the center cell.
NSIndexPath *path = (previousAttribute) ? previousAttribute.indexPath : atr.indexPath;
return path;
}
previousAttribute = atr;
}
return nil;
}
- (void) setVisibleCellsCenterAttributes:(NSArray *)visibleAttributes withCenterIndex:(NSInteger)centralIndex
{
NSInteger currentIndex = 0;
for (UICollectionViewLayoutAttributes *atr in visibleAttributes) {
HILayoutAttributes *lineAttributes = (HILayoutAttributes *) atr;
if (currentIndex == centralIndex) {
lineAttributes.isCenterCell = YES;
} else {
lineAttributes.isCenterCell = NO;
}
++currentIndex;
}
}
@end
omg, i've totally forgot on this one. have you solved the issue?
not really!
I'm on vacations now though! Will resume my efforts around June 15th!!
cheers!
Sent from my iPhone
On 11 mai 2013, at 01:35, Marin Usalj notifications@github.com wrote:
omg, i've totally forgot on this one. have you solved the issue?
— Reply to this email directly or view it on GitHub.
@Goles awesome, see you then :)
I was curious about the problem and have created a dummy project :)
Here are some of my thoughts.
nullMockForProtocol:
instead of mockForProtocol
. Especially for mock for delegate. Because without it I was getting errors like mock received unexpected message -collectionView:<UICollectionView: 0x9848000; frame = (0 0; 1024 768); clipsToBounds = YES; gestureRecognizers = <NSArray: 0x916dc80>; layer = <CALayer: 0x9173680>; contentOffset: {0, 0}> collection view layout: <HICollectionViewLineLayout: 0x9187940> layout:<HICollectionViewLineLayout: 0x9187940> insetForSectionAtIndex:0
.[[delegateMock should] conformToProtocol:@protocol(UICollectionViewDelegateFlowLayout)];
and [[dataSourceMock should] conformToProtocol:@protocol(UICollectionViewDataSource)];
line. No need to test if KWMock class works. It's part of library and it's tested in Kiwi's tests. And the second mistake here is that you did test in beforeEach
block. Tests should be inside tests (it
).layoutAttributesForElementsInRect:
and noticed that attributes have wrong frames. Seems like theirs origins were not set. Or probably I missed something in HILayoutAttributes
? I don't know what you have implemented in that class.In case you have the same problem in your project as well you can try to override setFrame:
method of HILayoutAttributes
and to see when it's called and with what values when you run the app. Probably you also need to mock some other methods from dataSource and/or delegate protocols, so attributes frame will be set correctly.
I didn't work with UICollectionViews yet, so maybe I missed something. But I hope something of that will help :)
I need to test a UICollectionViewFlowLayout subclass with Kiwi,
I have correctly mocked up the delegate and the dataSource for a UICollectionView, but I'm still having some issues.
With the specified item size of
CGSize(200.0f, 200.0f)
, I should be getting 5 items on the screen, but for some reason the attributes array that is returned at the last line does return 10 attributes, so that means that there are 10 visible cells.What could be going on here? If my layout works as expected there's always 5 elements on the screen:
This is what I have so far (read the comments), and it mostly works.
This is what I see when I just run the app with no tests (5 visible cells)