简体   繁体   中英

UICollectionViewLayout (Converting from Swift to Objective-C)

I'm currently following this tutorial ( https://www.raywenderlich.com/99087/swift-expanding-cells-ios-collection-views ) which creates a custom UICollectionViewLayout, the problem is that the tutorial is written in Swift but I'm trying to convert it to Objective-C for my project.

The first part of reproducing the tutorial into Objective-C was fine and i've gotten to this stage. 在此处输入图片说明

Though, in the 2nd part when we're suppose to create a custom UICollectionViewLayout, and upon changing in the storyboard the Layout of CollectionView to Custom and setting the custom class, a blank screen appears.

Below are the codes that I'd reproduced from the tutorial from Swift to Objective-C:

@implementation TimetableCustomLayout{
    NSMutableArray *cache;
}

-(NSInteger)featuredItemIndex{

CGFloat dragOffset = 180;
    return MAX(0, self.collectionView.contentOffset.y - dragOffset);
}

-(CGFloat)nextItemPercentageOffset{
    CGFloat dragOffset = 180;
    return (self.collectionView.contentOffset.y / dragOffset) - [self    featuredItemIndex];
}

-(CGFloat)width{
    return CGRectGetWidth(self.collectionView.bounds);
}

-(CGFloat)height{
    return CGRectGetHeight(self.collectionView.bounds);
}

-(NSInteger)numberOfItems{
    //Will be replaced with dynamic value later
    return 5;
}


-(CGSize)collectionViewContentSize{

    CGFloat dragOffset = 180;



    return CGSizeMake([self height], [self width]);
}


-(void)prepareLayout{

    [super prepareLayout];
    cache = [[NSMutableArray alloc]initWithObjects:[UICollectionViewLayoutAttributes class], nil];

    self.standardHeight = 100;
    self.featuredHeight = 280;

    CGRect frame = CGRectZero;
    CGFloat y = 0;

    for(int item = 0; item < 5; item ++){
        NSIndexPath *indexPath = [NSIndexPath indexPathForItem:item inSection:0];
        UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];

        attributes.zIndex = item;
        CGFloat height = self.standardHeight;

        if(indexPath.item == [self featuredItemIndex]){
            CGFloat yOffset = self.standardHeight * [self nextItemPercentageOffset];
            y = self.collectionView.contentOffset.y - yOffset;

            height = self.featuredHeight;

    }else if(indexPath.item == ([self featuredItemIndex] + 1) && indexPath.item != [self numberOfItems]){
            CGFloat maxY = y + self.standardHeight;
            height = self.standardHeight + MAX((self.featuredHeight - self.standardHeight) * [self nextItemPercentageOffset], 0);
            y = maxY - height;
    }

        frame = CGRectMake(0, y, [self width], [self height]);
    attributes.frame = frame;
        [cache addObject:attributes];

        y = CGRectGetMaxY(frame);

    }

}

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
    [super layoutAttributesForElementsInRect:rect];



    NSMutableArray *layoutAttributes = [[NSMutableArray alloc]initWithObjects:[UICollectionViewLayoutAttributes class], nil];

    NSLog(@"%@", cache);

    for(UICollectionViewLayoutAttributes *attributes in cache){
        if(CGRectIntersectsRect(attributes.frame, rect)){
            [layoutAttributes addObject:attributes];
        }
    }

    return layoutAttributes;

}


-(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds{
    return true;
}

@end

I'm also getting error, Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[UICollectionViewLayoutAttributes frame]: unrecognized selector.

I believe that the error is possibly due to incorrect translation from Swift to Objective-C, particularly this line,

Swift:

var cache = [UICollectionViewLayoutAttributes]()

Objective-C:

NSMutableArray *layoutAttributes = [[NSMutableArray alloc]initWithObjects:[UICollectionViewLayoutAttributes class], nil];

This is my first question on StackOverflow, any feedback and help would be greatly appreciated, thanks in advance.

You are adding a reference to the UICollectionViewLayoutAttributes class to the cache and layoutAttributes array on initialization. And then, calling frame property to the class reference (notice the + on the error message that denotes a class method, where instance methods use - ).

Replace this line:

NSMutableArray *layoutAttributes = [[NSMutableArray alloc]initWithObjects:[UICollectionViewLayoutAttributes class], nil];

With this:

NSMutableArray *layoutAttributes = [[NSMutableArray alloc] init];

The same applies to the cache variable initialization.


You can also use type-safe arrays in Objective-C using generics:

NSMutableArray<UICollectionViewLayoutAttributes*> *layoutAttributes = [[NSMutableArray alloc] init];

More information here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM